Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
Molstar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michal Malý
Molstar
Commits
b8f168eb
Commit
b8f168eb
authored
4 years ago
by
JonStargaryen
Browse files
Options
Downloads
Patches
Plain Diff
iterators
parent
560c26c7
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/mol-io/writer/mol2/encoder.ts
+221
-144
221 additions, 144 deletions
src/mol-io/writer/mol2/encoder.ts
with
221 additions
and
144 deletions
src/mol-io/writer/mol2/encoder.ts
+
221
−
144
View file @
b8f168eb
...
@@ -9,12 +9,12 @@ import { LigandEncoder } from '../ligand-encoder';
...
@@ -9,12 +9,12 @@ import { LigandEncoder } from '../ligand-encoder';
import
{
StringBuilder
}
from
'
../../../mol-util
'
;
import
{
StringBuilder
}
from
'
../../../mol-util
'
;
import
{
getCategoryInstanceData
}
from
'
../cif/encoder/util
'
;
import
{
getCategoryInstanceData
}
from
'
../cif/encoder/util
'
;
import
{
BondType
}
from
'
../../../mol-model/structure/model/types
'
;
import
{
BondType
}
from
'
../../../mol-model/structure/model/types
'
;
//
import { ComponentBond } from '../../../mol-model-formats/structure/property/bonds/comp';
import
{
ComponentBond
}
from
'
../../../mol-model-formats/structure/property/bonds/comp
'
;
//
// type MOL_TYPE = 'SMALL' | 'BIOPOLYMER' | 'PROTEIN' | 'NUCLEIC_ACID' | 'SACCHARIDE';
// type MOL_TYPE = 'SMALL' | 'BIOPOLYMER' | 'PROTEIN' | 'NUCLEIC_ACID' | 'SACCHARIDE';
//
// type CHARGE_TYPE = 'NO_CHARGES' | 'DEL_RE' | 'GASTEIGER' | 'GAST_HUCK' | 'HUCKEL' | 'PULLMAN' | 'GAUSS80_CHARGES' | 'AMPAC_CHARGES' | 'MULLIKEN_CHARGES' | 'DICT_ CHARGES' | 'MMFF94_CHARGES' | 'USER_CHARGES';
// type CHARGE_TYPE = 'NO_CHARGES' | 'DEL_RE' | 'GASTEIGER' | 'GAST_HUCK' | 'HUCKEL' | 'PULLMAN' | 'GAUSS80_CHARGES' | 'AMPAC_CHARGES' | 'MULLIKEN_CHARGES' | 'DICT_ CHARGES' | 'MMFF94_CHARGES' | 'USER_CHARGES';
//
const NON_METAL_ATOMS = 'H D B C N O F Si P S Cl As Se Br Te I At He Ne Ar Kr Xe Rn'.split(' ');
const
NON_METAL_ATOMS
=
'
H D B C N O F Si P S Cl As Se Br Te I At He Ne Ar Kr Xe Rn
'
.
split
(
'
'
);
//
type Bond
Data = { label_atom_id:
string, order: number,
aromatic: boolean
};
type
Bond
Map
=
Map
<
string
,
{
order
:
number
,
flags
:
number
}
>
;
// specification: http://chemyang.ccnu.edu.cn/ccb/server/AIMMS/mol2.pdf
// specification: http://chemyang.ccnu.edu.cn/ccb/server/AIMMS/mol2.pdf
export
class
Mol2Encoder
extends
LigandEncoder
{
export
class
Mol2Encoder
extends
LigandEncoder
{
...
@@ -50,8 +50,7 @@ export class Mol2Encoder extends LigandEncoder {
...
@@ -50,8 +50,7 @@ export class Mol2Encoder extends LigandEncoder {
}
}
});
});
// const sybyl = this.mapToSybyl(label_atom_id1, atom1.type_symbol, bondMap);
const
sybyl
=
this
.
mapToSybyl
(
label_atom_id1
,
atom1
.
type_symbol
,
bondMap
);
const
sybyl
=
'
?
'
;
StringBuilder
.
writeSafe
(
a
,
`
${
i1
+
1
}
${
label_atom_id1
}
${
atom1
.
Cartn_x
.
toFixed
(
3
)}
${
atom1
.
Cartn_y
.
toFixed
(
3
)}
${
atom1
.
Cartn_z
.
toFixed
(
3
)}
${
sybyl
}
1
${
name
}
0.000\n`
);
StringBuilder
.
writeSafe
(
a
,
`
${
i1
+
1
}
${
label_atom_id1
}
${
atom1
.
Cartn_x
.
toFixed
(
3
)}
${
atom1
.
Cartn_y
.
toFixed
(
3
)}
${
atom1
.
Cartn_z
.
toFixed
(
3
)}
${
sybyl
}
1
${
name
}
0.000\n`
);
});
});
...
@@ -62,146 +61,224 @@ export class Mol2Encoder extends LigandEncoder {
...
@@ -62,146 +61,224 @@ export class Mol2Encoder extends LigandEncoder {
StringBuilder
.
writeSafe
(
this
.
out
,
`@<TRIPOS>SUBSTRUCTURE\n1
${
name
}
1\n`
);
StringBuilder
.
writeSafe
(
this
.
out
,
`@<TRIPOS>SUBSTRUCTURE\n1
${
name
}
1\n`
);
}
}
// private toArray(map: Map<string, { order: number, flags: number }>): BondData[] {
private
count
<
K
,
V
>
(
map
:
Map
<
K
,
V
>
,
predicate
:
(
k
:
K
,
v
:
V
)
=>
boolean
):
number
{
// const array: BondData[] = [];
let
count
=
0
;
// map.forEach((v, k) => array.push({ label_atom_id: k, order: v.order, aromatic: BondType.is(BondType.Flag.Aromatic, v.flags) }));
const
iter
=
map
.
entries
();
// return array;
let
result
=
iter
.
next
();
// }
while
(
!
result
.
done
)
{
if
(
predicate
(
result
.
value
[
0
],
result
.
value
[
1
]))
{
count
++
;
}
result
=
iter
.
next
();
}
return
count
;
}
private
orderSum
(
map
:
BondMap
):
number
{
let
sum
=
0
;
const
iter
=
map
.
values
();
let
result
=
iter
.
next
();
while
(
!
result
.
done
)
{
sum
+=
result
.
value
.
order
;
result
=
iter
.
next
();
}
return
sum
;
}
private
isNonMetalBond
(
label_atom_id
:
string
):
boolean
{
return
NON_METAL_ATOMS
.
some
(
a
=>
label_atom_id
.
startsWith
(
a
));
}
private
extractNonmets
(
map
:
BondMap
):
BondMap
{
const
ret
=
new
Map
<
string
,
{
order
:
number
,
flags
:
number
}
>
();
const
iter
=
map
.
entries
();
let
result
=
iter
.
next
();
while
(
!
result
.
done
)
{
const
[
k
,
v
]
=
result
.
value
;
if
(
NON_METAL_ATOMS
.
some
(
a
=>
k
.
startsWith
(
a
)))
{
ret
.
set
(
k
,
v
);
}
result
=
iter
.
next
();
}
return
ret
;
}
// see https://www.sdsc.edu/CCMS/Packages/cambridge/pluto/atom_types.html
// see https://www.sdsc.edu/CCMS/Packages/cambridge/pluto/atom_types.html
// cannot account for covalently bound amino acids etc
// cannot account for covalently bound amino acids etc
// private mapToSybyl(label_atom_id: string, type_symbol: string, bondMap: ComponentBond.Entry) {
private
mapToSybyl
(
label_atom_id1
:
string
,
type_symbol1
:
string
,
bondMap
:
ComponentBond
.
Entry
)
{
// const partialBondMap = bondMap.map.get(label_atom_id)!;
// TODO if altLoc: 'Du' // 1.1
// const bond = this.toArray(partialBondMap);
// TODO if end of polymeric bond: 'Du' // 1.2
if
(
type_symbol1
===
'
D
'
)
return
'
H
'
;
// 1.3
// const num_bond = bond.length;
if
(
type_symbol1
===
'
P
'
)
return
'
P.3
'
;
// 1.4, 4mpo/ligand?encoding=mol2&auth_seq_id=203 (PO4)
// const nonmet = bond.filter(b => this.isNonMetalBond(b));
if
(
type_symbol1
===
'
Co
'
||
type_symbol1
===
'
Ru
'
)
return
type_symbol1
+
'
.oh
'
;
// 1.5
// const num_nonmet = nonmet.length;
// const arom = bond.filter(e => e.aromatic);
const
bonds
=
bondMap
.
map
.
get
(
label_atom_id1
)
!
;
// const num_arom = arom.length;
const
numBonds
=
bonds
.
size
;
// // TODO if altLoc: 'Du' // 1.1
if
(
type_symbol1
===
'
Ti
'
||
type_symbol1
===
'
Cr
'
)
{
// 1.10
// // TODO if end of polymeric bond: 'Du' // 1.2
return
type_symbol1
+
(
numBonds
<=
4
?
'
.th
'
:
'
.oh
'
);
// 1.10.1 & 1.10.2
// if (type_symbol === 'D') return 'H'; // 1.3
}
// if (type_symbol === 'P') return 'P.3'; // 1.4, 4mpo/ligand?encoding=mol2&auth_seq_id=203 (PO4)
if
(
type_symbol1
===
'
C
'
)
{
// 1.6
// if (type_symbol === 'Co' || type_symbol === 'Ru') return type_symbol + '.oh'; // 1.5
if
(
numBonds
>=
4
&&
this
.
count
(
bonds
,
(
_k
,
v
)
=>
v
.
order
===
1
)
>=
4
)
return
'
C.3
'
;
// 1.6.1, 3rga/ligand?encoding=mol2&auth_seq_id=307 (MOH)
// if (type_symbol === 'C') { // 1.6
if
(
numBonds
===
3
&&
this
.
isCat
(
bonds
,
bondMap
))
return
'
C.cat
'
;
// 1.6.2, 1acj/ligand?encoding=mol2&auth_seq_id=44 (ARG), 5vjb/ligand?encoding=mol2&auth_seq_id=101 (GAI)
// if (num_bond >= 4 && bond.every(b => b.order === 1)) return 'C.3'; // 1.6.1, 3rga/ligand?encoding=mol2&auth_seq_id=307 (MOH)
if
(
numBonds
>=
2
&&
this
.
count
(
bonds
,
(
_k
,
v
)
=>
BondType
.
is
(
BondType
.
Flag
.
Aromatic
,
v
.
flags
))
>=
2
)
return
'
C.ar
'
;
// 1.6.3, 1acj/ligand?encoding=mol2&auth_seq_id=30 (PHE), 1acj/ligand?encoding=mol2&auth_seq_id=63 (TYR), 1acj/ligand?encoding=mol2&auth_seq_id=84 (TRP), 1acj/ligand?encoding=mol2&auth_seq_id=999 (THA)
// if (num_bond === 3 && this.isCat(label_atom_id, bond, bondMap)) return 'C.cat'; // 1.6.2, 1acj/ligand?encoding=mol2&auth_seq_id=44 (ARG), 5vjb/ligand?encoding=mol2&auth_seq_id=101 (GAI)
if
((
numBonds
===
1
||
numBonds
===
2
)
&&
this
.
count
(
bonds
,
(
_k
,
v
)
=>
v
.
order
===
3
))
return
'
C.1
'
;
// 1.6.4, 3i04/ligand?encoding=mol2&auth_asym_id=C&auth_seq_id=900 (CYN)
// if (num_bond >= 2 && num_arom >= 2) return 'C.ar'; // 1.6.3, 1acj/ligand?encoding=mol2&auth_seq_id=30 (PHE), 1acj/ligand?encoding=mol2&auth_seq_id=63 (TYR), 1acj/ligand?encoding=mol2&auth_seq_id=84 (TRP), 1acj/ligand?encoding=mol2&auth_seq_id=999 (THA)
return
'
C.2
'
;
// 1.6.5
// if ((num_bond === 1 || num_bond === 2) && bond.filter(b => b.order === 3).length === 1) return 'C.1'; // 1.6.4, 3i04/ligand?encoding=mol2&auth_asym_id=C&auth_seq_id=900 (CYN)
}
// return 'C.2'; // 1.6.5
// }
// most of the time, bonds will equal non-metal bonds
// if (type_symbol === 'O') { // 1.7
const
nonmets
=
this
.
count
(
bonds
,
(
k
,
_v
)
=>
this
.
isNonMetalBond
(
k
))
===
bonds
.
size
?
bonds
:
this
.
extractNonmets
(
bonds
);
// if (num_nonmet === 1) { // 1.7.1
const
numNonmets
=
nonmets
.
size
;
// if (this.isOC(nonmet[0], bondMap)) return 'O.co2'; // 1.7.1.1, 4h2v/ligand?encoding=mol2&auth_seq_id=403 (ACT)
// if (this.isOP(nonmet[0], bondMap)) return 'O.co2'; // 1.7.1.2, 4mpo/ligand?encoding=mol2&auth_seq_id=203 (PO4)
if
(
type_symbol1
===
'
O
'
)
{
// 1.7
// }
if
(
numNonmets
===
1
)
{
// 1.7.1
// if (num_nonmet >= 2 && bond.every(b => b.order === 1)) return 'O.3'; // 1.7.2, 1acj/ligand?encoding=mol2&auth_seq_id=601 (HOH), 3rga/ligand?encoding=mol2&auth_seq_id=307 (MOH)
if
(
this
.
isOC
(
nonmets
,
bondMap
))
return
'
O.co2
'
;
// 1.7.1.1, 4h2v/ligand?encoding=mol2&auth_seq_id=403 (ACT)
// return 'O.2'; // 1.7.3, 1acj/ligand?encoding=mol2&auth_seq_id=4 (SER)
if
(
this
.
isOP
(
nonmets
,
bondMap
))
return
'
O.co2
'
;
// 1.7.1.2, 4mpo/ligand?encoding=mol2&auth_seq_id=203 (PO4)
// }
}
// if (type_symbol === 'N') { // 1.8
if
(
numNonmets
>=
2
&&
this
.
count
(
bonds
,
(
_k
,
v
)
=>
v
.
order
===
1
)
===
bonds
.
size
)
return
'
O.3
'
;
// 1.7.2, 1acj/ligand?encoding=mol2&auth_seq_id=601 (HOH), 3rga/ligand?encoding=mol2&auth_seq_id=307 (MOH)
// if (num_nonmet === 4 && bond.every(b => b.order === 1)) return 'N.4'; // 1.8.1, 4ikf/ligand?encoding=mol2&auth_seq_id=403 (NH4)
return
'
O.2
'
;
// 1.7.3, 1acj/ligand?encoding=mol2&auth_seq_id=4 (SER)
// if (num_bond >= 2 && num_arom === 2) return 'N.ar'; // 1.8.2, 1acj/ligand?encoding=mol2&auth_seq_id=84 (TRP), 1acj/ligand?encoding=mol2&auth_seq_id=999 (THA)
}
// if (num_nonmet === 1 && nonmet.some(b => b.order === 3)) return 'N.1'; // 1.8.3, 3i04/ligand?encoding=mol2&auth_asym_id=C&auth_seq_id=900 (CYN)
if
(
type_symbol1
===
'
N
'
)
{
// 1.8
// if (num_nonmet === 2 && (nonmet[0].order + nonmet[1].order === 4)) return 'N.1'; // 1.8.4, 3sbr/ligand?encoding=mol2&auth_seq_id=640&auth_asym_id=D (N2O)
if
(
numNonmets
===
4
&&
this
.
count
(
nonmets
,
(
_k
,
v
)
=>
v
.
order
===
1
)
===
4
)
return
'
N.4
'
;
// 1.8.1, 4ikf/ligand?encoding=mol2&auth_seq_id=403 (NH4)
// if (num_nonmet === 3 && this.hasCOCS(nonmet, bondMap)) return 'N.am'; // 1.8.5, 3zfz/ligand?encoding=mol2&auth_seq_id=1669 (1W8)
if
(
numBonds
>=
2
&&
this
.
count
(
bonds
,
(
_k
,
v
)
=>
BondType
.
is
(
BondType
.
Flag
.
Aromatic
,
v
.
flags
))
>=
2
)
return
'
N.ar
'
;
// 1.8.2, 1acj/ligand?encoding=mol2&auth_seq_id=84 (TRP), 1acj/ligand?encoding=mol2&auth_seq_id=999 (THA)
// if (num_nonmet === 3) { // 1.8.6
if
(
numNonmets
===
1
&&
this
.
count
(
nonmets
,
(
_k
,
v
)
=>
v
.
order
===
3
))
return
'
N.1
'
;
// 1.8.3, 3i04/ligand?encoding=mol2&auth_asym_id=C&auth_seq_id=900 (CYN)
// if (nonmet.filter(b => b.order > 1).length === 1) return 'N.pl3'; // 1.8.6.1, 4hon/ligand?encoding=mol2&auth_seq_id=407 (NO3)
if
(
numNonmets
===
2
&&
this
.
orderSum
(
nonmets
)
===
4
)
return
'
N.1
'
;
// 1.8.4, 3sbr/ligand?encoding=mol2&auth_seq_id=640&auth_asym_id=D (N2O)
// if (nonmet.every(b => b.order === 1)) {
if
(
numNonmets
===
3
&&
this
.
hasCOCS
(
nonmets
,
bondMap
))
return
'
N.am
'
;
// 1.8.5, 3zfz/ligand?encoding=mol2&auth_seq_id=1669 (1W8)
// if (this.isNpl3(nonmet, bondMap)) return 'N.pl3'; // 1.8.6.1.1 & 1.8.6.1.2, 1acj/ligand?encoding=mol2&auth_seq_id=44 (ARG), 5vjb/ligand?encoding=mol2&auth_seq_id=101 (GAI)
if
(
numNonmets
===
3
)
{
// 1.8.6
// }
if
(
this
.
count
(
nonmets
,
(
_k
,
v
)
=>
v
.
order
>
1
)
===
1
)
return
'
N.pl3
'
;
// 1.8.6.1, 4hon/ligand?encoding=mol2&auth_seq_id=407 (NO3)
// return 'N.3';
if
(
this
.
count
(
nonmets
,
(
_k
,
v
)
=>
v
.
order
===
1
)
===
3
)
{
// }
if
(
this
.
isNpl3
(
nonmets
,
bondMap
))
return
'
N.pl3
'
;
// 1.8.6.1.1 & 1.8.6.1.2, 1acj/ligand?encoding=mol2&auth_seq_id=44 (ARG), 5vjb/ligand?encoding=mol2&auth_seq_id=101 (GAI)
// return 'N.2'; // 1.8.7, 1acj/ligand?encoding=mol2&auth_seq_id=4 (SER)
}
// }
return
'
N.3
'
;
// if (type_symbol === 'S') { // 1.9
}
// if (num_nonmet === 3 && this.countOfOxygenWithSingleNonmet(nonmet, bondMap) === 1) return 'S.o'; // 1.9.1, 4i03/ligand?encoding=mol2&auth_seq_id=312 (DMS)
return
'
N.2
'
;
// 1.8.7, 1acj/ligand?encoding=mol2&auth_seq_id=4 (SER)
// if (num_nonmet === 4 && this.countOfOxygenWithSingleNonmet(nonmet, bondMap) === 2) return 'S.o2'; // 1.9.2, 1udt/ligand?encoding=mol2&auth_seq_id=1000 (VIA)
}
// if (num_nonmet >= 2 && bond.every(b => b.order === 1)) return 'S.3'; // 1.9.3, 3zfz/ligand?encoding=mol2&auth_seq_id=1669 (1W8)
if
(
type_symbol1
===
'
S
'
)
{
// 1.9
// return 'S.2'; // 1.9.4, 4gpc/ligand?encoding=mol2&auth_seq_id=902 (SO4)
if
(
numNonmets
===
3
&&
this
.
countOfOxygenWithSingleNonmet
(
nonmets
,
bondMap
)
===
1
)
return
'
S.o
'
;
// 1.9.1, 4i03/ligand?encoding=mol2&auth_seq_id=312 (DMS)
// }
if
(
numNonmets
===
4
&&
this
.
countOfOxygenWithSingleNonmet
(
nonmets
,
bondMap
)
===
2
)
return
'
S.o2
'
;
// 1.9.2, 1udt/ligand?encoding=mol2&auth_seq_id=1000 (VIA)
// if (type_symbol === 'Ti' || type_symbol === 'Cr') { // 1.10
if
(
numNonmets
>=
2
&&
this
.
count
(
bonds
,
(
_k
,
v
)
=>
v
.
order
===
1
)
>=
2
)
return
'
S.3
'
;
// 1.9.3, 3zfz/ligand?encoding=mol2&auth_seq_id=1669 (1W8), 4gpc/ligand?encoding=mol2&auth_seq_id=902 (SO4)
// return type_symbol + (num_bond <= 4 ? '.th' : '.oh'); // 1.10.1 & 1.10.2
return
'
S.2
'
;
// 1.9.4
// }
}
// return type_symbol; // 1.11
return
type_symbol1
;
// 1.11
// }
}
// private isNonMetalBond(b: BondData): boolean {
// 1.8.6.2.1: If one single bond is to an atom that forms a bond of type double, triple, aromatic or
// // would be nice to have type_symbol here...
// delocalised .AND. one other single bond is to H then atom_type is N.pl3
// return NON_METAL_ATOMS.some(a => this.getLabel(b.label_atom_id).startsWith(a));
// 1.8.6.2.2: If one single bond is to an atom that forms a bond of type double, triple, aromatic or
// }
// delocalised .AND. neither of the other single bonds are to H .AND. sum_of_angles around N .ge. 350 deg then atom_type is N.pl3
// TODO cannot check accurately for delocalized bonds
// // 1.8.6.2.1: If one single bond is to an atom that forms a bond of type double, triple, aromatic or
private
isNpl3
(
nonmets
:
BondMap
,
bondMap
:
ComponentBond
.
Entry
):
boolean
{
// // delocalised .AND. one other single bond is to H then atom_type is N.pl3
const
iter
=
nonmets
.
keys
();
// // 1.8.6.2.2: If one single bond is to an atom that forms a bond of type double, triple, aromatic or
let
result
=
iter
.
next
();
// // delocalised .AND. neither of the other single bonds are to H .AND. sum_of_angles around N .ge. 350 deg then atom_type is N.pl3
while
(
!
result
.
done
)
{
// // TODO cannot check accurately for delocalized bonds
const
label_atom_id
=
result
.
value
;
// // TODO cannot check accurately for 2nd criterion without coordinates
const
adjacentBonds
=
bondMap
.
map
.
get
(
label_atom_id
)
!
;
// private isNpl3(nonmet: BondData[], bondMap: ComponentBond.Entry): boolean {
if
(
this
.
count
(
adjacentBonds
,
(
_k
,
v
)
=>
v
.
order
>
1
||
BondType
.
is
(
BondType
.
Flag
.
Aromatic
,
v
.
flags
)))
{
// for (let i = 0, il = nonmet.length; i < il; i++) {
// TODO check accurately for 2nd criterion with coordinates
// const consumed = nonmet[i];
return
true
;
// // determine index that fulfills 1st criterion
}
// if (this.toArray(bondMap.map.get(consumed.label_atom_id)!).some(b => b.order > 1 || b.aromatic)) {
result
=
iter
.
next
();
// if (nonmet.filter(b => b !== consumed).filter(b => this.getLabel(b.label_atom_id).startsWith('H')).length === 1) return true; // 1.8.6.2.1
}
// if (nonmet.filter(b => b !== consumed).every(b => !this.getLabel(b.label_atom_id).startsWith('H'))) return true; // 1.8.6.2.2
return
false
;
// }
}
// }
// return false;
// If bond is to carbon .AND. carbon forms a total of 3 bonds, 2 of which are to an oxygen
// }
// forming only 1 non-metal bond then atom_type is O.co2
private
isOC
(
nonmets
:
BondMap
,
bondMap
:
ComponentBond
.
Entry
):
boolean
{
// // If bond is to carbon .AND. carbon forms a total of 3 bonds, 2 of which are to an oxygen
const
nonmet
=
nonmets
.
entries
().
next
()
!
.
value
as
[
string
,
{
order
:
number
,
flags
:
number
}];
// // forming only 1 non-metal bond then atom_type is O.co2
if
(
!
nonmet
[
0
].
startsWith
(
'
C
'
))
return
false
;
// private isOC(nonmet: BondData, bondMap: ComponentBond.Entry): boolean {
const
carbonBonds
=
bondMap
.
map
.
get
(
nonmet
[
0
])
!
;
// if (!this.getLabel(nonmet.label_atom_id).startsWith('C')) return false;
if
(
carbonBonds
.
size
!==
3
)
return
false
;
// const carbonBonds = this.toArray(bondMap.map.get(nonmet.label_atom_id)!);
// if (carbonBonds.length !== 3) return false;
let
count
=
0
;
// return carbonBonds.filter(b => this.getLabel(b.label_atom_id).startsWith('O') &&
const
iter
=
carbonBonds
.
keys
();
// this.toArray(bondMap.map.get(b.label_atom_id)!).filter(ob => this.isNonMetalBond(ob)).length === 1).length === 2;
let
result
=
iter
.
next
();
// }
while
(
!
result
.
done
)
{
const
label_atom_id
=
result
.
value
;
// // If bond is to phosphorus .AND. phosphorus forms at least 2 bonds to an oxygen forming
if
(
label_atom_id
.
startsWith
(
'
O
'
))
{
// // only 1 non-metal bond then atom_type is O.co2
const
adjacentBonds
=
bondMap
.
map
.
get
(
label_atom_id
)
!
;
// private isOP(nonmet: BondData, bondMap: ComponentBond.Entry): boolean {
if
(
this
.
count
(
adjacentBonds
,
(
k
,
_v
)
=>
this
.
isNonMetalBond
(
k
))
===
1
)
count
++
;
// if (!this.getLabel(nonmet.label_atom_id).startsWith('P')) return false;
}
// const phosphorusBonds = this.toArray(bondMap.map.get(nonmet.label_atom_id)!);
result
=
iter
.
next
();
// if (phosphorusBonds.length < 2) return false;
}
// return phosphorusBonds.filter(b => this.getLabel(b.label_atom_id).startsWith('O') &&
return
count
===
2
;
// this.toArray(bondMap.map.get(b.label_atom_id)!).filter(ob => this.isNonMetalBond(ob)).length === 1).length >= 2;
}
// }
// If bond is to phosphorus .AND. phosphorus forms at least 2 bonds to an oxygen forming
// // If num_bond .eq. 3 .AND. all bonds are acyclic .AND. all bonds are to nitrogen .AND. each
// only 1 non-metal bond then atom_type is O.co2
// // nitrogen forms bonds to 2 other atoms both of which are not oxygen then atom_type is C.cat.
private
isOP
(
nonmets
:
BondMap
,
bondMap
:
ComponentBond
.
Entry
):
boolean
{
// private isCat(root: string, bond: BondData[], bondMap: ComponentBond.Entry): boolean {
const
nonmet
=
nonmets
.
entries
().
next
()
!
.
value
as
[
string
,
{
order
:
number
,
flags
:
number
}];
// if (bond.some(b => !this.getLabel(b.label_atom_id).startsWith('N'))) return false;
if
(
!
nonmet
[
0
].
startsWith
(
'
P
'
))
return
false
;
// const nitrogenBonds = bond.map(b => b.label_atom_id).map(label_atom_id => this.toArray(bondMap.map.get(label_atom_id)!));
const
phosphorusBonds
=
bondMap
.
map
.
get
(
nonmet
[
0
])
!
;
if
(
phosphorusBonds
.
size
<
2
)
return
false
;
// // ensure no cycles
// const all = [];
let
count
=
0
;
// const unique = new Set();
const
iter
=
phosphorusBonds
.
keys
();
// nitrogenBonds.forEach(a => a.map(b => b.label_atom_id).filter(lai => lai !== root).forEach(lai => { all.push(lai); unique.add(lai); }));
let
result
=
iter
.
next
();
// if (all.length !== unique.size) return false;
while
(
!
result
.
done
)
{
const
label_atom_id
=
result
.
value
;
// return nitrogenBonds.every(a => a.length >= 2 && a.every(b => b.label_atom_id !== 'O'));
if
(
label_atom_id
.
startsWith
(
'
O
'
))
{
// }
const
adjacentBonds
=
bondMap
.
map
.
get
(
label_atom_id
)
!
;
if
(
this
.
count
(
adjacentBonds
,
(
k
,
_v
)
=>
this
.
isNonMetalBond
(
k
))
===
1
)
count
++
;
// private countOfOxygenWithSingleNonmet(nonmet: BondData[], bondMap: ComponentBond.Entry): number {
}
// return nonmet.map(b => b.label_atom_id)
result
=
iter
.
next
();
// .filter(label_atom_id => this.getLabel(label_atom_id).startsWith('O'))
}
// .map(label_atom_id => this.toArray(bondMap.map.get(label_atom_id)!)
return
count
>=
2
;
// .filter(b => this.isNonMetalBond(b)).length === 1)
}
// .length;
// }
// If num_bond .eq. 3 .AND. all bonds are acyclic .AND. all bonds are to nitrogen .AND. each
// nitrogen forms bonds to 2 other atoms both of which are not oxygen then atom_type is C.cat.
// // If num_nonmet .eq. 3 .AND. one bond is to C=O or C=S then atom_type is N.am
private
isCat
(
currentBondMap
:
BondMap
,
bondMap
:
ComponentBond
.
Entry
):
boolean
{
// private hasCOCS(nonmet: BondData[], bondMap: ComponentBond.Entry): boolean {
const
iter1
=
currentBondMap
.
keys
();
// return nonmet.map(b => b.label_atom_id)
let
result1
=
iter1
.
next
();
// .filter(label_atom_id => this.getLabel(label_atom_id).startsWith('C'))
while
(
!
result1
.
done
)
{
// .filter(label_atom_id => this.toArray(bondMap.map.get(label_atom_id)!)
const
label_atom_id
=
result1
.
value
;
// .filter(b => b.order === 2)
if
(
!
label_atom_id
.
startsWith
(
'
N
'
))
return
false
;
// .filter(b => this.getLabel(b.label_atom_id).startsWith('O') || this.getLabel(b.label_atom_id).startsWith('S')))
// .length === 1;
const
adjacentBonds
=
bondMap
.
map
.
get
(
label_atom_id
)
!
;
// }
if
(
adjacentBonds
.
size
<
2
)
return
false
;
const
iter2
=
adjacentBonds
.
keys
();
let
result2
=
iter2
.
next
();
while
(
!
result2
.
done
)
{
if
(
result2
.
value
.
startsWith
(
'
O
'
))
return
false
;
result2
=
iter2
.
next
();
}
result1
=
iter1
.
next
();
}
// TODO ensure no cycles
return
true
;
}
private
countOfOxygenWithSingleNonmet
(
nonmets
:
BondMap
,
bondMap
:
ComponentBond
.
Entry
):
number
{
let
count
=
0
;
const
iter
=
nonmets
.
keys
();
let
result
=
iter
.
next
();
while
(
!
result
.
done
)
{
const
label_atom_id
=
result
.
value
;
if
(
label_atom_id
.
startsWith
(
'
O
'
))
{
const
adjacentBonds
=
bondMap
.
map
.
get
(
label_atom_id
)
!
;
if
(
this
.
count
(
adjacentBonds
,
(
k
,
_v
)
=>
this
.
isNonMetalBond
(
k
)))
count
++
;
}
result
=
iter
.
next
();
}
return
count
;
}
// If num_nonmet .eq. 3 .AND. one bond is to C=O or C=S then atom_type is N.am
private
hasCOCS
(
nonmets
:
BondMap
,
bondMap
:
ComponentBond
.
Entry
):
boolean
{
const
iter
=
nonmets
.
keys
();
let
result
=
iter
.
next
();
while
(
!
result
.
done
)
{
const
label_atom_id
=
result
.
value
;
if
(
label_atom_id
.
startsWith
(
'
C
'
))
{
const
adjacentBonds
=
bondMap
.
map
.
get
(
label_atom_id
)
!
;
if
(
this
.
count
(
adjacentBonds
,
(
k
,
v
)
=>
k
.
startsWith
(
'
O
'
)
||
k
.
startsWith
(
'
S
'
)
&&
v
.
order
===
2
))
return
true
;
}
result
=
iter
.
next
();
}
return
false
;
}
protected
writeFullCategory
<
Ctx
>
(
sb
:
StringBuilder
,
category
:
Category
<
Ctx
>
,
context
?:
Ctx
)
{
protected
writeFullCategory
<
Ctx
>
(
sb
:
StringBuilder
,
category
:
Category
<
Ctx
>
,
context
?:
Ctx
)
{
const
{
instance
,
source
}
=
getCategoryInstanceData
(
category
,
context
);
const
{
instance
,
source
}
=
getCategoryInstanceData
(
category
,
context
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment