@datagrok/sequence-translator 1.0.13 → 1.0.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.
- package/dist/package-test.js +70674 -1436
- package/dist/package.js +69844 -4386
- package/package.json +27 -22
- package/scripts/build-monomer-lib.py +178 -0
- package/setup-unlink-clean.cmd +14 -0
- package/setup.cmd +14 -11
- package/setup.sh +37 -0
- package/src/autostart/constants.ts +12 -0
- package/src/autostart/registration.ts +18 -4
- package/src/axolabs/constants.ts +14 -14
- package/src/axolabs/define-pattern.ts +13 -12
- package/src/axolabs/draw-svg.ts +140 -201
- package/src/axolabs/helpers.ts +94 -0
- package/src/main/main-view.ts +90 -29
- package/src/package.ts +20 -2
- package/src/structures-works/const.ts +5 -0
- package/src/structures-works/converters.ts +29 -27
- package/src/structures-works/from-monomers.ts +187 -31
- package/src/structures-works/map.ts +6 -7
- package/src/structures-works/mol-transformations.ts +172 -622
- package/src/structures-works/save-sense-antisense.ts +6 -3
- package/src/structures-works/sequence-codes-tools.ts +8 -10
- package/{test-SequenceTranslator-62cc009524f3-4a9916b0.html → test-SequenceTranslator-91c83d8913ff-f94596bc.html} +10 -10
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/sequence-translator",
|
|
3
3
|
"friendlyName": "Sequence Translator",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.15",
|
|
5
5
|
"author": {
|
|
6
|
-
"name": "
|
|
7
|
-
"email": "
|
|
6
|
+
"name": "Alexey Choposky",
|
|
7
|
+
"email": "achopovsky@datagrok.ai"
|
|
8
8
|
},
|
|
9
9
|
"description": "SequenceTranslator is a [package](https://datagrok.ai/help/develop/develop#packages) for the [Datagrok](https://datagrok.ai) platform, used to translate [oligonucleotide](https://en.wikipedia.org/wiki/Oligonucleotide) sequences between [different representations](https://github.com/datagrok-ai/public/tree/master/packages/SequenceTranslator#sequence-representations).",
|
|
10
10
|
"repository": {
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
"directory": "packages/SequenceTranslator"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@datagrok-libraries/utils": "^1.
|
|
16
|
+
"@datagrok-libraries/utils": "^1.17.2",
|
|
17
17
|
"@types/react": "^18.0.15",
|
|
18
|
+
"@datagrok-libraries/bio": "^5.11.1",
|
|
18
19
|
"datagrok-api": "^1.7.2",
|
|
19
20
|
"datagrok-tools": "^4.1.2",
|
|
20
21
|
"npm": "^8.11.0",
|
|
@@ -23,24 +24,6 @@
|
|
|
23
24
|
"ts-loader": "^9.3.1",
|
|
24
25
|
"typescript": "^4.7.4"
|
|
25
26
|
},
|
|
26
|
-
"scripts": {
|
|
27
|
-
"link-api": "npm link datagrok-api",
|
|
28
|
-
"debug-sequencetranslator": "grok publish",
|
|
29
|
-
"release-sequencetranslator": "grok publish localhost --release",
|
|
30
|
-
"build-sequencetranslator": "webpack",
|
|
31
|
-
"build": "webpack",
|
|
32
|
-
"debug-sequencetranslator-public": "grok publish public",
|
|
33
|
-
"release-sequencetranslator-public": "grok publish public --release",
|
|
34
|
-
"debug-sequencetranslator-local": "grok publish local",
|
|
35
|
-
"release-sequencetranslator-local": "grok publish local --release",
|
|
36
|
-
"test": "jest",
|
|
37
|
-
"test-dev": "set HOST=dev && jest",
|
|
38
|
-
"test-local": "set HOST=localhost && jest"
|
|
39
|
-
},
|
|
40
|
-
"sources": [
|
|
41
|
-
"css/style.css",
|
|
42
|
-
"vendors/openchemlib-full.js"
|
|
43
|
-
],
|
|
44
27
|
"devDependencies": {
|
|
45
28
|
"@types/jest": "^27.0.0",
|
|
46
29
|
"@types/jquery": "^3.5.14",
|
|
@@ -60,5 +43,27 @@
|
|
|
60
43
|
"@types/node-fetch": "^2.6.2",
|
|
61
44
|
"node-fetch": "^2.6.7"
|
|
62
45
|
},
|
|
46
|
+
"grokDependencies": {
|
|
47
|
+
"@datagrok/chem": "1.3.32"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"link-api": "npm link datagrok-api",
|
|
51
|
+
"link-all": "npm link datagrok-api @datagrok-libraries/utils @datagrok-libraries/bio",
|
|
52
|
+
"debug-sequencetranslator": "grok publish",
|
|
53
|
+
"release-sequencetranslator": "grok publish localhost --release",
|
|
54
|
+
"build-sequencetranslator": "webpack",
|
|
55
|
+
"build": "webpack",
|
|
56
|
+
"debug-sequencetranslator-public": "grok publish public",
|
|
57
|
+
"release-sequencetranslator-public": "grok publish public --release",
|
|
58
|
+
"debug-sequencetranslator-local": "grok publish local",
|
|
59
|
+
"release-sequencetranslator-local": "grok publish local --release",
|
|
60
|
+
"test": "jest",
|
|
61
|
+
"test-dev": "set HOST=dev && jest",
|
|
62
|
+
"test-local": "set HOST=localhost && jest"
|
|
63
|
+
},
|
|
64
|
+
"sources": [
|
|
65
|
+
"css/style.css",
|
|
66
|
+
"vendors/openchemlib-full.js"
|
|
67
|
+
],
|
|
63
68
|
"category": "Bioinformatics"
|
|
64
69
|
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
from io import TextIOWrapper
|
|
2
|
+
|
|
3
|
+
from rdkit import Chem
|
|
4
|
+
|
|
5
|
+
import orjson
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
|
|
9
|
+
from click_default_group import DefaultGroup
|
|
10
|
+
from rdkit.Chem.rdchem import Mol
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def molAddCollection(mol: Mol, name: str, title: str = None) -> str:
|
|
14
|
+
"""
|
|
15
|
+
Get and postprocess (atom's CFG, title, e.t.c.) molblock
|
|
16
|
+
:param mol: Mol molecule structure / object
|
|
17
|
+
:param name: Monomer name to add to molblock title
|
|
18
|
+
:param title: title to replace in Chem.MolToMolBlock() string output
|
|
19
|
+
:return: molblock string
|
|
20
|
+
"""
|
|
21
|
+
res: str = Chem.MolToMolBlock(mol, forceV3000=True) # MolToMolFile
|
|
22
|
+
|
|
23
|
+
mb_line_list: list[str] = res.split('\n')
|
|
24
|
+
if title:
|
|
25
|
+
mb_line_list[1] = title
|
|
26
|
+
|
|
27
|
+
if name and name not in mb_line_list[1]:
|
|
28
|
+
mb_line_list[1] += '|' + name
|
|
29
|
+
|
|
30
|
+
end_bond_idx: int = mb_line_list.index('M V30 END BOND')
|
|
31
|
+
chirality = [atom.GetChiralTag() for atom in mol.GetAtoms()]
|
|
32
|
+
begin_atom_idx = mb_line_list.index('M V30 BEGIN ATOM')
|
|
33
|
+
end_atom_idx = mb_line_list.index('M V30 END ATOM')
|
|
34
|
+
for atom_idx in range(1, end_atom_idx - begin_atom_idx):
|
|
35
|
+
line_idx = begin_atom_idx + atom_idx
|
|
36
|
+
atom_ch = chirality[atom_idx - 1]
|
|
37
|
+
if atom_ch != Chem.rdchem.CHI_UNSPECIFIED:
|
|
38
|
+
mb_line_list[line_idx] += " CFG={0}".format(int(atom_ch))
|
|
39
|
+
|
|
40
|
+
steabs: list[int] = [i + 1 for (i, ch) in enumerate(chirality) if ch != Chem.rdchem.CHI_UNSPECIFIED]
|
|
41
|
+
if len(steabs) > 0:
|
|
42
|
+
steabs_str: str = "M V30 MDLV30/STEABS ATOMS=({count} {list})" \
|
|
43
|
+
.format(count=len(steabs), list=' '.join([str(idx) for idx in steabs]))
|
|
44
|
+
|
|
45
|
+
mb_line_list = mb_line_list[:(end_bond_idx + 1)] + \
|
|
46
|
+
["M V30 BEGIN COLLECTION", steabs_str, "M V30 END COLLECTION"] + \
|
|
47
|
+
mb_line_list[(end_bond_idx + 1):]
|
|
48
|
+
|
|
49
|
+
return '\n'.join(mb_line_list)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def molfile2molfile(src_mol: str, name: str) -> str:
|
|
53
|
+
mol: Mol = Chem.MolFromMolBlock(src_mol)
|
|
54
|
+
src_mf_lines = src_mol.split('\n')
|
|
55
|
+
title = src_mf_lines[1]
|
|
56
|
+
return molAddCollection(mol, name, title=title)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def smiles2molfile(smiles: str, name: str) -> str:
|
|
60
|
+
mol: Mol = Chem.MolFromSmiles(smiles)
|
|
61
|
+
return molAddCollection(mol, name)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
CodesType = dict[str, dict[str, list[str]]]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class Monomer:
|
|
68
|
+
def __init__(self,
|
|
69
|
+
symbol: str, name: str, molfile: str, smiles: str,
|
|
70
|
+
codes: CodesType):
|
|
71
|
+
self.monomerType = 'Backbone'
|
|
72
|
+
self.smiles = smiles
|
|
73
|
+
self.name = name
|
|
74
|
+
self.author = 'SequenceTranslator'
|
|
75
|
+
self.molfile = molfile2molfile(molfile, name) if molfile else smiles2molfile(smiles, name)
|
|
76
|
+
self.naturalAnalog = ''
|
|
77
|
+
self.rgroups = [
|
|
78
|
+
{
|
|
79
|
+
"capGroupSmiles": "O[*:1]",
|
|
80
|
+
"alternateId": "R1-OH",
|
|
81
|
+
"capGroupName": "OH",
|
|
82
|
+
"label": "R1"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"capGroupSmiles": "O[*:2]",
|
|
86
|
+
"alternateId": "R2-OH",
|
|
87
|
+
"capGroupName": "OH",
|
|
88
|
+
"label": "R2"
|
|
89
|
+
}]
|
|
90
|
+
self.createDate = None
|
|
91
|
+
self.id = 0
|
|
92
|
+
self.polymerType = 'RNA'
|
|
93
|
+
self.symbol = symbol
|
|
94
|
+
self.codes: CodesType = codes
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
def from_json(src_json: {}):
|
|
98
|
+
obj = Monomer(src_json['symbol'], src_json['name'],
|
|
99
|
+
src_json['molfile'], src_json['smiles'],
|
|
100
|
+
src_json['codes'])
|
|
101
|
+
return obj
|
|
102
|
+
|
|
103
|
+
def to_json(self):
|
|
104
|
+
return {
|
|
105
|
+
'monomerType': self.monomerType,
|
|
106
|
+
'smiles': self.smiles,
|
|
107
|
+
'name': self.name,
|
|
108
|
+
'author': self.author,
|
|
109
|
+
'molfile': self.molfile,
|
|
110
|
+
'naturalAnalog': self.naturalAnalog,
|
|
111
|
+
'rgroups': self.rgroups,
|
|
112
|
+
'createDate': self.createDate,
|
|
113
|
+
'id': self.id,
|
|
114
|
+
'polymerType': self.polymerType,
|
|
115
|
+
'symbol': self.symbol,
|
|
116
|
+
'codes': self.codes,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def codes2monomers(codes_json: {}) -> dict[str, Monomer]:
|
|
121
|
+
monomers_res: dict[str, Monomer] = {}
|
|
122
|
+
for (codes_src, src_dict) in codes_json.items():
|
|
123
|
+
for (codes_type, monomers_dict) in src_dict.items():
|
|
124
|
+
for (codes_code, monomer_json) in monomers_dict.items():
|
|
125
|
+
monomer_name = monomer_json['name']
|
|
126
|
+
if monomer_name not in monomers_res:
|
|
127
|
+
symbol = monomer_json['name']
|
|
128
|
+
name = monomer_json['name']
|
|
129
|
+
smiles = monomer_json['SMILES']
|
|
130
|
+
monomers_res[monomer_name] = Monomer(symbol, name, None, smiles, {})
|
|
131
|
+
codes = monomers_res[monomer_name].codes
|
|
132
|
+
if codes_src not in codes:
|
|
133
|
+
codes[codes_src] = {}
|
|
134
|
+
if codes_type not in codes[codes_src]:
|
|
135
|
+
codes[codes_src][codes_type] = [];
|
|
136
|
+
codes[codes_src][codes_type].append(codes_code)
|
|
137
|
+
return monomers_res
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@click.group(cls=DefaultGroup, default='main')
|
|
141
|
+
def cli():
|
|
142
|
+
pass
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@cli.command()
|
|
146
|
+
@click.pass_context
|
|
147
|
+
@click.option('--initial', 'initial_f',
|
|
148
|
+
help='Initial monomers source file.',
|
|
149
|
+
type=click.File('r', 'utf-8'))
|
|
150
|
+
@click.option('--lib', 'lib_f',
|
|
151
|
+
help='Output library (HELM format) file.',
|
|
152
|
+
type=click.File('wb', 'utf-8'))
|
|
153
|
+
@click.option('--add', 'add_f_list', multiple=True,
|
|
154
|
+
help='Additional libraries to build.',
|
|
155
|
+
type=click.File('r', 'utf-8'))
|
|
156
|
+
def main(ctx, initial_f: TextIOWrapper, lib_f: TextIOWrapper, add_f_list: list[TextIOWrapper]):
|
|
157
|
+
initial_json_str = initial_f.read()
|
|
158
|
+
|
|
159
|
+
initial_json = orjson.loads(initial_json_str)
|
|
160
|
+
|
|
161
|
+
monomers: dict[str, Monomer] = codes2monomers(initial_json)
|
|
162
|
+
|
|
163
|
+
for add_f in add_f_list:
|
|
164
|
+
add_json_str = add_f.read()
|
|
165
|
+
add_json = orjson.loads(add_json_str)
|
|
166
|
+
for add_m in add_json:
|
|
167
|
+
m = Monomer.from_json(add_m)
|
|
168
|
+
monomers[m.name] = m
|
|
169
|
+
|
|
170
|
+
add_json = [m.to_json() for m in monomers.values()]
|
|
171
|
+
|
|
172
|
+
lib_json_txt = orjson.dumps(add_json, option=orjson.OPT_INDENT_2)
|
|
173
|
+
lib_f.write(lib_json_txt)
|
|
174
|
+
k = 11
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
if __name__ == '__main__':
|
|
178
|
+
cli()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
set package_dir=%cd%
|
|
2
|
+
|
|
3
|
+
set dirs=^
|
|
4
|
+
\..\..\js-api\ ^
|
|
5
|
+
\..\..\libraries\utils\ ^
|
|
6
|
+
\..\..\libraries\bio\ ^
|
|
7
|
+
\
|
|
8
|
+
|
|
9
|
+
call npm uninstall -g datagrok-api @datagrok-libraries/utils @datagrok-libraries/bio
|
|
10
|
+
|
|
11
|
+
for %%p in (%dirs%) do cd %package_dir%\%%p & rmdir /s /q node_modules
|
|
12
|
+
for %%p in (%dirs%) do cd %package_dir%\%%p & rmdir /s /q dist
|
|
13
|
+
|
|
14
|
+
rem for %%p in (%dirs%) do cd %package_dir%\%%p & del "package-lock.json"
|
package/setup.cmd
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
call setup-unlink-clean.cmd
|
|
2
|
+
|
|
3
|
+
set package_dir=%cd%
|
|
4
|
+
|
|
5
|
+
set dirs=^
|
|
6
|
+
\..\..\js-api\ ^
|
|
7
|
+
\..\..\libraries\utils\ ^
|
|
8
|
+
\..\..\libraries\bio\ ^
|
|
9
|
+
\
|
|
10
|
+
|
|
11
|
+
for %%p in (%dirs%) do cd %package_dir%\%%p & call npm install
|
|
12
|
+
for %%p in (%dirs%) do cd %package_dir%\%%p & call npm link
|
|
13
|
+
for %%p in (%dirs%) do cd %package_dir%\%%p & call npm run link-all
|
|
14
|
+
for %%p in (%dirs%) do cd %package_dir%\%%p & call npm run build
|
package/setup.sh
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
./setup-unlink-clean.sh
|
|
4
|
+
|
|
5
|
+
GREEN='\e[0;32m'
|
|
6
|
+
NO_COLOR='\e[0m'
|
|
7
|
+
|
|
8
|
+
package_dir=$(pwd)
|
|
9
|
+
|
|
10
|
+
dirs=(
|
|
11
|
+
"../../js-api/"
|
|
12
|
+
"../../libraries/utils/"
|
|
13
|
+
"../../libraries/bio/"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
for dir in ${dirs[@]}; do
|
|
17
|
+
cd $package_dir
|
|
18
|
+
cd $dir
|
|
19
|
+
echo -e $GREEN npm install in $(pwd) $NO_COLOR
|
|
20
|
+
npm install
|
|
21
|
+
echo -e $GREEN npm link in $(pwd) $NO_COLOR
|
|
22
|
+
npm link
|
|
23
|
+
done
|
|
24
|
+
|
|
25
|
+
for dir in ${dirs[@]}; do
|
|
26
|
+
cd $package_dir
|
|
27
|
+
cd $dir
|
|
28
|
+
if [ $dir != "../../js-api/" ]; then
|
|
29
|
+
echo -e $GREEN npm link-all in $(pwd) $NO_COLOR
|
|
30
|
+
npm run link-all
|
|
31
|
+
fi
|
|
32
|
+
echo -e $GREEN npm run build in$(pwd) $NO_COLOR
|
|
33
|
+
npm run build || exit
|
|
34
|
+
done
|
|
35
|
+
|
|
36
|
+
cd $package_dir
|
|
37
|
+
npm run link-all
|
|
@@ -6,6 +6,18 @@ export const SEQUENCE_TYPES = {
|
|
|
6
6
|
DIMER: 'Dimer',
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
+
export const CELL_STRUCTURE = {
|
|
10
|
+
DUPLEX: {
|
|
11
|
+
BEFORE_SS: 'SS ',
|
|
12
|
+
BEFORE_AS: '\r\nAS ',
|
|
13
|
+
},
|
|
14
|
+
TRIPLEX_OR_DIMER: {
|
|
15
|
+
BEFORE_SS: 'SS ',
|
|
16
|
+
BEFORE_AS1: '\r\nAS1 ',
|
|
17
|
+
BEFORE_AS2: '\r\nAS2 ',
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
9
21
|
export const COL_NAMES = {
|
|
10
22
|
CHEMISTRY: 'Chemistry',
|
|
11
23
|
NUMBER: 'Number',
|
|
@@ -4,7 +4,7 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
import {siRnaBioSpringToGcrs, siRnaAxolabsToGcrs, gcrsToNucleotides, asoGapmersBioSpringToGcrs, gcrsToMermade12,
|
|
5
5
|
siRnaNucleotidesToGcrs} from '../structures-works/converters';
|
|
6
6
|
import {weightsObj, SYNTHESIZERS} from '../structures-works/map';
|
|
7
|
-
import {SEQUENCE_TYPES, COL_NAMES, GENERATED_COL_NAMES} from './constants';
|
|
7
|
+
import {SEQUENCE_TYPES, COL_NAMES, GENERATED_COL_NAMES, CELL_STRUCTURE} from './constants';
|
|
8
8
|
import {saltMass, saltMolWeigth, molecularWeight, batchMolWeight} from './calculations';
|
|
9
9
|
import {isValidSequence} from '../structures-works/sequence-codes-tools';
|
|
10
10
|
import {sequenceToMolV3000} from '../structures-works/from-monomers';
|
|
@@ -19,13 +19,18 @@ import {IDPS} from './IDPs';
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
function parseStrandsFromDuplexCell(s: string): {SS: string, AS: string} {
|
|
22
|
-
const arr = s
|
|
22
|
+
const arr = s
|
|
23
|
+
.slice(CELL_STRUCTURE.DUPLEX.BEFORE_SS.length)
|
|
24
|
+
.split(CELL_STRUCTURE.DUPLEX.BEFORE_AS);
|
|
23
25
|
return {SS: arr[0], AS: arr[1]};
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
function parseStrandsFromTriplexOrDimerCell(s: string): {SS: string, AS1: string, AS2: string} {
|
|
27
|
-
const arr1 = s
|
|
28
|
-
|
|
29
|
+
const arr1 = s
|
|
30
|
+
.slice(CELL_STRUCTURE.TRIPLEX_OR_DIMER.BEFORE_SS.length)
|
|
31
|
+
.split(CELL_STRUCTURE.TRIPLEX_OR_DIMER.BEFORE_AS1);
|
|
32
|
+
const arr2 = arr1[1]
|
|
33
|
+
.split(CELL_STRUCTURE.TRIPLEX_OR_DIMER.BEFORE_AS2);
|
|
29
34
|
return {SS: arr1[0], AS1: arr2[0], AS2: arr2[1]};
|
|
30
35
|
}
|
|
31
36
|
|
|
@@ -249,6 +254,15 @@ export function oligoSdFile(table: DG.DataFrame) {
|
|
|
249
254
|
if ([COL_NAMES.SALT, COL_NAMES.EQUIVALENTS, COL_NAMES.SALT_MOL_WEIGHT].includes(colName))
|
|
250
255
|
updateCalculatedColumns(view.dataFrame, view.dataFrame.currentRowIdx);
|
|
251
256
|
});
|
|
257
|
+
|
|
258
|
+
function updateCalculatedColumns(t: DG.DataFrame, i: number): void {
|
|
259
|
+
const smValue = saltMass(saltNamesList, molWeightCol, equivalentsCol, i, saltCol);
|
|
260
|
+
t.getCol(COL_NAMES.SALT_MASS).set(i, smValue, false);
|
|
261
|
+
const smwValue = saltMolWeigth(saltNamesList, saltCol, molWeightCol, i);
|
|
262
|
+
t.getCol(COL_NAMES.SALT_MOL_WEIGHT).set(i, smwValue, false);
|
|
263
|
+
const bmw = batchMolWeight(t.getCol(COL_NAMES.COMPOUND_MOL_WEIGHT), t.getCol(COL_NAMES.SALT_MASS), i);
|
|
264
|
+
t.getCol(COL_NAMES.BATCH_MOL_WEIGHT).set(i, bmw, false);
|
|
265
|
+
}
|
|
252
266
|
}),
|
|
253
267
|
]);
|
|
254
268
|
grok.shell.v.setRibbonPanels([[d]]);
|
package/src/axolabs/constants.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
export const
|
|
1
|
+
const RNA_COLOR = 'rgb(255,230,153)';
|
|
2
|
+
const INVABASIC_COLOR = 'rgb(203,119,211)';
|
|
3
|
+
export const AXOLABS_MAP:
|
|
4
4
|
{[index: string]: {fullName: string, symbols: [string, string, string, string], color: string}} =
|
|
5
5
|
{
|
|
6
6
|
'RNA': {
|
|
7
7
|
fullName: 'RNA nucleotides',
|
|
8
8
|
symbols: ['A', 'C', 'G', 'U'],
|
|
9
|
-
color:
|
|
9
|
+
color: RNA_COLOR,
|
|
10
10
|
},
|
|
11
11
|
'DNA': {
|
|
12
12
|
fullName: 'DNA nucleotides',
|
|
@@ -44,24 +44,24 @@ export const axolabsMap:
|
|
|
44
44
|
color: 'rgb(255,192,0)',
|
|
45
45
|
},
|
|
46
46
|
'A': {
|
|
47
|
-
fullName: '
|
|
47
|
+
fullName: 'Adenosine',
|
|
48
48
|
symbols: ['a', 'a', 'a', 'a'],
|
|
49
|
-
color:
|
|
49
|
+
color: RNA_COLOR,
|
|
50
50
|
},
|
|
51
51
|
'C': {
|
|
52
|
-
fullName: '
|
|
52
|
+
fullName: 'Cytidine',
|
|
53
53
|
symbols: ['c', 'c', 'c', 'c'],
|
|
54
|
-
color:
|
|
54
|
+
color: RNA_COLOR,
|
|
55
55
|
},
|
|
56
56
|
'G': {
|
|
57
|
-
fullName: '
|
|
57
|
+
fullName: 'Guanosine',
|
|
58
58
|
symbols: ['g', 'g', 'g', 'g'],
|
|
59
|
-
color:
|
|
59
|
+
color: RNA_COLOR,
|
|
60
60
|
},
|
|
61
61
|
'U': {
|
|
62
|
-
fullName: '
|
|
62
|
+
fullName: 'Uridine',
|
|
63
63
|
symbols: ['u', 'u', 'u', 'u'],
|
|
64
|
-
color:
|
|
64
|
+
color: RNA_COLOR,
|
|
65
65
|
},
|
|
66
66
|
'X-New': {
|
|
67
67
|
fullName: '',
|
|
@@ -81,7 +81,7 @@ export const axolabsMap:
|
|
|
81
81
|
'InvAbasic': {
|
|
82
82
|
fullName: 'Inverted abasic capped',
|
|
83
83
|
symbols: ['(invabasic)', '(invabasic)', '(invabasic)', '(invabasic)'],
|
|
84
|
-
color:
|
|
84
|
+
color: INVABASIC_COLOR,
|
|
85
85
|
},
|
|
86
86
|
"5\"-vinylps": {
|
|
87
87
|
fullName: '5\'-vinylphosphonate-2\'-OMe-uridine',
|
|
@@ -91,7 +91,7 @@ export const axolabsMap:
|
|
|
91
91
|
'InvAbasic(o)': {
|
|
92
92
|
fullName: 'Inverted abasic capped (overhang)',
|
|
93
93
|
symbols: ['(invabasic)', '(invabasic)', '(invabasic)', '(invabasic)'],
|
|
94
|
-
color:
|
|
94
|
+
color: INVABASIC_COLOR,
|
|
95
95
|
},
|
|
96
96
|
"2\"-OMe-U(o)": {
|
|
97
97
|
fullName: 'Nucleotide Uridine with 2\'O-Methyl protection (overhang)',
|
|
@@ -6,9 +6,10 @@ import * as svg from 'save-svg-as-png';
|
|
|
6
6
|
import $ from 'cash-dom';
|
|
7
7
|
|
|
8
8
|
import {drawAxolabsPattern} from './draw-svg';
|
|
9
|
-
import {
|
|
9
|
+
import {AXOLABS_MAP} from './constants';
|
|
10
|
+
import {isOverhang} from './helpers';
|
|
10
11
|
|
|
11
|
-
const baseChoices: string[] = Object.keys(
|
|
12
|
+
const baseChoices: string[] = Object.keys(AXOLABS_MAP);
|
|
12
13
|
const defaultBase: string = baseChoices[0];
|
|
13
14
|
const defaultPto: boolean = true;
|
|
14
15
|
const defaultSequenceLength: number = 23;
|
|
@@ -17,7 +18,7 @@ const userStorageKey: string = 'SequenceTranslator';
|
|
|
17
18
|
const exampleMinWidth: string = '400px';
|
|
18
19
|
|
|
19
20
|
function generateExample(sequenceLength: number, sequenceBasis: string): string {
|
|
20
|
-
const uniqueSymbols =
|
|
21
|
+
const uniqueSymbols = AXOLABS_MAP[sequenceBasis].symbols.join('');
|
|
21
22
|
return uniqueSymbols.repeat(Math.floor(sequenceLength / 4)) + uniqueSymbols.slice(0, sequenceLength % 4);
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -64,12 +65,12 @@ function translateSequence(
|
|
|
64
65
|
let i: number = -1;
|
|
65
66
|
let mainSequence = sequence.replace(/[AUGC]/g, function(x: string) {
|
|
66
67
|
i++;
|
|
67
|
-
const indexOfSymbol =
|
|
68
|
-
let symbol =
|
|
69
|
-
if (bases[i].value
|
|
70
|
-
if (i < sequence.length / 2 && bases[i + 1].value
|
|
68
|
+
const indexOfSymbol = AXOLABS_MAP['RNA']['symbols'].indexOf(x);
|
|
69
|
+
let symbol = AXOLABS_MAP[bases[i].value]['symbols'][indexOfSymbol];
|
|
70
|
+
if (isOverhang(bases[i].value)) {
|
|
71
|
+
if (i < sequence.length / 2 && !isOverhang(bases[i + 1].value))
|
|
71
72
|
symbol = symbol + x + 'f';
|
|
72
|
-
else if (i > sequence.length / 2 && bases[i - 1].value
|
|
73
|
+
else if (i > sequence.length / 2 && !isOverhang(bases[i - 1].value))
|
|
73
74
|
symbol = x + 'f' + symbol;
|
|
74
75
|
}
|
|
75
76
|
return (ptoLinkages[i].value) ? symbol + 's' : symbol;
|
|
@@ -150,12 +151,12 @@ export function defineAxolabsPattern() {
|
|
|
150
151
|
updateSvgScheme();
|
|
151
152
|
updateOutputExamples();
|
|
152
153
|
});
|
|
153
|
-
if (asBases[i].value
|
|
154
|
+
if (!isOverhang(asBases[i].value))
|
|
154
155
|
nucleotideCounter++;
|
|
155
156
|
|
|
156
157
|
asModificationItems.append(
|
|
157
158
|
ui.divH([
|
|
158
|
-
ui.div([ui.label(asBases[i].value
|
|
159
|
+
ui.div([ui.label(isOverhang(asBases[i].value) ? '' : String(nucleotideCounter))],
|
|
159
160
|
{style: {width: '20px'}})!,
|
|
160
161
|
ui.block75([asBases[i]])!,
|
|
161
162
|
ui.div([asPtoLinkages[i]])!,
|
|
@@ -196,12 +197,12 @@ export function defineAxolabsPattern() {
|
|
|
196
197
|
updateSvgScheme();
|
|
197
198
|
updateOutputExamples();
|
|
198
199
|
});
|
|
199
|
-
if (ssBases[i].value
|
|
200
|
+
if (!isOverhang(ssBases[i].value))
|
|
200
201
|
nucleotideCounter++;
|
|
201
202
|
|
|
202
203
|
ssModificationItems.append(
|
|
203
204
|
ui.divH([
|
|
204
|
-
ui.div([ui.label(ssBases[i].value
|
|
205
|
+
ui.div([ui.label(isOverhang(ssBases[i].value) ? '' : String(nucleotideCounter))],
|
|
205
206
|
{style: {width: '20px'}})!,
|
|
206
207
|
ui.block75([ssBases[i]])!,
|
|
207
208
|
ui.div([ssPtoLinkages[i]])!,
|