diff --git a/.github/workflows/indigo-ci.yaml b/.github/workflows/indigo-ci.yaml
index 4a7a05e49b..a3a13af246 100644
--- a/.github/workflows/indigo-ci.yaml
+++ b/.github/workflows/indigo-ci.yaml
@@ -676,7 +676,7 @@ jobs:
python setup.py bdist_wheel
cp dist/*.whl ${GITHUB_WORKSPACE}/dist/
- name: Run pylint
- run: pylint bingo_elastic
+ run: pylint --max-args 10 bingo_elastic
working-directory: bingo/bingo-elastic/python
- name: Run tests
run: pytest tests
diff --git a/api/c/indigo/src/indigo_layout.cpp b/api/c/indigo/src/indigo_layout.cpp
index eec28abc5f..d1d3ad72cd 100644
--- a/api/c/indigo/src/indigo_layout.cpp
+++ b/api/c/indigo/src/indigo_layout.cpp
@@ -58,19 +58,16 @@ CEXPORT int indigoLayout(int object)
ml.max_iterations = self.layout_max_iterations;
ml.bond_length = 1.6f;
ml.layout_orientation = (layout_orientation_value)self.layout_orientation;
- bool has_atropisomery = mol->hasAtropisomericCenter();
- if (has_atropisomery)
+ if (mol->hasAtropoStereoBonds())
ml.respect_existing_layout = true;
TimeoutCancellationHandler cancellation(self.cancellation_timeout);
ml.setCancellationHandler(&cancellation);
-
ml.make();
if (obj.type != IndigoObject::SUBMOLECULE)
{
- if (!has_atropisomery)
- mol->clearBondDirections();
+ mol->clearBondDirections();
try
{
mol->markBondsStereocenters();
diff --git a/api/tests/integration/ref/basic/buffer_string_load_iterate.py.out b/api/tests/integration/ref/basic/buffer_string_load_iterate.py.out
index 3c241d861f..9ef808c527 100644
--- a/api/tests/integration/ref/basic/buffer_string_load_iterate.py.out
+++ b/api/tests/integration/ref/basic/buffer_string_load_iterate.py.out
@@ -35741,7 +35741,7 @@ C(O)(C)C=C>>C(=O)(C)CC
[C:1]1([F:33])([O:4][C:10]2[C:15]([F:20])=[C:19]([C:21]([F:24])=[C:17]([F:22])[C:14]=2[F:18])[F:23])[C:3]([F:9])=[C:8]([C:11](=O)[C:6]([F:12])=[C:2]1[F:7])[F:13].[C:25]1([NH:28][NH2:31])=[CH:27][CH:30]=[CH:32][CH:29]=[CH:26]1>>[C:1]1(=[C:3]([F:9])[C:8](=[C:11]([N:31]=[N:28][C:25]2[CH:26]=[CH:29][CH:32]=[CH:30][CH:27]=2)[C:6]([F:12])=[C:2]1[F:7])[F:13])[O:4][C:10]1[C:15]([F:20])=[C:19]([C:21]([F:24])=[C:17]([F:22])[C:14]=1[F:18])[F:23].[C:11]1([N:31]=[N:28][C:25]2[CH:26]=[CH:29][CH:32]=[CH:30][CH:27]=2)[C:8]([F:13])=[C:3]([C:1]([F:33])=[C:2]([F:7])[C:6]=1[F:12])[F:9]
[C@:1]1([H])([C:4]#[C:8][CH3:13])[CH2:3][O:7]C(C)(C)[N:2]1[C:6](=[O:12])OC(C)(C)C.C(C)(C)(C)OC(=O)OC(=O)[O:19][C:18]([CH3:22])([CH3:21])[CH3:20]>>[C@H:1]([C:3](=O)[OH:7])([C:4]#[C:8][CH3:13])[NH:2][C:6](=[O:12])[O:19][C:18]([CH3:22])([CH3:21])[CH3:20].[NH:2]([C:1](=O)[C:4]#[C:8][CH3:13])[C:6](=[O:12])[O:19][C:18]([CH3:22])([CH3:21])[CH3:20]
[C:1]1([Si](C)(C)C)([O:21][CH2:3]1)[CH:2](OS(=O)(=O)C)[C:6]1([CH2:13][CH2:15][CH2:19][CH3:20])[O:22][CH2:11]1>>[C:6]1([CH2:13][CH2:15][CH2:19][CH3:20])=[CH:11][O:22][C:1]([CH2:3]F)=[CH:2]1.[C:6]1([CH2:13][CH2:15][CH2:19][CH3:20])=[CH:11][O:22][C:1]([CH2:3][OH:21])=[CH:2]1
-[C:1]1([O:48][CH2:4]1)([C@@:3]1([H])[CH2:9][CH2:17][C@@:14]2([H])[C@:24]3([H])[CH2:27][CH:29]=[C:30]4[CH2:33][C@H:35]([CH2:34][CH2:31][C@:28]4([CH3:32])[C@@:26]3([H])[CH2:25][CH2:15][C@:8]12[CH3:16])[O:36][Si](C)(C)C(C)(C)C)[CH:2](OS(=O)(=O)C)[C:6]1([Si](C)(C)C)[O:49][CH2:10]1>>[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10]F)=[CH:2]1.[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10][OH:49])=[CH:2]1 |w:0,34,40,a:3,7,9,15,18,20,24,47,51,53,57,63,65,69,78,82,84,88,94,96,100|
+[C@:1]1([O:48][CH2:4]1)([C@@:3]1([H])[CH2:9][CH2:17][C@@:14]2([H])[C@:24]3([H])[CH2:27][CH:29]=[C:30]4[CH2:33][C@H:35]([CH2:34][CH2:31][C@:28]4([CH3:32])[C@@:26]3([H])[CH2:25][CH2:15][C@:8]12[CH3:16])[O:36][Si](C)(C)C(C)(C)C)[CH:2](OS(=O)(=O)C)[C:6]1([Si](C)(C)C)[O:49][CH2:10]1>>[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10]F)=[CH:2]1.[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10][OH:49])=[CH:2]1 |a:0,3,7,9,15,18,20,24,47,51,53,57,63,65,69,78,82,84,88,94,96,100,w:34,40|
[C@H:1]1([CH2:4][C:9](=[O:13])[O:12][CH3:14])[C:3](=[O:8])[CH2:7][C@@:10]2([H])[CH:11]=[CH:6][C@:2]1([H])[O:29]2.S(=O)(=O)(C(F)(F)F)O[Si:22]([CH3:28])([CH3:27])[CH3:26]>>[CH:10]1([O:29][Si:22]([CH3:28])([CH3:27])[CH3:26])[CH2:11][CH2:6][CH:2]=[C:1]([CH2:4][C:9](=[O:13])[O:12][CH3:14])[C:3](=[O:8])[CH2:7]1.[C@@H:2]1([CH2:6][CH2:11][CH:10]=[CH:7][C:3](=[O:8])[C@@H:1]1[CH2:4][C:9](=[O:13])[O:12][CH3:14])[O:29][Si:22]([CH3:28])([CH3:27])[CH3:26].[C@@:3]12([CH:7]=[CH:10][CH2:11][CH2:6][C@H:2]([O:29][Si:22]([CH3:28])([CH3:27])[CH3:26])[C@@:1]1([H])[C@@H:4]2[C:9](=[O:13])[O:12][CH3:14])[O:8][Si:22]([CH3:28])([CH3:27])[CH3:26] |&1:0,9,13,46,53,64,69,75,77|
[C:1]1([O:4][Si:8]([CH3:14])([CH3:13])[C:12]([CH3:21])([CH3:20])[CH3:19])=[CH:3][C:7](=[CH:9][CH:5]=[C:2]1[O:6][Si:10]([CH3:17])([CH3:16])[C:15]([CH3:24])([CH3:23])[CH3:22])[CH2:11][N:18]([C:26](=[O:29])[C:28]([F:33])([F:32])[F:31])[CH2:25][CH2:27][C:30]1[CH:35]=[CH:37][C:38]([OH:39])=[CH:36][CH:34]=1>>[C:30]12([CH:34]=[CH:36][C:38](=[O:39])[CH:37]=[CH:35]1)[CH2:27][CH2:25][N:18]([CH2:11][C:7]1[CH:3]=[C:1]([C:2]([O:6][Si:10]([CH3:16])([CH3:17])[C:15]([CH3:24])([CH3:22])[CH3:23])=[CH:5][C:9]2=1)[O:4][Si:8]([CH3:13])([CH3:14])[C:12]([CH3:21])([CH3:19])[CH3:20])[C:26](=[O:29])[C:28]([F:33])([F:31])[F:32].[C:9]12[CH:5]=[C:2]([C:1]([O:4][Si:8]([CH3:13])([CH3:14])[C:12]([CH3:21])([CH3:19])[CH3:20])=[CH:3][C:7]=1[CH2:11][N:18]([C:26](=[O:29])[C:28]([F:33])([F:31])[F:32])[CH2:25][CH2:27][C:30]1[CH:34]=[CH:36][C:38]([OH:39])=[CH:37][C:35]2=1)[O:6][Si:10]([CH3:16])([CH3:17])[C:15]([CH3:24])([CH3:22])[CH3:23]
[C:12]1([N+:11]([O-:4])=[O:5])=[CH:7][C:9](=[C:8]([F:1])[CH:6]=[C:10]1[F:3])[F:2].[C:23]([CH3:15])([CH3:14])([CH3:13])[O:25][C:24](=[O:17])[N:26]1[CH2:21][CH2:19][CH:22]([OH:16])[CH2:18][CH2:20]1>>[C:8]1([CH:6]=[C:10]([C:12]([N+:11]([O-:4])=[O:5])=[CH:7][C:9]=1[F:2])[F:3])[O:16][CH:22]1[CH2:19][CH2:21][N:26]([C:24](=[O:17])[O:25][C:23]([CH3:15])([CH3:13])[CH3:14])[CH2:20][CH2:18]1.[C:10]1(=[CH:6][C:8](=[C:9]([F:2])[CH:7]=[C:12]1[N+:11]([O-:4])=[O:5])[F:1])[O:16][CH:22]1[CH2:19][CH2:21][N:26]([C:24](=[O:17])[O:25][C:23]([CH3:15])([CH3:13])[CH3:14])[CH2:20][CH2:18]1
@@ -36072,7 +36072,7 @@ C(O)(C)C=C>>C(=O)(C)CC
[C:1]1([F:33])([O:4][C:10]2[C:15]([F:20])=[C:19]([C:21]([F:24])=[C:17]([F:22])[C:14]=2[F:18])[F:23])[C:3]([F:9])=[C:8]([C:11](=O)[C:6]([F:12])=[C:2]1[F:7])[F:13].[C:25]1([NH:28][NH2:31])=[CH:27][CH:30]=[CH:32][CH:29]=[CH:26]1>>[C:1]1(=[C:3]([F:9])[C:8](=[C:11]([N:31]=[N:28][C:25]2[CH:26]=[CH:29][CH:32]=[CH:30][CH:27]=2)[C:6]([F:12])=[C:2]1[F:7])[F:13])[O:4][C:10]1[C:15]([F:20])=[C:19]([C:21]([F:24])=[C:17]([F:22])[C:14]=1[F:18])[F:23].[C:11]1([N:31]=[N:28][C:25]2[CH:26]=[CH:29][CH:32]=[CH:30][CH:27]=2)[C:8]([F:13])=[C:3]([C:1]([F:33])=[C:2]([F:7])[C:6]=1[F:12])[F:9]
[C@:1]1([H])([C:4]#[C:8][CH3:13])[CH2:3][O:7]C(C)(C)[N:2]1[C:6](=[O:12])OC(C)(C)C.C(C)(C)(C)OC(=O)OC(=O)[O:19][C:18]([CH3:22])([CH3:21])[CH3:20]>>[C@H:1]([C:3](=O)[OH:7])([C:4]#[C:8][CH3:13])[NH:2][C:6](=[O:12])[O:19][C:18]([CH3:22])([CH3:21])[CH3:20].[NH:2]([C:1](=O)[C:4]#[C:8][CH3:13])[C:6](=[O:12])[O:19][C:18]([CH3:22])([CH3:21])[CH3:20]
[C:1]1([Si](C)(C)C)([O:21][CH2:3]1)[CH:2](OS(=O)(=O)C)[C:6]1([CH2:13][CH2:15][CH2:19][CH3:20])[O:22][CH2:11]1>>[C:6]1([CH2:13][CH2:15][CH2:19][CH3:20])=[CH:11][O:22][C:1]([CH2:3]F)=[CH:2]1.[C:6]1([CH2:13][CH2:15][CH2:19][CH3:20])=[CH:11][O:22][C:1]([CH2:3][OH:21])=[CH:2]1
-[C:1]1([O:48][CH2:4]1)([C@@:3]1([H])[CH2:9][CH2:17][C@@:14]2([H])[C@:24]3([H])[CH2:27][CH:29]=[C:30]4[CH2:33][C@H:35]([CH2:34][CH2:31][C@:28]4([CH3:32])[C@@:26]3([H])[CH2:25][CH2:15][C@:8]12[CH3:16])[O:36][Si](C)(C)C(C)(C)C)[CH:2](OS(=O)(=O)C)[C:6]1([Si](C)(C)C)[O:49][CH2:10]1>>[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10]F)=[CH:2]1.[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10][OH:49])=[CH:2]1 |w:0,34,40,a:3,7,9,15,18,20,24,47,51,53,57,63,65,69,78,82,84,88,94,96,100|
+[C@:1]1([O:48][CH2:4]1)([C@@:3]1([H])[CH2:9][CH2:17][C@@:14]2([H])[C@:24]3([H])[CH2:27][CH:29]=[C:30]4[CH2:33][C@H:35]([CH2:34][CH2:31][C@:28]4([CH3:32])[C@@:26]3([H])[CH2:25][CH2:15][C@:8]12[CH3:16])[O:36][Si](C)(C)C(C)(C)C)[CH:2](OS(=O)(=O)C)[C:6]1([Si](C)(C)C)[O:49][CH2:10]1>>[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10]F)=[CH:2]1.[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10][OH:49])=[CH:2]1 |a:0,3,7,9,15,18,20,24,47,51,53,57,63,65,69,78,82,84,88,94,96,100,w:34,40|
[C@H:1]1([CH2:4][C:9](=[O:13])[O:12][CH3:14])[C:3](=[O:8])[CH2:7][C@@:10]2([H])[CH:11]=[CH:6][C@:2]1([H])[O:29]2.S(=O)(=O)(C(F)(F)F)O[Si:22]([CH3:28])([CH3:27])[CH3:26]>>[CH:10]1([O:29][Si:22]([CH3:28])([CH3:27])[CH3:26])[CH2:11][CH2:6][CH:2]=[C:1]([CH2:4][C:9](=[O:13])[O:12][CH3:14])[C:3](=[O:8])[CH2:7]1.[C@@H:2]1([CH2:6][CH2:11][CH:10]=[CH:7][C:3](=[O:8])[C@@H:1]1[CH2:4][C:9](=[O:13])[O:12][CH3:14])[O:29][Si:22]([CH3:28])([CH3:27])[CH3:26].[C@@:3]12([CH:7]=[CH:10][CH2:11][CH2:6][C@H:2]([O:29][Si:22]([CH3:28])([CH3:27])[CH3:26])[C@@:1]1([H])[C@@H:4]2[C:9](=[O:13])[O:12][CH3:14])[O:8][Si:22]([CH3:28])([CH3:27])[CH3:26] |&1:0,9,13,46,53,64,69,75,77|
[C:1]1([O:4][Si:8]([CH3:14])([CH3:13])[C:12]([CH3:21])([CH3:20])[CH3:19])=[CH:3][C:7](=[CH:9][CH:5]=[C:2]1[O:6][Si:10]([CH3:17])([CH3:16])[C:15]([CH3:24])([CH3:23])[CH3:22])[CH2:11][N:18]([C:26](=[O:29])[C:28]([F:33])([F:32])[F:31])[CH2:25][CH2:27][C:30]1[CH:35]=[CH:37][C:38]([OH:39])=[CH:36][CH:34]=1>>[C:30]12([CH:34]=[CH:36][C:38](=[O:39])[CH:37]=[CH:35]1)[CH2:27][CH2:25][N:18]([CH2:11][C:7]1[CH:3]=[C:1]([C:2]([O:6][Si:10]([CH3:16])([CH3:17])[C:15]([CH3:24])([CH3:22])[CH3:23])=[CH:5][C:9]2=1)[O:4][Si:8]([CH3:13])([CH3:14])[C:12]([CH3:21])([CH3:19])[CH3:20])[C:26](=[O:29])[C:28]([F:33])([F:31])[F:32].[C:9]12[CH:5]=[C:2]([C:1]([O:4][Si:8]([CH3:13])([CH3:14])[C:12]([CH3:21])([CH3:19])[CH3:20])=[CH:3][C:7]=1[CH2:11][N:18]([C:26](=[O:29])[C:28]([F:33])([F:31])[F:32])[CH2:25][CH2:27][C:30]1[CH:34]=[CH:36][C:38]([OH:39])=[CH:37][C:35]2=1)[O:6][Si:10]([CH3:16])([CH3:17])[C:15]([CH3:24])([CH3:22])[CH3:23]
[C:12]1([N+:11]([O-:4])=[O:5])=[CH:7][C:9](=[C:8]([F:1])[CH:6]=[C:10]1[F:3])[F:2].[C:23]([CH3:15])([CH3:14])([CH3:13])[O:25][C:24](=[O:17])[N:26]1[CH2:21][CH2:19][CH:22]([OH:16])[CH2:18][CH2:20]1>>[C:8]1([CH:6]=[C:10]([C:12]([N+:11]([O-:4])=[O:5])=[CH:7][C:9]=1[F:2])[F:3])[O:16][CH:22]1[CH2:19][CH2:21][N:26]([C:24](=[O:17])[O:25][C:23]([CH3:15])([CH3:13])[CH3:14])[CH2:20][CH2:18]1.[C:10]1(=[CH:6][C:8](=[C:9]([F:2])[CH:7]=[C:12]1[N+:11]([O-:4])=[O:5])[F:1])[O:16][CH:22]1[CH2:19][CH2:21][N:26]([C:24](=[O:17])[O:25][C:23]([CH3:15])([CH3:13])[CH3:14])[CH2:20][CH2:18]1
diff --git a/api/tests/integration/ref/basic/molfile_stereo_desc.py.out b/api/tests/integration/ref/basic/molfile_stereo_desc.py.out
index 7a1990e0b6..63cfe19281 100644
--- a/api/tests/integration/ref/basic/molfile_stereo_desc.py.out
+++ b/api/tests/integration/ref/basic/molfile_stereo_desc.py.out
@@ -2360,7 +2360,7 @@ M V30 COUNTS 15 16 1 0 0
M V30 BEGIN ATOM
M V30 1 C 0.0884 2.7107 0.0 0
M V30 2 C -0.6261 2.2982 0.0 0
-M V30 3 C -0.6261 1.4732 0.0 0 CFG=3
+M V30 3 C -0.6261 1.4732 0.0 0 CFG=1
M V30 4 C 0.0884 1.0607 0.0 0
M V30 5 C 0.8029 1.4732 0.0 0
M V30 6 C 0.8029 2.2982 0.0 0
@@ -2393,7 +2393,7 @@ M V30 15 2 13 14
M V30 16 1 13 15
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 7)
+M V30 MDLV30/STERAC1 ATOMS=(2 3 7)
M V30 END COLLECTION
M V30 BEGIN SGROUP
M V30 1 DAT 1 ATOMS=(1 7) FIELDNAME=INDIGO_CIP_DESC FIELDDISP=" 0.0000 -
diff --git a/api/tests/integration/ref/bingo/molecules.py.out b/api/tests/integration/ref/bingo/molecules.py.out
index 97783072cc..6c1a060fc8 100644
--- a/api/tests/integration/ref/bingo/molecules.py.out
+++ b/api/tests/integration/ref/bingo/molecules.py.out
@@ -39,7 +39,7 @@ Structure 275 excluded: molfile loader: direction of bond #7 makes no sense
Structure 276 excluded: element: bad valence on H having 1 drawn bonds, charge 1, and 0 radical electrons
Structure 283 excluded: element: bad valence on N having 4 drawn bonds, charge 0, and 0 radical electrons
Structure 286 excluded: stereocenters: stereo types of the opposite bonds mismatch near atom 0
-Structure 294 excluded: molfile loader: direction of bond #22 makes no sense
+Structure 294 excluded: molfile loader: direction of bond #185 makes no sense
Structure 295 excluded: stereocenters: stereo types of the opposite bonds mismatch near atom 0
Structure 301 excluded: stereocenters: stereo types of the opposite bonds mismatch near atom 1
Structure 316 excluded: stereocenters: stereo types of non-opposite bonds match near atom 30
@@ -263,7 +263,7 @@ Structure 1785 excluded: stereocenters: one bond up, one bond down -- indefinite
Structure 1792 excluded: stereocenters: 2 hydrogens near stereocenter 6
Structure 1797 excluded: element: bad valence on N having 5 drawn bonds, charge 1, and 0 radical electrons
Structure 1799 excluded: molfile loader: direction of bond #45 makes no sense
-Structure 1800 excluded: molfile loader: direction of bond #177 makes no sense
+Structure 1800 excluded: molfile loader: direction of bond #185 makes no sense
Structure 1823 excluded: molfile loader: direction of bond #0 makes no sense
Structure 1830 excluded: molfile loader: direction of bond #1 makes no sense
Structure 1831 excluded: molfile loader: direction of bond #9 makes no sense
@@ -288,7 +288,7 @@ Structure 1926 excluded: molfile loader: direction of bond #7 makes no sense
Structure 1931 excluded: element: bad valence on H having 4 drawn bonds, charge 0, and 0 radical electrons
Structure 1939 excluded: element: bad valence on C having 5 drawn bonds, charge 0, and 0 radical electrons
Structure 1945 excluded: molfile loader: direction of bond #5 makes no sense
-Structure 1948 excluded: molfile loader: direction of bond #22 makes no sense
+Structure 1948 excluded: molfile loader: direction of bond #185 makes no sense
Structure 1952 excluded: molfile loader: direction of bond #3 makes no sense
Structure 1953 excluded: stereocenters: stereo types of the opposite bonds mismatch near atom 0
Structure 1956 excluded: element: bad valence on C having 4 drawn bonds, charge -1, and 1 radical electrons
@@ -1479,7 +1479,7 @@ Finished indexing 2026 structures. 304 wrong structures excluded
1366 c1(N2C[C@H](CNC(C)=O)OC2=O)cc(F)c([C@]2([C@@]3([H])[C@@]2(C[S@@](C3)=O)[H])[H])cc1 c1(N2C[C@H](CNC(C)=O)OC2=O)cc(F)c([C@]2([C@@]3([H])[C@@]2(C[S@@](C3)=O)[H])[H])cc1
1541 C(C(C([H])([H])[H])(C([H])([H])[H])N(C([C@@]1(C([H])([H])N(C(c2c([H])c([H])c([H])[n]c2[H])([H])[H])C([H])([H])C([H])([H])N1C([C@](C([C@](C(c1c([H])c([H])c([H])c([H])c1[H])([H])[H])(C(N([C@]1(c2c(c(c(c([H])c2C([H])([H])[C@]1(OC(C(C(C(=O)OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])=O)[H])[H])[H])[H])[H])[H])=O)[H])([H])[H])(O[H])[H])([H])[H])[H])=O)[H])([H])([H])[H] C(C(C([H])([H])[H])(C([H])([H])[H])N(C([C@@]1(C([H])([H])N(C(c2c([H])c([H])c([H])[n]c2[H])([H])[H])C([H])([H])C([H])([H])N1C([C@](C([C@](C(c1c([H])c([H])c([H])c([H])c1[H])([H])[H])(C(N([C@]1(c2c(c(c(c([H])c2C([H])([H])[C@]1(OC(C(C(C(=O)OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])=O)[H])[H])[H])[H])[H])[H])=O)[H])([H])[H])(O[H])[H])([H])[H])[H])=O)[H])([H])([H])[H]
1670 N1(CC(=O)OCC=CC1)CP(O)(O)=O N1(CC(=O)OCC=CC1)CP(O)(O)=O
- 1766 C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r| C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r|
+ 1766 C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r| C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r|
1807 C(C(C(C(C(C(C(C(C(C(C(C(O[H])(C(C(=O)N(C1(C(OP(=O)(O[H])O[H])([H])OC(C(OC2(C(N(C(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(OC(=O)C(C(C(C(C(C(C(/C(=C(/C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])\[H])/[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])[H])([H])C(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])([H])C(OP(O[H])(O[H])=O)([H])C(C(OC3(C([H])([H])C(OC4(OC(C(O[H])(C(O[H])([H])[H])[H])([H])C(O[H])([H])C(O[H])([H])C4([H])[H])C(O[H])=O)([H])C(O[H])([H])C(C(O[H])(C(O[H])([H])[H])[H])([H])O3)C(O[H])=O)([H])[H])([H])O2)[H])([H])[H])([H])C(O[H])([H])C1(OC(=O)C(C(O[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])[H])[H])[H])([H])[H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])([H])[H] C(C(C(C(C(C(C(C(C(C(C(C(O[H])(C(C(=O)N(C1(C(OP(=O)(O[H])O[H])([H])OC(C(OC2(C(N(C(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(OC(=O)C(C(C(C(C(C(C(/C(=C(/C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])\[H])/[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])[H])([H])C(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])([H])C(OP(O[H])(O[H])=O)([H])C(C(OC3(C([H])([H])C(OC4(OC(C(O[H])(C(O[H])([H])[H])[H])([H])C(O[H])([H])C(O[H])([H])C4([H])[H])C(O[H])=O)([H])C(O[H])([H])C(C(O[H])(C(O[H])([H])[H])[H])([H])O3)C(O[H])=O)([H])[H])([H])O2)[H])([H])[H])([H])C(O[H])([H])C1(OC(=O)C(C(O[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])[H])[H])[H])([H])[H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])([H])[H]
1962 CN1CCCOCC1 CN1CCCOCC1
1971 [C@]1(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](O[H])([H])C(O[C@]2(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](O[H])([H])C(O[H])([H])C2([H])[H])C(=O)O[H])([H])C1([H])[H])(OC1([C@@](O[C@@]2(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](OP(OP(=O)(OC(C(N([H])[H])([H])[H])([H])[H])O[H])(=O)O[H])([H])C(O[C@]3(OC(C(C(O[C@@]4([C@@](O[H])([H])C(O[H])([H])[C@](C(O[H])(C(O[H])([H])[H])[H])(O[H])C([H])([H])O4)[H])([H])[H])(O[H])[H])([H])[C@](OP(=O)(O[H])O[H])([H])C(O[C@]4(C(O[H])([H])C(O[C@]5(C(O[C@]6(C(O[C@@]7([C@](N(C(=O)C([H])([H])[H])[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O7)[H])([H])C(O[H])([H])[C@@](O[C@]7(C(O[H])([H])C(OC8([C@](O[H])([H])C(O[H])([H])C(O[C@]9(C(O[C@]%10(C(O[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O%10)[H])([H])C(O[C@@]%10(OC(C([H])([H])[H])([H])[C@](O[H])([H])C([H])([H])C%10(O[H])[H])[H])([H])[C@@](O[H])([H])C(C(O[H])([H])[H])([H])O9)[H])([H])[C@@](C([H])([H])[H])([H])O8)[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O7)[H])([H])C(C(O[H])([H])[H])([H])O6)[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O5)[H])([H])[C@@](O[H])([H])C(C(O[C@]5(C(O[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O5)[H])([H])[H])([H])O4)[H])([H])[C@]3(O[H])[H])[H])([H])[C@]2(O[H])[H])[H])([H])C(C(O[H])(C(O[H])([H])[H])[H])([H])O[C@](C(=O)O[H])(OC(C2([C@@](OP(=O)(O[H])O[H])([H])C(OC(C(C(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)([H])[C@@](N(C(C(C(OC(=O)C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)[H])([H])[C@@](OC(C3(O[C@](C(P(=O)(O[H])O[H])([H])[H])([H])C(C(C(C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[C@](OC(C(C(O[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)([H])[C@]3(O[H])[H])[H])([H])[H])([H])O2)[H])([H])[H])C1([H])[H])[H])C(=O)O[H] [C@]1(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](O[H])([H])C(O[C@]2(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](O[H])([H])C(O[H])([H])C2([H])[H])C(=O)O[H])([H])C1([H])[H])(OC1([C@@](O[C@@]2(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](OP(OP(=O)(OC(C(N([H])[H])([H])[H])([H])[H])O[H])(=O)O[H])([H])C(O[C@]3(OC(C(C(O[C@@]4([C@@](O[H])([H])C(O[H])([H])[C@](C(O[H])(C(O[H])([H])[H])[H])(O[H])C([H])([H])O4)[H])([H])[H])(O[H])[H])([H])[C@](OP(=O)(O[H])O[H])([H])C(O[C@]4(C(O[H])([H])C(O[C@]5(C(O[C@]6(C(O[C@@]7([C@](N(C(=O)C([H])([H])[H])[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O7)[H])([H])C(O[H])([H])[C@@](O[C@]7(C(O[H])([H])C(OC8([C@](O[H])([H])C(O[H])([H])C(O[C@]9(C(O[C@]%10(C(O[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O%10)[H])([H])C(O[C@@]%10(OC(C([H])([H])[H])([H])[C@](O[H])([H])C([H])([H])C%10(O[H])[H])[H])([H])[C@@](O[H])([H])C(C(O[H])([H])[H])([H])O9)[H])([H])[C@@](C([H])([H])[H])([H])O8)[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O7)[H])([H])C(C(O[H])([H])[H])([H])O6)[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O5)[H])([H])[C@@](O[H])([H])C(C(O[C@]5(C(O[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O5)[H])([H])[H])([H])O4)[H])([H])[C@]3(O[H])[H])[H])([H])[C@]2(O[H])[H])[H])([H])C(C(O[H])(C(O[H])([H])[H])[H])([H])O[C@](C(=O)O[H])(OC(C2([C@@](OP(=O)(O[H])O[H])([H])C(OC(C(C(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)([H])[C@@](N(C(C(C(OC(=O)C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)[H])([H])[C@@](OC(C3(O[C@](C(P(=O)(O[H])O[H])([H])[H])([H])C(C(C(C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[C@](OC(C(C(O[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)([H])[C@]3(O[H])[H])[H])([H])[H])([H])O2)[H])([H])[H])C1([H])[H])[H])C(=O)O[H]
@@ -2251,7 +2251,7 @@ Finished indexing 2026 structures. 304 wrong structures excluded
1691 C(C1C2C(C(C(C(N([H])[H])=O)([H])[H])([H])[H])(C(C([H])([H])[H])(C([H])([H])[H])C(N=2)=C([H])C2C(C(C(C(N([H])[H])=O)([H])[H])([H])[H])(C(C([H])([H])[H])(C(C(N([H])[H])=O)([H])[H])C(N=2)=C(C([H])([H])[H])C2C(C(C(C(N([H])[H])=O)([H])[H])([H])[H])(C(C([H])([H])[H])(C(C(N([H])[H])=O)([H])[H])C(C([H])([H])[H])(N=2)C2(C(C(C(N([H])[H])=O)([H])[H])(C(C([H])([H])[H])(C(C(C(N(C(C(C([H])([H])[H])(OP([O-])(=O)OC3(C(C(O[H])([H])[H])([H])OC([n]4c([H])[n]c5[n]c([n]c(N([H])[H])c45)S(C([H])([H])[H])(=O)=O)([H])C3(O[H])[H])[H])[H])([H])[H])[H])=O)([H])[H])([H])[H])C=1[N-]2)[H])[H])[H])[H])[H])([H])([H])[H].[C-]#N.[Co+3] |c:26,57,174| C(C1C2C(C(C(C(N([H])[H])=O)([H])[H])([H])[H])(C(C([H])([H])[H])(C([H])([H])[H])C(N=2)=C([H])C2C(C(C(C(N([H])[H])=O)([H])[H])([H])[H])(C(C([H])([H])[H])(C(C(N([H])[H])=O)([H])[H])C(N=2)=C(C([H])([H])[H])C2C(C(C(C(N([H])[H])=O)([H])[H])([H])[H])(C(C([H])([H])[H])(C(C(N([H])[H])=O)([H])[H])C(C([H])([H])[H])(N=2)C2(C(C(C(N([H])[H])=O)([H])[H])(C(C([H])([H])[H])(C(C(C(N(C(C(C([H])([H])[H])(OP([O-])(=O)OC3(C(C(O[H])([H])[H])([H])OC([n]4c([H])[n]c5[n]c([n]c(N([H])[H])c45)S(C([H])([H])[H])(=O)=O)([H])C3(O[H])[H])[H])[H])([H])[H])[H])=O)([H])[H])([H])[H])C=1[N-]2)[H])[H])[H])[H])[H])([H])([H])[H].[C-]#N.[Co+3] |c:26,57,174|
1722 C(C(O/C(=C(/C(=O)N([H])C([H])(C(S[H])([H])[H])C(=O)O[H])\[N+]#N)/O[H])([H])[H])([H])([H])[H] C(C(O/C(=C(/C(=O)N([H])C([H])(C(S[H])([H])[H])C(=O)O[H])\[N+]#N)/O[H])([H])[H])([H])([H])[H]
1748 C1(C)CCC(C)[N+]1(CC)CCCCCCCCCCCC.C(C)OS(=O)(=O)[O-] C1(C)CCC(C)[N+]1(CC)CCCCCCCCCCCC.C(C)OS(=O)(=O)[O-]
- 1766 C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r| C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r|
+ 1766 C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r| C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r|
1807 C(C(C(C(C(C(C(C(C(C(C(C(O[H])(C(C(=O)N(C1(C(OP(=O)(O[H])O[H])([H])OC(C(OC2(C(N(C(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(OC(=O)C(C(C(C(C(C(C(/C(=C(/C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])\[H])/[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])[H])([H])C(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])([H])C(OP(O[H])(O[H])=O)([H])C(C(OC3(C([H])([H])C(OC4(OC(C(O[H])(C(O[H])([H])[H])[H])([H])C(O[H])([H])C(O[H])([H])C4([H])[H])C(O[H])=O)([H])C(O[H])([H])C(C(O[H])(C(O[H])([H])[H])[H])([H])O3)C(O[H])=O)([H])[H])([H])O2)[H])([H])[H])([H])C(O[H])([H])C1(OC(=O)C(C(O[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])[H])[H])[H])([H])[H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])([H])[H] C(C(C(C(C(C(C(C(C(C(C(C(O[H])(C(C(=O)N(C1(C(OP(=O)(O[H])O[H])([H])OC(C(OC2(C(N(C(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(OC(=O)C(C(C(C(C(C(C(/C(=C(/C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])\[H])/[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])[H])([H])C(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])([H])C(OP(O[H])(O[H])=O)([H])C(C(OC3(C([H])([H])C(OC4(OC(C(O[H])(C(O[H])([H])[H])[H])([H])C(O[H])([H])C(O[H])([H])C4([H])[H])C(O[H])=O)([H])C(O[H])([H])C(C(O[H])(C(O[H])([H])[H])[H])([H])O3)C(O[H])=O)([H])[H])([H])O2)[H])([H])[H])([H])C(O[H])([H])C1(OC(=O)C(C(O[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])[H])[H])[H])([H])[H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])([H])[H]
1829 CNC(C1CCS(=O)(=O)N1CC)=O CNC(C1CCS(=O)(=O)N1CC)=O
1841 CC1(C)C(=O)NC(C)(C)C(=O)N1[2H] CC1(C)C(=O)NC(C)(C)C(=O)N1[2H]
@@ -2318,7 +2318,7 @@ Finished indexing 2026 structures. 304 wrong structures excluded
1541 C(C(C([H])([H])[H])(C([H])([H])[H])N(C([C@@]1(C([H])([H])N(C(c2c([H])c([H])c([H])[n]c2[H])([H])[H])C([H])([H])C([H])([H])N1C([C@](C([C@](C(c1c([H])c([H])c([H])c([H])c1[H])([H])[H])(C(N([C@]1(c2c(c(c(c([H])c2C([H])([H])[C@]1(OC(C(C(C(=O)OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])=O)[H])[H])[H])[H])[H])[H])=O)[H])([H])[H])(O[H])[H])([H])[H])[H])=O)[H])([H])([H])[H] C(C(C([H])([H])[H])(C([H])([H])[H])N(C([C@@]1(C([H])([H])N(C(c2c([H])c([H])c([H])[n]c2[H])([H])[H])C([H])([H])C([H])([H])N1C([C@](C([C@](C(c1c([H])c([H])c([H])c([H])c1[H])([H])[H])(C(N([C@]1(c2c(c(c(c([H])c2C([H])([H])[C@]1(OC(C(C(C(=O)OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])=O)[H])[H])[H])[H])[H])[H])=O)[H])([H])[H])(O[H])[H])([H])[H])[H])=O)[H])([H])([H])[H]
1578 C1C([S+](C)C)([H])[CH-]1.N#C[C-](C1([H])C([N+](CC)(CC)CC)([H])/C/1=C(\C#N)/C#N)C#N.c1c([P+](Cl)(Cl)Cl)c[cH-]c1.C1C(=P(Cl)(Cl)Cl)C=CC=1.[N+](C)(C)(C)CC(=O)[O-].c1ccccc1[P+](c1ccccc1)(c1ccccc1)[C-2][P+](c1ccccc1)(c1ccccc1)c1ccccc1.C(#C[B-](c1ccccc1)(c1ccccc1)c1ccccc1)[P+](C)(c1ccccc1)c1ccccc1.[n+]1(ccc(CC(O)[O-])cc1)C.c12cc([O-])ccc1ccc(-c1c[s][s+]c1)c2.c1cc([O-])ccc1O[O+].c1cc([O-])ccc1[O+]=O.C(/C)(=C/C[S+](c1cc(C(C)(C)C)c([O-])c(C(C)(C)C)c1)C)\C.c1c([N-]c2[n+](-c3ccccc3)c[n](-c3ccccc3)[n]2)cccc1.c1(ccc(C)cc1)S([N-][n+]1ccccc1)(=O)=O.C1CCC[N+]1=[N-] C1C([S+](C)C)([H])[CH-]1.N#C[C-](C1([H])C([N+](CC)(CC)CC)([H])/C/1=C(\C#N)/C#N)C#N.c1c([P+](Cl)(Cl)Cl)c[cH-]c1.C1C(=P(Cl)(Cl)Cl)C=CC=1.[N+](C)(C)(C)CC(=O)[O-].c1ccccc1[P+](c1ccccc1)(c1ccccc1)[C-2][P+](c1ccccc1)(c1ccccc1)c1ccccc1.C(#C[B-](c1ccccc1)(c1ccccc1)c1ccccc1)[P+](C)(c1ccccc1)c1ccccc1.[n+]1(ccc(CC(O)[O-])cc1)C.c12cc([O-])ccc1ccc(-c1c[s][s+]c1)c2.c1cc([O-])ccc1O[O+].c1cc([O-])ccc1[O+]=O.C(/C)(=C/C[S+](c1cc(C(C)(C)C)c([O-])c(C(C)(C)C)c1)C)\C.c1c([N-]c2[n+](-c3ccccc3)c[n](-c3ccccc3)[n]2)cccc1.c1(ccc(C)cc1)S([N-][n+]1ccccc1)(=O)=O.C1CCC[N+]1=[N-]
1670 N1(CC(=O)OCC=CC1)CP(O)(O)=O N1(CC(=O)OCC=CC1)CP(O)(O)=O
- 1766 C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r| C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r|
+ 1766 C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r| C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r|
1845 Cl([O-])(=[O+][H])(=O)=O.O(C(C([N+]12C([H])([H])C([H])([H])O[Ni+2]341(OC([H])([H])C([H])([H])[N+]3(C(C(O[H])([H])[H])([H])[H])C([H])([H])C([H])([H])O4)OC(C2([H])[H])([H])[H])([H])[H])([H])[H])[H] Cl([O-])(=[O+][H])(=O)=O.O(C(C([N+]12C([H])([H])C([H])([H])O[Ni+2]341(OC([H])([H])C([H])([H])[N+]3(C(C(O[H])([H])[H])([H])[H])C([H])([H])C([H])([H])O4)OC(C2([H])[H])([H])[H])([H])[H])([H])[H])[H]
1861 C/C=C/N1[C-](C2CCCCC2)C(=O)[O+]=C1C C/C=C/N1[C-](C2CCCCC2)C(=O)[O+]=C1C
1962 CN1CCCOCC1 CN1CCCOCC1
@@ -2475,7 +2475,7 @@ Finished indexing 2026 structures. 304 wrong structures excluded
1707 O1[C@H]([C@@H](C)CO)[C@H](O)[C@H]([C@@H](C)CO)OC1 |&1:1,2,6,8,9,r| O1[C@H]([C@@H](C)CO)[C@H](O)[C@H]([C@@H](C)CO)OC1 |&1:1,2,6,8,9,r|
1708 C12OSC3C4(C5OSC6OSC(OS5)C(C(SO3)OS1)(C1SOC3SOC(SO1)C6(C1OSC4OSC(OS1)C23Br)C)Cl)I C12OSC3C4(C5OSC6OSC(OS5)C(C(SO3)OS1)(C1SOC3SOC(SO1)C6(C1OSC4OSC(OS1)C23Br)C)Cl)I
1759 O1[C@H](C(C)CO)[C@H](O)[C@H](C(C)CO)OC1 |&1:1,6,8,r| O1[C@H](C(C)CO)[C@H](O)[C@H](C(C)CO)OC1 |&1:1,6,8,r|
- 1766 C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r| C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r|
+ 1766 C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r| C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r|
1933 C(C(=O)[O-])C(CO)(C(=O)[O-])C(=O)[O-].[Ce+3] C(C(=O)[O-])C(CO)(C(=O)[O-])C(=O)[O-].[Ce+3]
1971 [C@]1(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](O[H])([H])C(O[C@]2(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](O[H])([H])C(O[H])([H])C2([H])[H])C(=O)O[H])([H])C1([H])[H])(OC1([C@@](O[C@@]2(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](OP(OP(=O)(OC(C(N([H])[H])([H])[H])([H])[H])O[H])(=O)O[H])([H])C(O[C@]3(OC(C(C(O[C@@]4([C@@](O[H])([H])C(O[H])([H])[C@](C(O[H])(C(O[H])([H])[H])[H])(O[H])C([H])([H])O4)[H])([H])[H])(O[H])[H])([H])[C@](OP(=O)(O[H])O[H])([H])C(O[C@]4(C(O[H])([H])C(O[C@]5(C(O[C@]6(C(O[C@@]7([C@](N(C(=O)C([H])([H])[H])[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O7)[H])([H])C(O[H])([H])[C@@](O[C@]7(C(O[H])([H])C(OC8([C@](O[H])([H])C(O[H])([H])C(O[C@]9(C(O[C@]%10(C(O[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O%10)[H])([H])C(O[C@@]%10(OC(C([H])([H])[H])([H])[C@](O[H])([H])C([H])([H])C%10(O[H])[H])[H])([H])[C@@](O[H])([H])C(C(O[H])([H])[H])([H])O9)[H])([H])[C@@](C([H])([H])[H])([H])O8)[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O7)[H])([H])C(C(O[H])([H])[H])([H])O6)[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O5)[H])([H])[C@@](O[H])([H])C(C(O[C@]5(C(O[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O5)[H])([H])[H])([H])O4)[H])([H])[C@]3(O[H])[H])[H])([H])[C@]2(O[H])[H])[H])([H])C(C(O[H])(C(O[H])([H])[H])[H])([H])O[C@](C(=O)O[H])(OC(C2([C@@](OP(=O)(O[H])O[H])([H])C(OC(C(C(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)([H])[C@@](N(C(C(C(OC(=O)C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)[H])([H])[C@@](OC(C3(O[C@](C(P(=O)(O[H])O[H])([H])[H])([H])C(C(C(C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[C@](OC(C(C(O[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)([H])[C@]3(O[H])[H])[H])([H])[H])([H])O2)[H])([H])[H])C1([H])[H])[H])C(=O)O[H] [C@]1(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](O[H])([H])C(O[C@]2(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](O[H])([H])C(O[H])([H])C2([H])[H])C(=O)O[H])([H])C1([H])[H])(OC1([C@@](O[C@@]2(OC(C(O[H])(C(O[H])([H])[H])[H])([H])[C@](OP(OP(=O)(OC(C(N([H])[H])([H])[H])([H])[H])O[H])(=O)O[H])([H])C(O[C@]3(OC(C(C(O[C@@]4([C@@](O[H])([H])C(O[H])([H])[C@](C(O[H])(C(O[H])([H])[H])[H])(O[H])C([H])([H])O4)[H])([H])[H])(O[H])[H])([H])[C@](OP(=O)(O[H])O[H])([H])C(O[C@]4(C(O[H])([H])C(O[C@]5(C(O[C@]6(C(O[C@@]7([C@](N(C(=O)C([H])([H])[H])[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O7)[H])([H])C(O[H])([H])[C@@](O[C@]7(C(O[H])([H])C(OC8([C@](O[H])([H])C(O[H])([H])C(O[C@]9(C(O[C@]%10(C(O[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O%10)[H])([H])C(O[C@@]%10(OC(C([H])([H])[H])([H])[C@](O[H])([H])C([H])([H])C%10(O[H])[H])[H])([H])[C@@](O[H])([H])C(C(O[H])([H])[H])([H])O9)[H])([H])[C@@](C([H])([H])[H])([H])O8)[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O7)[H])([H])C(C(O[H])([H])[H])([H])O6)[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O5)[H])([H])[C@@](O[H])([H])C(C(O[C@]5(C(O[H])([H])C(O[H])([H])[C@](O[H])([H])C(C(O[H])([H])[H])([H])O5)[H])([H])[H])([H])O4)[H])([H])[C@]3(O[H])[H])[H])([H])[C@]2(O[H])[H])[H])([H])C(C(O[H])(C(O[H])([H])[H])[H])([H])O[C@](C(=O)O[H])(OC(C2([C@@](OP(=O)(O[H])O[H])([H])C(OC(C(C(OC(=O)C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)([H])[C@@](N(C(C(C(OC(=O)C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)[H])([H])[C@@](OC(C3(O[C@](C(P(=O)(O[H])O[H])([H])[H])([H])C(C(C(C(C(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[C@](OC(C(C(O[H])(C(C(C(C(C(C(C(C(C(C(C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])([H])[H])=O)([H])[C@]3(O[H])[H])[H])([H])[H])([H])O2)[H])([H])[H])C1([H])[H])[H])C(=O)O[H]
** searchSim(C(CO)(CO)C, 0.9, 1, tanimoto) **
@@ -2795,7 +2795,7 @@ Finished indexing 2026 structures. 304 wrong structures excluded
1558 [H]C1([H])[C@]2(C([H])([H])[C@@]([H])([C@@]([H])(C(=O)OC([H])([H])[H])[C@@](N2C([H])([H])[H])([H])C1([H])[H])OC(c1c([H])c([H])c([H])c([H])c1[H])=O)[H].[H]C1([H])[C@]2(C([H])([H])[C@@]([H])([C@@]([H])(C(=O)OC([H])([H])[H])[C@@](N2C([H])([H])[H])([H])C1([H])[H])OC(c1c([H])c([H])c([H])c([H])c1[H])=O)[H] [H]C1([H])[C@]2(C([H])([H])[C@@]([H])([C@@]([H])(C(=O)OC([H])([H])[H])[C@@](N2C([H])([H])[H])([H])C1([H])[H])OC(c1c([H])c([H])c([H])c([H])c1[H])=O)[H].[H]C1([H])[C@]2(C([H])([H])[C@@]([H])([C@@]([H])(C(=O)OC([H])([H])[H])[C@@](N2C([H])([H])[H])([H])C1([H])[H])OC(c1c([H])c([H])c([H])c([H])c1[H])=O)[H]
1578 C1C([S+](C)C)([H])[CH-]1.N#C[C-](C1([H])C([N+](CC)(CC)CC)([H])/C/1=C(\C#N)/C#N)C#N.c1c([P+](Cl)(Cl)Cl)c[cH-]c1.C1C(=P(Cl)(Cl)Cl)C=CC=1.[N+](C)(C)(C)CC(=O)[O-].c1ccccc1[P+](c1ccccc1)(c1ccccc1)[C-2][P+](c1ccccc1)(c1ccccc1)c1ccccc1.C(#C[B-](c1ccccc1)(c1ccccc1)c1ccccc1)[P+](C)(c1ccccc1)c1ccccc1.[n+]1(ccc(CC(O)[O-])cc1)C.c12cc([O-])ccc1ccc(-c1c[s][s+]c1)c2.c1cc([O-])ccc1O[O+].c1cc([O-])ccc1[O+]=O.C(/C)(=C/C[S+](c1cc(C(C)(C)C)c([O-])c(C(C)(C)C)c1)C)\C.c1c([N-]c2[n+](-c3ccccc3)c[n](-c3ccccc3)[n]2)cccc1.c1(ccc(C)cc1)S([N-][n+]1ccccc1)(=O)=O.C1CCC[N+]1=[N-] C1C([S+](C)C)([H])[CH-]1.N#C[C-](C1([H])C([N+](CC)(CC)CC)([H])/C/1=C(\C#N)/C#N)C#N.c1c([P+](Cl)(Cl)Cl)c[cH-]c1.C1C(=P(Cl)(Cl)Cl)C=CC=1.[N+](C)(C)(C)CC(=O)[O-].c1ccccc1[P+](c1ccccc1)(c1ccccc1)[C-2][P+](c1ccccc1)(c1ccccc1)c1ccccc1.C(#C[B-](c1ccccc1)(c1ccccc1)c1ccccc1)[P+](C)(c1ccccc1)c1ccccc1.[n+]1(ccc(CC(O)[O-])cc1)C.c12cc([O-])ccc1ccc(-c1c[s][s+]c1)c2.c1cc([O-])ccc1O[O+].c1cc([O-])ccc1[O+]=O.C(/C)(=C/C[S+](c1cc(C(C)(C)C)c([O-])c(C(C)(C)C)c1)C)\C.c1c([N-]c2[n+](-c3ccccc3)c[n](-c3ccccc3)[n]2)cccc1.c1(ccc(C)cc1)S([N-][n+]1ccccc1)(=O)=O.C1CCC[N+]1=[N-]
1748 C1(C)CCC(C)[N+]1(CC)CCCCCCCCCCCC.C(C)OS(=O)(=O)[O-] C1(C)CCC(C)[N+]1(CC)CCCCCCCCCCCC.C(C)OS(=O)(=O)[O-]
- 1766 C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r| C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r|
+ 1766 C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r| C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r|
1861 C/C=C/N1[C-](C2CCCCC2)C(=O)[O+]=C1C C/C=C/N1[C-](C2CCCCC2)C(=O)[O+]=C1C
1941 N1(C(C)=C(C)N(C(C)C)[C]1)C(C)C |^3:9| N1(C(C)=C(C)N(C(C)C)[C]1)C(C)C |^3:9|
1981 O=C1N2[C@](CCC2)([H])C(=O)N([H])CC(=O)N([H])[C@](C(N([C@](C(N([C@]2([C@](C)([H])SC[C@@](C(=O)N([C@](C(N([C@](C(N([C@](C(N([C@@]3([C@@](C)([H])SC[C@]4(C(=O)N([C@](Cc5[n]c[n]([H])c5)(C(=O)N([C@@](C(N([C@](C(N([C@](C(N([C@@](Cc5c[n]([H])c[n]5)(C(N([C@](C(=O)N(C(C(N([C@@](CCCCN([H])[H])(C(=O)O[H])[H])[H])=O)=C)[H])(C(C)C)[H])[H])=O)[H])[H])=O)([C@@](CC)(C)[H])[H])[H])=O)(CO[H])[H])[H])=O)(CS[C@@](C)([H])[C@@](C(N4[H])=O)([H])N([H])C(=O)[C@@](C)([H])N([H])C3=O)[H])[H])[H])[H])[H])[H])[H])=O)(CCCCN([H])[H])[H])[H])=O)(CCSC)[H])[H])=O)(CC(N([H])[H])=O)[H])[H])([H])N([H])C(=O)CN([H])C(=O)[C@](CCSC)([H])N([H])C(=O)[C@](CC(C)C)([H])N([H])C(=O)[C@](C)([H])N([H])C(=O)CN([H])C2=O)[H])[H])=O)(CCCCN([H])[H])[H])[H])=O)([H])CS[C@@](C)([H])[C@@]1(N(C(=O)[C@@]1(N([H])C(=O)[C@](CC(C)C)([H])N([H])C(=O)C(=C)N([H])C(=O)[C@@]([C@@](CC)(C)[H])([H])N([H])C(=O)[C@](N(C(=O)/C(/N(C([C@]([C@](CC)(C)[H])(N([H])[H])[H])=O)[H])=C(/C)\[H])[H])([H])CSC1)[H])[H])[H] O=C1N2[C@](CCC2)([H])C(=O)N([H])CC(=O)N([H])[C@](C(N([C@](C(N([C@]2([C@](C)([H])SC[C@@](C(=O)N([C@](C(N([C@](C(N([C@](C(N([C@@]3([C@@](C)([H])SC[C@]4(C(=O)N([C@](Cc5[n]c[n]([H])c5)(C(=O)N([C@@](C(N([C@](C(N([C@](C(N([C@@](Cc5c[n]([H])c[n]5)(C(N([C@](C(=O)N(C(C(N([C@@](CCCCN([H])[H])(C(=O)O[H])[H])[H])=O)=C)[H])(C(C)C)[H])[H])=O)[H])[H])=O)([C@@](CC)(C)[H])[H])[H])=O)(CO[H])[H])[H])=O)(CS[C@@](C)([H])[C@@](C(N4[H])=O)([H])N([H])C(=O)[C@@](C)([H])N([H])C3=O)[H])[H])[H])[H])[H])[H])[H])=O)(CCCCN([H])[H])[H])[H])=O)(CCSC)[H])[H])=O)(CC(N([H])[H])=O)[H])[H])([H])N([H])C(=O)CN([H])C(=O)[C@](CCSC)([H])N([H])C(=O)[C@](CC(C)C)([H])N([H])C(=O)[C@](C)([H])N([H])C(=O)CN([H])C2=O)[H])[H])=O)(CCCCN([H])[H])[H])[H])=O)([H])CS[C@@](C)([H])[C@@]1(N(C(=O)[C@@]1(N([H])C(=O)[C@](CC(C)C)([H])N([H])C(=O)C(=C)N([H])C(=O)[C@@]([C@@](CC)(C)[H])([H])N([H])C(=O)[C@](N(C(=O)/C(/N(C([C@]([C@](CC)(C)[H])(N([H])[H])[H])=O)[H])=C(/C)\[H])[H])([H])CSC1)[H])[H])[H]
@@ -5151,7 +5151,7 @@ Finished indexing 2026 structures. 304 wrong structures excluded
1541 C(C(C([H])([H])[H])(C([H])([H])[H])N(C([C@@]1(C([H])([H])N(C(c2c([H])c([H])c([H])[n]c2[H])([H])[H])C([H])([H])C([H])([H])N1C([C@](C([C@](C(c1c([H])c([H])c([H])c([H])c1[H])([H])[H])(C(N([C@]1(c2c(c(c(c([H])c2C([H])([H])[C@]1(OC(C(C(C(=O)OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])=O)[H])[H])[H])[H])[H])[H])=O)[H])([H])[H])(O[H])[H])([H])[H])[H])=O)[H])([H])([H])[H] C(C(C([H])([H])[H])(C([H])([H])[H])N(C([C@@]1(C([H])([H])N(C(c2c([H])c([H])c([H])[n]c2[H])([H])[H])C([H])([H])C([H])([H])N1C([C@](C([C@](C(c1c([H])c([H])c([H])c([H])c1[H])([H])[H])(C(N([C@]1(c2c(c(c(c([H])c2C([H])([H])[C@]1(OC(C(C(C(=O)OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC(C(OC([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])=O)[H])[H])[H])[H])[H])[H])=O)[H])([H])[H])(O[H])[H])([H])[H])[H])=O)[H])([H])([H])[H]
1578 C1C([S+](C)C)([H])[CH-]1.N#C[C-](C1([H])C([N+](CC)(CC)CC)([H])/C/1=C(\C#N)/C#N)C#N.c1c([P+](Cl)(Cl)Cl)c[cH-]c1.C1C(=P(Cl)(Cl)Cl)C=CC=1.[N+](C)(C)(C)CC(=O)[O-].c1ccccc1[P+](c1ccccc1)(c1ccccc1)[C-2][P+](c1ccccc1)(c1ccccc1)c1ccccc1.C(#C[B-](c1ccccc1)(c1ccccc1)c1ccccc1)[P+](C)(c1ccccc1)c1ccccc1.[n+]1(ccc(CC(O)[O-])cc1)C.c12cc([O-])ccc1ccc(-c1c[s][s+]c1)c2.c1cc([O-])ccc1O[O+].c1cc([O-])ccc1[O+]=O.C(/C)(=C/C[S+](c1cc(C(C)(C)C)c([O-])c(C(C)(C)C)c1)C)\C.c1c([N-]c2[n+](-c3ccccc3)c[n](-c3ccccc3)[n]2)cccc1.c1(ccc(C)cc1)S([N-][n+]1ccccc1)(=O)=O.C1CCC[N+]1=[N-] C1C([S+](C)C)([H])[CH-]1.N#C[C-](C1([H])C([N+](CC)(CC)CC)([H])/C/1=C(\C#N)/C#N)C#N.c1c([P+](Cl)(Cl)Cl)c[cH-]c1.C1C(=P(Cl)(Cl)Cl)C=CC=1.[N+](C)(C)(C)CC(=O)[O-].c1ccccc1[P+](c1ccccc1)(c1ccccc1)[C-2][P+](c1ccccc1)(c1ccccc1)c1ccccc1.C(#C[B-](c1ccccc1)(c1ccccc1)c1ccccc1)[P+](C)(c1ccccc1)c1ccccc1.[n+]1(ccc(CC(O)[O-])cc1)C.c12cc([O-])ccc1ccc(-c1c[s][s+]c1)c2.c1cc([O-])ccc1O[O+].c1cc([O-])ccc1[O+]=O.C(/C)(=C/C[S+](c1cc(C(C)(C)C)c([O-])c(C(C)(C)C)c1)C)\C.c1c([N-]c2[n+](-c3ccccc3)c[n](-c3ccccc3)[n]2)cccc1.c1(ccc(C)cc1)S([N-][n+]1ccccc1)(=O)=O.C1CCC[N+]1=[N-]
1748 C1(C)CCC(C)[N+]1(CC)CCCCCCCCCCCC.C(C)OS(=O)(=O)[O-] C1(C)CCC(C)[N+]1(CC)CCCCCCCCCCCC.C(C)OS(=O)(=O)[O-]
- 1766 C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r| C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r|
+ 1766 C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r| C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r|
1981 O=C1N2[C@](CCC2)([H])C(=O)N([H])CC(=O)N([H])[C@](C(N([C@](C(N([C@]2([C@](C)([H])SC[C@@](C(=O)N([C@](C(N([C@](C(N([C@](C(N([C@@]3([C@@](C)([H])SC[C@]4(C(=O)N([C@](Cc5[n]c[n]([H])c5)(C(=O)N([C@@](C(N([C@](C(N([C@](C(N([C@@](Cc5c[n]([H])c[n]5)(C(N([C@](C(=O)N(C(C(N([C@@](CCCCN([H])[H])(C(=O)O[H])[H])[H])=O)=C)[H])(C(C)C)[H])[H])=O)[H])[H])=O)([C@@](CC)(C)[H])[H])[H])=O)(CO[H])[H])[H])=O)(CS[C@@](C)([H])[C@@](C(N4[H])=O)([H])N([H])C(=O)[C@@](C)([H])N([H])C3=O)[H])[H])[H])[H])[H])[H])[H])=O)(CCCCN([H])[H])[H])[H])=O)(CCSC)[H])[H])=O)(CC(N([H])[H])=O)[H])[H])([H])N([H])C(=O)CN([H])C(=O)[C@](CCSC)([H])N([H])C(=O)[C@](CC(C)C)([H])N([H])C(=O)[C@](C)([H])N([H])C(=O)CN([H])C2=O)[H])[H])=O)(CCCCN([H])[H])[H])[H])=O)([H])CS[C@@](C)([H])[C@@]1(N(C(=O)[C@@]1(N([H])C(=O)[C@](CC(C)C)([H])N([H])C(=O)C(=C)N([H])C(=O)[C@@]([C@@](CC)(C)[H])([H])N([H])C(=O)[C@](N(C(=O)/C(/N(C([C@]([C@](CC)(C)[H])(N([H])[H])[H])=O)[H])=C(/C)\[H])[H])([H])CSC1)[H])[H])[H] O=C1N2[C@](CCC2)([H])C(=O)N([H])CC(=O)N([H])[C@](C(N([C@](C(N([C@]2([C@](C)([H])SC[C@@](C(=O)N([C@](C(N([C@](C(N([C@](C(N([C@@]3([C@@](C)([H])SC[C@]4(C(=O)N([C@](Cc5[n]c[n]([H])c5)(C(=O)N([C@@](C(N([C@](C(N([C@](C(N([C@@](Cc5c[n]([H])c[n]5)(C(N([C@](C(=O)N(C(C(N([C@@](CCCCN([H])[H])(C(=O)O[H])[H])[H])=O)=C)[H])(C(C)C)[H])[H])=O)[H])[H])=O)([C@@](CC)(C)[H])[H])[H])=O)(CO[H])[H])[H])=O)(CS[C@@](C)([H])[C@@](C(N4[H])=O)([H])N([H])C(=O)[C@@](C)([H])N([H])C3=O)[H])[H])[H])[H])[H])[H])[H])=O)(CCCCN([H])[H])[H])[H])=O)(CCSC)[H])[H])=O)(CC(N([H])[H])=O)[H])[H])([H])N([H])C(=O)CN([H])C(=O)[C@](CCSC)([H])N([H])C(=O)[C@](CC(C)C)([H])N([H])C(=O)[C@](C)([H])N([H])C(=O)CN([H])C2=O)[H])[H])=O)(CCCCN([H])[H])[H])[H])=O)([H])CS[C@@](C)([H])[C@@]1(N(C(=O)[C@@]1(N([H])C(=O)[C@](CC(C)C)([H])N([H])C(=O)C(=C)N([H])C(=O)[C@@]([C@@](CC)(C)[H])([H])N([H])C(=O)[C@](N(C(=O)/C(/N(C([C@]([C@](CC)(C)[H])(N([H])[H])[H])=O)[H])=C(/C)\[H])[H])([H])CSC1)[H])[H])[H]
** searchSim(N(CC)(CC)C(C)C, 0.9, 1, tanimoto) **
107 C[N+]([C-](C)C)(C)C C[N+]([C-](C)C)(C)C
@@ -5629,7 +5629,7 @@ Finished indexing 2026 structures. 304 wrong structures excluded
1592 c1(c([H])c([H])c(C(C(N(/N=C(\c2c([O-])[n]c3c(c(c(c([H])c3[n]2)[H])[N+](O[H])=O)[H])/C(c2c([H])c([H])c(C(/C(=C3/C(=O)N=C4C(=C(C(=C([H])C4=N/3)[H])N(O[H])O[H])[H])/N=N/C(C(c3c([H])c([H])c([H])c([H])c3[H])([H])[H])=O)(O[H])[H])c([H])c2[H])(O[H])[H])[H])=O)([H])[H])c([H])c1[H])[H] c1(c([H])c([H])c(C(C(N(/N=C(\c2c([O-])[n]c3c(c(c(c([H])c3[n]2)[H])[N+](O[H])=O)[H])/C(c2c([H])c([H])c(C(/C(=C3/C(=O)N=C4C(=C(C(=C([H])C4=N/3)[H])N(O[H])O[H])[H])/N=N/C(C(c3c([H])c([H])c([H])c([H])c3[H])([H])[H])=O)(O[H])[H])c([H])c2[H])(O[H])[H])[H])=O)([H])[H])c([H])c1[H])[H]
1602 c1(cc(C(O[2H])=N)cc(/C(/C)=C(/C)\CC)c1)[C@@]([12CH3])(C)C.c1(cc(C(O[2H])=N)cc(/C(/C)=C(\C)/CC)c1)[C@]([12CH3])(C)C |&1:16,36,r| c1(cc(C(O[2H])=N)cc(/C(/C)=C(/C)\CC)c1)[C@@]([12CH3])(C)C.c1(cc(C(O[2H])=N)cc(/C(/C)=C(\C)/CC)c1)[C@]([12CH3])(C)C |&1:16,36,r|
1646 c1(cc(C(O[2H])=N)cc(/C(/C)=C(/C)\CC)c1)[C@@]([12CH3])(C)C |&1:16,r| c1(cc(C(O[2H])=N)cc(/C(/C)=C(/C)\CC)c1)[C@@]([12CH3])(C)C |&1:16,r|
- 1766 C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r| C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r|
+ 1766 C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r| C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r|
1855 c1(-c2[n][nH]c3c2cccc3)[n]c2ccc(C(=O)OC)cc2[nH]1 c1(-c2[n][nH]c3c2cccc3)[n]c2ccc(C(=O)OC)cc2[nH]1
1862 c12[n](CCCCCc3c(-c4[n][n][n][n-]4)cc(C)[n]3C)c(OCC)[n]c1cccc2C(NC)=O.c12[n+](CCCCCc3c(-c4[n][n-][n][n]4)cc(C)[n]3C)c(OCC)[nH]c1cccc2/C(=N/C)/[O-].c12[n](CCCCCc3c(-c4[n][n][n][n-]4)cc(C)[n]3C)c(OCC)[n]c1cccc2/C(=N/C)/O.c12[n+](CCCCCc3c(-c4[n][nH][n][n]4)cc(C)[n]3C)c(OCC)[nH]c1cccc2/C(=N/C)/O.c12[n+](CCCCCc3c(-c4[n][n-][n][n]4)cc(C)[n]3C)c(OCC)[nH]c1cccc2C([N-]C)=O c12[n](CCCCCc3c(-c4[n][n][n][n-]4)cc(C)[n]3C)c(OCC)[n]c1cccc2C(NC)=O.c12[n+](CCCCCc3c(-c4[n][n-][n][n]4)cc(C)[n]3C)c(OCC)[nH]c1cccc2/C(=N/C)/[O-].c12[n](CCCCCc3c(-c4[n][n][n][n-]4)cc(C)[n]3C)c(OCC)[n]c1cccc2/C(=N/C)/O.c12[n+](CCCCCc3c(-c4[n][nH][n][n]4)cc(C)[n]3C)c(OCC)[nH]c1cccc2/C(=N/C)/O.c12[n+](CCCCCc3c(-c4[n][n-][n][n]4)cc(C)[n]3C)c(OCC)[nH]c1cccc2C([N-]C)=O
1874 c1c(C(=O)O[Na])c(O)ccc1 c1c(C(=O)O[Na])c(O)ccc1
@@ -11432,7 +11432,7 @@ Finished indexing 2026 structures. 304 wrong structures excluded
1429 C(c1c(/C(/c2c([H])c([H])c([H])c([H])c2S([O-])(=O)=O)=C2/C([H])=C(C(C([H])([H])[H])(C([H])([H])[H])[H])C(=O)C(C(N(C(C(O[H])=O)([H])[H])C(C([O-])=O)([H])[H])([H])[H])=C/2C([H])([H])[H])c([H])c(C(C([H])([H])[H])(C([H])([H])[H])[H])c(O[H])c1C(N(C(C([O-])=O)([H])[H])C(C([O-])=O)([H])[H])([H])[H])([H])([H])[H] C(c1c(/C(/c2c([H])c([H])c([H])c([H])c2S([O-])(=O)=O)=C2/C([H])=C(C(C([H])([H])[H])(C([H])([H])[H])[H])C(=O)C(C(N(C(C(O[H])=O)([H])[H])C(C([O-])=O)([H])[H])([H])[H])=C/2C([H])([H])[H])c([H])c(C(C([H])([H])[H])(C([H])([H])[H])[H])c(O[H])c1C(N(C(C([O-])=O)([H])[H])C(C([O-])=O)([H])[H])([H])[H])([H])([H])[H]
1475 c1ccccc1C[N+](C)(C)C.[Br-] c1ccccc1C[N+](C)(C)C.[Br-]
1594 C(C(C([H])([H])[H])(C([H])([H])[H])OC(N(C(C(C(C(C(N1C([H])([H])C([H])([H])C([H])([H])N(C(C(C(C(C(N(C(c2c([H])c([H])c([H])c([H])c2[H])([H])[H])C(=O)OC(C([H])([H])[H])(C([H])([H])[H])C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])C([H])([H])C([H])([H])N(C(C(C(C(C(N(C(c2c([H])c([H])c([H])c([H])c2[H])([H])[H])C(=O)OC(C([H])([H])[H])(C([H])([H])[H])C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])C([H])([H])C([H])([H])C([H])([H])[N+](C(C(C(C(C(N(C(c2c([H])c([H])c([H])c([H])c2[H])([H])[H])C(=O)OC(C([H])([H])[H])(C([H])([H])[H])C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(C(C(C(C(C(N(C(c2c([H])c([H])c([H])c([H])c2[H])([H])[H])C(=O)OC(C([H])([H])[H])(C([H])([H])[H])C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])C([H])([H])C([H])([H])C1([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])C(c1c([H])c([H])c([H])c([H])c1[H])([H])[H])=O)([H])([H])[H] C(C(C([H])([H])[H])(C([H])([H])[H])OC(N(C(C(C(C(C(N1C([H])([H])C([H])([H])C([H])([H])N(C(C(C(C(C(N(C(c2c([H])c([H])c([H])c([H])c2[H])([H])[H])C(=O)OC(C([H])([H])[H])(C([H])([H])[H])C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])C([H])([H])C([H])([H])N(C(C(C(C(C(N(C(c2c([H])c([H])c([H])c([H])c2[H])([H])[H])C(=O)OC(C([H])([H])[H])(C([H])([H])[H])C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])C([H])([H])C([H])([H])C([H])([H])[N+](C(C(C(C(C(N(C(c2c([H])c([H])c([H])c([H])c2[H])([H])[H])C(=O)OC(C([H])([H])[H])(C([H])([H])[H])C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])(C(C(C(C(C(N(C(c2c([H])c([H])c([H])c([H])c2[H])([H])[H])C(=O)OC(C([H])([H])[H])(C([H])([H])[H])C([H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])C([H])([H])C([H])([H])C1([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])C(c1c([H])c([H])c([H])c([H])c1[H])([H])[H])=O)([H])([H])[H]
- 1766 C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r| C(O)[C@]12COC(c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1C(c1ccccc1)OC2.C(O)[C@]12COC(c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,12,24,27,35,46,49,56,68,78,79,r|
+ 1766 C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r| C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)N1[C@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@@H](c1ccccc1)OC2.C(O)[C@]12CO[C@H](c3ccccc3)[N@@]1[C@H](c1ccccc1)OC2 |&1:2,5,12,13,24,27,35,46,49,56,57,68,71,78,79,r|
** searchSim(N(C)(CC1C=CC=CC=1)C, 0.9, 1, tanimoto) **
1475 c1ccccc1C[N+](C)(C)C.[Br-] c1ccccc1C[N+](C)(C)C.[Br-]
** searchSim(N(C)(CC1C=CC=CC=1)C, 0.9, 1, tversky 0.3 0.7) **
diff --git a/api/tests/integration/ref/formats/mol_to_smiles.py.out b/api/tests/integration/ref/formats/mol_to_smiles.py.out
index 900d00b2b0..1bdefd0c40 100644
--- a/api/tests/integration/ref/formats/mol_to_smiles.py.out
+++ b/api/tests/integration/ref/formats/mol_to_smiles.py.out
@@ -1,3 +1,3 @@
C1%82(C%83O%84%85)OC%86(C(O%87%88%89)C(O%90%91)C%921O%93%94%95)O%96%97%98.[*:1]%96.[*:2]%93.[*:3]%84.[*:4]%90.[*:5]%87.[*:6]%94%85.[*:7]%95%97.[*:8]%83.[*:9]%91%88.[*:10]%89%98.[*:11]%86.[*:12]%92.[*:13]%82 |$;;;;;;;;;;;;_R1;_R2;_R3;_R4;_R5;_R6;_R7;_R8;_R9;_R10;_R11;_R12;_R13$|
[O-][N+](C1=NN=NN1CC1N=NNN=1)=O
-C1C(O)=C(C2C=CC(C)=CC=2N)C(C)=CC=1 |o1:3,r,wU:3.12|
+C1C(O)=C(C2C=CC(C)=CC=2N)C(C)=CC=1 |o1:3,r,wU:3.12,(25.51,-10.61,;25.51,-12.12,;24.22,-12.87,;26.82,-12.86,;26.82,-14.36,;25.51,-15.12,;25.52,-16.62,;26.82,-17.36,;26.82,-18.86,;28.12,-16.61,;28.12,-15.11,;29.18,-14.05,;28.11,-12.11,;29.41,-12.86,;28.11,-10.61,;26.82,-9.86,)|
diff --git a/api/tests/integration/ref/formats/serialize_badmols.py.out b/api/tests/integration/ref/formats/serialize_badmols.py.out
index ae892d9358..61136f7275 100644
--- a/api/tests/integration/ref/formats/serialize_badmols.py.out
+++ b/api/tests/integration/ref/formats/serialize_badmols.py.out
@@ -11,7 +11,7 @@ M V30 1 C 0.0884202 2.7107 0.0 0
M V30 2 C 0.8029 2.29818 0.0 0
M V30 3 C 0.8029 1.4732 0.0 0
M V30 4 C 0.0884202 1.06068 0.0 0
-M V30 5 C -0.626110 1.4732 0.0 0 CFG=3
+M V30 5 C -0.626110 1.4732 0.0 0 CFG=1
M V30 6 C -1.34049 1.06068 0.0 0 CFG=2
M V30 7 C -2.05502 1.4732 0.0 0
M V30 8 C -2.7695 1.06068 0.0 0
@@ -42,7 +42,7 @@ M V30 15 1 5 15
M V30 16 1 1 15 CFG=1
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 6)
+M V30 MDLV30/STERAC1 ATOMS=(2 5 6)
M V30 END COLLECTION
M V30 END CTAB
M END
@@ -59,7 +59,7 @@ M V30 1 C 0.0884202 2.7107 0.0 0
M V30 2 C 0.8029 2.29818 0.0 0
M V30 3 C 0.8029 1.4732 0.0 0
M V30 4 C 0.0884202 1.06068 0.0 0
-M V30 5 C -0.626110 1.4732 0.0 0 CFG=3
+M V30 5 C -0.626110 1.4732 0.0 0 CFG=1
M V30 6 C -1.34049 1.06068 0.0 0 CFG=2
M V30 7 C -2.05502 1.4732 0.0 0
M V30 8 C -2.7695 1.06068 0.0 0
@@ -90,7 +90,7 @@ M V30 15 1 5 15
M V30 16 1 1 15 CFG=1
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 6)
+M V30 MDLV30/STERAC1 ATOMS=(2 5 6)
M V30 MDLV30/HILITE BONDS=(12 1 2 3 4 6 7 8 9 10 11 15 16)
M V30 MDLV30/HILITE ATOMS=(12 1 2 3 4 5 6 7 8 9 10 11 15)
M V30 END COLLECTION
@@ -110,7 +110,7 @@ M V30 1 C 0.0884202 2.7107 0.0 0
M V30 2 C 0.8029 2.29821 0.0 0
M V30 3 C 0.8029 1.47324 0.0 0
M V30 4 C 0.0884202 1.06067 0.0 0
-M V30 5 C -0.626110 1.47324 0.0 0 CFG=3
+M V30 5 C -0.626110 1.47324 0.0 0 CFG=1
M V30 6 C -1.34049 1.06067 0.0 0 CFG=2
M V30 7 C -2.05502 1.47324 0.0 0
M V30 8 C -2.7695 1.06067 0.0 0
@@ -152,7 +152,7 @@ M V30 21 1 5 20
M V30 22 1 1 20 CFG=1
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 6)
+M V30 MDLV30/STERAC1 ATOMS=(2 5 6)
M V30 END COLLECTION
M V30 END CTAB
M END
@@ -169,7 +169,7 @@ M V30 1 C 0.0884202 2.7107 0.0 0
M V30 2 C 0.8029 2.29821 0.0 0
M V30 3 C 0.8029 1.47324 0.0 0
M V30 4 C 0.0884202 1.06067 0.0 0
-M V30 5 C -0.626110 1.47324 0.0 0 CFG=3
+M V30 5 C -0.626110 1.47324 0.0 0 CFG=1
M V30 6 C -1.34049 1.06067 0.0 0 CFG=2
M V30 7 C -2.05502 1.47324 0.0 0
M V30 8 C -2.7695 1.06067 0.0 0
@@ -211,7 +211,7 @@ M V30 21 1 5 20
M V30 22 1 1 20 CFG=1
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 6)
+M V30 MDLV30/STERAC1 ATOMS=(2 5 6)
M V30 MDLV30/HILITE BONDS=(18 1 2 3 4 6 7 8 9 10 11 14 15 16 17 18 19 21 22)
M V30 MDLV30/HILITE ATOMS=(18 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 17 18 20)
M V30 END COLLECTION
diff --git a/api/tests/integration/ref/formats/serialize_badrxns.py.out b/api/tests/integration/ref/formats/serialize_badrxns.py.out
index 5f42e8c406..a276164680 100644
--- a/api/tests/integration/ref/formats/serialize_badrxns.py.out
+++ b/api/tests/integration/ref/formats/serialize_badrxns.py.out
@@ -41,7 +41,7 @@ M V30 COUNTS 15 16 0 0 0
M V30 BEGIN ATOM
M V30 1 C 0.0884 2.7107 0.0 0
M V30 2 C -0.6261 2.2982 0.0 0
-M V30 3 C -0.6261 1.4732 0.0 0 CFG=3
+M V30 3 C -0.6261 1.4732 0.0 0 CFG=1
M V30 4 C 0.0884 1.0607 0.0 0
M V30 5 C 0.8029 1.4732 0.0 0
M V30 6 C 0.8029 2.2982 0.0 0
@@ -74,7 +74,7 @@ M V30 15 2 13 14
M V30 16 1 13 15
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 7)
+M V30 MDLV30/STERAC1 ATOMS=(2 3 7)
M V30 END COLLECTION
M V30 END CTAB
M V30 END PRODUCT
@@ -124,7 +124,7 @@ M V30 1 C 0.0884202 2.7107 0.0 0
M V30 2 C 0.8029 2.29818 0.0 0
M V30 3 C 0.8029 1.4732 0.0 0
M V30 4 C 0.0884202 1.06068 0.0 0
-M V30 5 C -0.626110 1.4732 0.0 0 CFG=3
+M V30 5 C -0.626110 1.4732 0.0 0 CFG=1
M V30 6 C -1.34049 1.06068 0.0 0 CFG=2
M V30 7 C -2.05502 1.4732 0.0 0
M V30 8 C -2.7695 1.06068 0.0 0
@@ -155,7 +155,7 @@ M V30 15 1 5 15
M V30 16 1 1 15 CFG=1
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 6)
+M V30 MDLV30/STERAC1 ATOMS=(2 5 6)
M V30 END COLLECTION
M V30 END CTAB
M V30 END PRODUCT
@@ -205,7 +205,7 @@ M V30 1 C 0.0884202 2.7107 0.0 0
M V30 2 C 0.8029 2.29818 0.0 0
M V30 3 C 0.8029 1.4732 0.0 0
M V30 4 C 0.0884202 1.06068 0.0 0
-M V30 5 C -0.626110 1.4732 0.0 0 CFG=3
+M V30 5 C -0.626110 1.4732 0.0 0 CFG=1
M V30 6 C -1.34049 1.06068 0.0 0 CFG=2
M V30 7 C -2.05502 1.4732 0.0 0
M V30 8 C -2.7695 1.06068 0.0 0
@@ -236,7 +236,7 @@ M V30 15 1 5 15
M V30 16 1 1 15 CFG=1
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 6)
+M V30 MDLV30/STERAC1 ATOMS=(2 5 6)
M V30 MDLV30/HILITE BONDS=(6 1 2 3 4 15 16)
M V30 MDLV30/HILITE ATOMS=(6 1 2 3 4 5 15)
M V30 END COLLECTION
@@ -287,7 +287,7 @@ M V30 COUNTS 20 22 0 0 0
M V30 BEGIN ATOM
M V30 1 C 0.0884 2.7107 0.0 0
M V30 2 C -0.6261 2.2982 0.0 0
-M V30 3 C -0.6261 1.4732 0.0 0 CFG=3
+M V30 3 C -0.6261 1.4732 0.0 0 CFG=1
M V30 4 C 0.0884 1.0607 0.0 0
M V30 5 C 0.8029 1.4732 0.0 0
M V30 6 C 0.8029 2.2982 0.0 0
@@ -331,7 +331,7 @@ M V30 21 4 18 19
M V30 22 4 19 20
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 7)
+M V30 MDLV30/STERAC1 ATOMS=(2 3 7)
M V30 END COLLECTION
M V30 END CTAB
M V30 END PRODUCT
@@ -381,7 +381,7 @@ M V30 1 C 0.0884202 2.7107 0.0 0
M V30 2 C 0.8029 2.29821 0.0 0
M V30 3 C 0.8029 1.47324 0.0 0
M V30 4 C 0.0884202 1.06067 0.0 0
-M V30 5 C -0.626110 1.47324 0.0 0 CFG=3
+M V30 5 C -0.626110 1.47324 0.0 0 CFG=1
M V30 6 C -1.34049 1.06067 0.0 0 CFG=2
M V30 7 C -2.05502 1.47324 0.0 0
M V30 8 C -2.7695 1.06067 0.0 0
@@ -423,7 +423,7 @@ M V30 21 1 5 20
M V30 22 1 1 20 CFG=1
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 6)
+M V30 MDLV30/STERAC1 ATOMS=(2 5 6)
M V30 END COLLECTION
M V30 END CTAB
M V30 END PRODUCT
@@ -473,7 +473,7 @@ M V30 1 C 0.0884202 2.7107 0.0 0
M V30 2 C 0.8029 2.29821 0.0 0
M V30 3 C 0.8029 1.47324 0.0 0
M V30 4 C 0.0884202 1.06067 0.0 0
-M V30 5 C -0.626110 1.47324 0.0 0 CFG=3
+M V30 5 C -0.626110 1.47324 0.0 0 CFG=1
M V30 6 C -1.34049 1.06067 0.0 0 CFG=2
M V30 7 C -2.05502 1.47324 0.0 0
M V30 8 C -2.7695 1.06067 0.0 0
@@ -515,7 +515,7 @@ M V30 21 1 5 20
M V30 22 1 1 20 CFG=1
M V30 END BOND
M V30 BEGIN COLLECTION
-M V30 MDLV30/STERAC1 ATOMS=(1 6)
+M V30 MDLV30/STERAC1 ATOMS=(2 5 6)
M V30 MDLV30/HILITE BONDS=(6 1 2 3 4 21 22)
M V30 MDLV30/HILITE ATOMS=(6 1 2 3 4 5 20)
M V30 END COLLECTION
diff --git a/api/tests/integration/ref/formats/smiles.py.out b/api/tests/integration/ref/formats/smiles.py.out
index 8d8a2820b4..27d92a67c4 100644
--- a/api/tests/integration/ref/formats/smiles.py.out
+++ b/api/tests/integration/ref/formats/smiles.py.out
@@ -74,4 +74,10 @@ CCCCC |Sg:n:1,2,3::hh|
*** Atropisomers ***
atropisomer:
C1=CC=C(C)C(C2=C(N)C=C(C)C=C2)=C1O |o1:5,r,wU:5.4|
-C1=CC=C(C)C(C2=C(N)C=C(C)C=C2)=C1O |o1:5,r,wU:5.4|
+C1=CC=C(C)C(C2=C(N)C=C(C)C=C2)=C1O |o1:5,r,wU:5.4,(2.40,-1.39,;3.20,-0.00,;2.40,1.39,;0.80,1.39,;0.00,2.77,;0.00,0.00,;-1.60,0.00,;-2.40,1.39,;-1.60,2.77,;-4.00,1.39,;-4.80,0.00,;-6.40,0.00,;-4.00,-1.39,;-2.40,-1.39,;0.80,-1.39,;-0.00,-2.77,)|
+atropisomer:
+C1C(O)=C(C2C=CC(C)=CC=2N)C(C)=CC=1 |wU:3.12,wD:3.3|
+C1C(O)=C(C2C=CC(C)=CC=2N)C(C)=CC=1 |wU:3.12,wD:3.3,(-2.40,1.39,;-0.80,1.39,;-0.00,2.77,;0.00,0.00,;1.60,0.00,;2.40,1.39,;4.00,1.39,;4.80,0.00,;6.40,0.00,;4.00,-1.39,;2.40,-1.39,;1.60,-2.77,;-0.80,-1.39,;0.00,-2.77,;-2.40,-1.39,;-3.20,-0.00,)|
+atropisomer:
+C1C(O)=C(C2C=CC(C)=CC=2N)C(C)=CC=1 |w:3.3,3.12|
+C1C(O)=C(C2C=CC(C)=CC=2N)C(C)=CC=1 |w:3.3,3.12,(-2.40,1.39,;-0.80,1.39,;-0.00,2.77,;0.00,0.00,;1.60,0.00,;2.40,1.39,;4.00,1.39,;4.80,0.00,;6.40,0.00,;4.00,-1.39,;2.40,-1.39,;1.60,-2.77,;-0.80,-1.39,;0.00,-2.77,;-2.40,-1.39,;-3.20,-0.00,)|
diff --git a/api/tests/integration/ref/rsmiles/rsmiles2.py.out b/api/tests/integration/ref/rsmiles/rsmiles2.py.out
index 7f6b65fa3d..a41a34b572 100644
--- a/api/tests/integration/ref/rsmiles/rsmiles2.py.out
+++ b/api/tests/integration/ref/rsmiles/rsmiles2.py.out
@@ -866,8 +866,8 @@ CO[CH:10](OC)[O:7][CH3:1].[CH3:2][O:8][C:12](=[O:4])[CH2:6][C:11](=[O:5])[O:9][C
[C:1]1([Si](C)(C)C)([O:21][CH2:3]1)[CH:2](OS(=O)(=O)C)[C:6]1([CH2:13][CH2:15][CH2:19][CH3:20])[O:22][CH2:11]1>>[C:6]1([CH2:13][CH2:15][CH2:19][CH3:20])=[CH:11][O:22][C:1]([CH2:3]F)=[CH:2]1.[C:6]1([CH2:13][CH2:15][CH2:19][CH3:20])=[CH:11][O:22][C:1]([CH2:3][OH:21])=[CH:2]1
[CH3:1][CH2:6][CH2:2][CH2:3][C:10]1([CH2:5][O:8]1)[CH:9](OS(C)(=O)=O)[C:11]1([CH2:4][O:7]1)[Si](C)(C)C>>[CH3:1][CH2:6][CH2:2][CH2:3][C:10]1[CH:9]=[C:11]([CH2:4][OH:7])[O:8][CH:5]=1.[CH3:1][CH2:6][CH2:2][CH2:3][C:10]1[CH:9]=[C:11]([CH2:4]F)[O:8][CH:5]=1 |f:1.2|
*** 289 ***
-[C:1]1([O:48][CH2:4]1)([C@@:3]1([H])[CH2:9][CH2:17][C@@:14]2([H])[C@:24]3([H])[CH2:27][CH:29]=[C:30]4[CH2:33][C@H:35]([CH2:34][CH2:31][C@:28]4([CH3:32])[C@@:26]3([H])[CH2:25][CH2:15][C@:8]12[CH3:16])[O:36][Si](C)(C)C(C)(C)C)[CH:2](OS(=O)(=O)C)[C:6]1([Si](C)(C)C)[O:49][CH2:10]1>>[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10]F)=[CH:2]1.[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10][OH:49])=[CH:2]1 |w:0,34,40,a:3,7,9,15,18,20,24,47,51,53,57,63,65,69,78,82,84,88,94,96,100|
-C[Si](C)(C)[C:24]1([CH2:9][O:16]1)[CH:17](OS(C)(=O)=O)[C:25]1([CH2:3][O:14]1)[C@H:18]1[CH2:4][CH2:5][C@H:22]2[C@@H:19]3[CH2:10][CH:13]=[C:23]4[CH2:6][C@H:20]([CH2:7][CH2:11][C@:27]4([CH3:1])[C@H:21]3[CH2:8][CH2:12][C@@:26]21[CH3:2])[O:15][Si](C)(C)C(C)(C)C>>[CH3:2][C@:26]12[CH2:12][CH2:8][C@H:21]3[C@@H:19]([CH2:10][CH:13]=[C:23]4[CH2:6][C@@H:20]([OH:15])[CH2:7][CH2:11][C@@:27]43[CH3:1])[C@@H:22]1[CH2:5][CH2:4][C@@H:18]2[C:25]1[CH:17]=[C:24]([CH2:9]F)[O:14][CH:3]=1.[CH3:1][C@:27]12[CH2:11][CH2:7][C@H:20]([OH:15])[CH2:6][C:23]1=[CH:13][CH2:10][C@@H:19]1[C@@H:21]2[CH2:8][CH2:12][C@:26]2([CH3:2])[C@H:18]([CH2:4][CH2:5][C@H:22]21)[C:25]1[CH:17]=[C:24]([CH2:9][OH:16])[O:14][CH:3]=1 |f:1.2,w:4,7,13,a:16,19,20,25,28,30,33,44,47,48,53,57,59,62,71,74,80,81,84,86,89|
+[C@:1]1([O:48][CH2:4]1)([C@@:3]1([H])[CH2:9][CH2:17][C@@:14]2([H])[C@:24]3([H])[CH2:27][CH:29]=[C:30]4[CH2:33][C@H:35]([CH2:34][CH2:31][C@:28]4([CH3:32])[C@@:26]3([H])[CH2:25][CH2:15][C@:8]12[CH3:16])[O:36][Si](C)(C)C(C)(C)C)[CH:2](OS(=O)(=O)C)[C:6]1([Si](C)(C)C)[O:49][CH2:10]1>>[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10]F)=[CH:2]1.[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10][OH:49])=[CH:2]1 |a:0,3,7,9,15,18,20,24,47,51,53,57,63,65,69,78,82,84,88,94,96,100,w:34,40|
+C[Si](C)(C)[C:24]1([CH2:9][O:16]1)[CH:17](OS(C)(=O)=O)[C@:25]1([CH2:3][O:14]1)[C@H:18]1[CH2:4][CH2:5][C@H:22]2[C@@H:19]3[CH2:10][CH:13]=[C:23]4[CH2:6][C@H:20]([CH2:7][CH2:11][C@:27]4([CH3:1])[C@H:21]3[CH2:8][CH2:12][C@@:26]21[CH3:2])[O:15][Si](C)(C)C(C)(C)C>>[CH3:2][C@:26]12[CH2:12][CH2:8][C@H:21]3[C@@H:19]([CH2:10][CH:13]=[C:23]4[CH2:6][C@@H:20]([OH:15])[CH2:7][CH2:11][C@@:27]43[CH3:1])[C@@H:22]1[CH2:5][CH2:4][C@@H:18]2[C:25]1[CH:17]=[C:24]([CH2:9]F)[O:14][CH:3]=1.[CH3:1][C@:27]12[CH2:11][CH2:7][C@H:20]([OH:15])[CH2:6][C:23]1=[CH:13][CH2:10][C@@H:19]1[C@@H:21]2[CH2:8][CH2:12][C@:26]2([CH3:2])[C@H:18]([CH2:4][CH2:5][C@H:22]21)[C:25]1[CH:17]=[C:24]([CH2:9][OH:16])[O:14][CH:3]=1 |f:1.2,w:4,7,a:13,16,19,20,25,28,30,33,44,47,48,53,57,59,62,71,74,80,81,84,86,89|
*** 290 ***
[C@H:1]1([CH2:4][C:9](=[O:13])[O:12][CH3:14])[C:3](=[O:8])[CH2:7][C@@:10]2([H])[CH:11]=[CH:6][C@:2]1([H])[O:29]2.S(=O)(=O)(C(F)(F)F)O[Si:22]([CH3:28])([CH3:27])[CH3:26]>>[CH:10]1([O:29][Si:22]([CH3:28])([CH3:27])[CH3:26])[CH2:11][CH2:6][CH:2]=[C:1]([CH2:4][C:9](=[O:13])[O:12][CH3:14])[C:3](=[O:8])[CH2:7]1.[C@@H:2]1([CH2:6][CH2:11][CH:10]=[CH:7][C:3](=[O:8])[C@@H:1]1[CH2:4][C:9](=[O:13])[O:12][CH3:14])[O:29][Si:22]([CH3:28])([CH3:27])[CH3:26].[C@@:3]12([CH:7]=[CH:10][CH2:11][CH2:6][C@H:2]([O:29][Si:22]([CH3:28])([CH3:27])[CH3:26])[C@@:1]1([H])[C@@H:4]2[C:9](=[O:13])[O:12][CH3:14])[O:8][Si:22]([CH3:28])([CH3:27])[CH3:26] |&1:0,9,13,46,53,64,69,75,77|
[CH3:1][O:12][C:16](=[O:6])[CH2:8][C@@H:13]1[C@@H:14]2[CH:10]=[CH:9][C@H:15]([CH2:7][C:17]1=[O:5])[O:11]2.[CH3:2][Si:18]([CH3:3])([CH3:4])OS(=O)(=O)C(F)(F)F>>[CH3:4][Si:18]([CH3:2])([CH3:3])[O:11][C@@H:14]1[CH2:10][CH2:9][CH:15]=[CH:7][C:17](=[O:5])[C@H:13]1[CH2:8][C:16](=[O:6])[O:12][CH3:1].[CH3:4][Si:18]([CH3:2])([CH3:3])[O:11][CH:15]1[CH2:7][C:17](=[O:5])[C:13]([CH2:8][C:16](=[O:6])[O:12][CH3:1])=[CH:14][CH2:10][CH2:9]1.[CH3:3][Si:18]([CH3:2])([CH3:4])[O:11][C@@H:14]1[CH2:10][CH2:9][CH:15]=[CH:7][C@:17]2([O:5][Si:18]([CH3:3])([CH3:2])[CH3:4])[C@H:13]1[C@H:8]2[C:16](=[O:6])[O:12][CH3:1] |f:0.1,2.3.4,&1:5,6,9,31,38,67,72,78,79|
diff --git a/api/tests/integration/ref/standardize/basic.py.out b/api/tests/integration/ref/standardize/basic.py.out
index 55e9d14b1e..24d4e8a98b 100644
--- a/api/tests/integration/ref/standardize/basic.py.out
+++ b/api/tests/integration/ref/standardize/basic.py.out
@@ -1115,8 +1115,8 @@ M END
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
- 1 2 1 0 0 0 0
- 2 3 1 0 0 0 0
+ 2 1 1 4 0 0 0
+ 2 3 1 4 0 0 0
2 4 1 0 0 0 0
4 5 4 0 0 0 0
5 6 4 0 0 0 0
@@ -1153,7 +1153,7 @@ M END
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
- 1 2 1 0 0 0 0
+ 2 1 1 0 0 0 0
2 3 1 0 0 0 0
2 4 1 0 0 0 0
4 5 4 0 0 0 0
@@ -1192,8 +1192,8 @@ M END
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
- 1 2 1 0 0 0 0
- 2 3 1 0 0 0 0
+ 2 1 1 4 0 0 0
+ 2 3 1 4 0 0 0
2 4 1 0 0 0 0
4 5 4 0 0 0 0
5 6 4 0 0 0 0
@@ -1230,8 +1230,8 @@ M END
0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
0.0000 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
- 1 2 1 0 0 0 0
- 2 3 1 0 0 0 0
+ 2 1 1 4 0 0 0
+ 2 3 1 4 0 0 0
2 4 1 0 0 0 0
4 5 4 0 0 0 0
5 6 4 0 0 0 0
diff --git a/api/tests/integration/ref/stereo/bidirectional.py.out b/api/tests/integration/ref/stereo/bidirectional.py.out
index 99901048f5..6f337825d7 100644
--- a/api/tests/integration/ref/stereo/bidirectional.py.out
+++ b/api/tests/integration/ref/stereo/bidirectional.py.out
@@ -28,7 +28,7 @@ test2.mol stereocenters: one bond up, one bond down -- indefinite case near atom
04.mol C1CCC([C@H]2C=CC(N([H])C2=O)=O)O1 |&1:4,r|
05.mol C1CC[C@@H]([C@H]2C=CC(N([H])C2=O)=O)O1 |&1:3,4,r|
06.mol C1CC[C@@H](C2C=CC(N([H])C2=O)=O)O1 |&1:3,r|
-07.mol C1CCC(C2C=CC(N([H])C2=O)=O)O1
+07.mol C1CCC(C2C=CC(N([H])C2=O)=O)O1 |&1:3,r,wU:3.2,wD:3.3,(-2.06,-0.81,;-1.79,-1.62,;-0.94,-1.62,;-0.70,-0.78,;0.04,-0.14,;-0.15,0.64,;0.46,1.24,;1.22,1.01,;1.53,0.12,;2.06,-0.05,;0.82,-0.39,;1.04,-1.18,;1.84,1.62,;-1.41,-0.31,)|
08.mol C1CC[C@@](C)(C2C=CC(N([H])C2=O)=O)O1 |&1:3,r|
09.mol C1CC[C@@](C)(C2C=CC(N([H])C2=O)=O)O1 |&1:3,r|
10.mol C1CCC(C)(C2C=CC(N([H])C2=O)=O)O1
diff --git a/api/tests/integration/tests/basic/ref/crazystereo.ket b/api/tests/integration/tests/basic/ref/crazystereo.ket
index fe4a79bc83..e381f2a6b5 100644
--- a/api/tests/integration/tests/basic/ref/crazystereo.ket
+++ b/api/tests/integration/tests/basic/ref/crazystereo.ket
@@ -216,7 +216,8 @@
9.062226295471192,
0.7499902248382568,
0.0
- ]
+ ],
+ "stereoLabel": "&1"
},
{
"label": "C",
diff --git a/api/tests/integration/tests/exact/reload.py b/api/tests/integration/tests/exact/reload.py
index 5b8297aee4..3297da7b09 100644
--- a/api/tests/integration/tests/exact/reload.py
+++ b/api/tests/integration/tests/exact/reload.py
@@ -41,7 +41,7 @@ def testMol(mol):
perm_smiles = perm_mol.smiles()
if not indigo.exactMatch(mol, perm_mol):
msg = (
- " Exact: %s after reload from smiles %s. Permuted canonical smiles: %s\n %s %s"
+ " Exact: %s after reload from smiles %s. Permuted canonical smiles: %s"
% (mol.name(), base_smiles, perm_smiles)
)
print(msg)
diff --git a/api/tests/integration/tests/formats/ref/acd2d_err.ket b/api/tests/integration/tests/formats/ref/acd2d_err.ket
index 8a132ba64f..3f3f732ee1 100644
--- a/api/tests/integration/tests/formats/ref/acd2d_err.ket
+++ b/api/tests/integration/tests/formats/ref/acd2d_err.ket
@@ -54263,7 +54263,8 @@
0.03449999913573265,
1.1758999824523926,
0.0
- ]
+ ],
+ "stereoLabel": "&1"
},
{
"label": "C",
diff --git a/api/tests/integration/tests/formats/ref/acd2d_err3.sdf b/api/tests/integration/tests/formats/ref/acd2d_err3.sdf
index 7f61be9c7b..ade3ac61b4 100644
--- a/api/tests/integration/tests/formats/ref/acd2d_err3.sdf
+++ b/api/tests/integration/tests/formats/ref/acd2d_err3.sdf
@@ -8493,6 +8493,7 @@ M V30 30 1 13 25 CFG=3
M V30 31 1 14 26 CFG=3
M V30 END BOND
M V30 BEGIN COLLECTION
+M V30 MDLV30/STEABS ATOMS=(1 1)
M V30 MDLV30/STERAC1 ATOMS=(7 2 9 10 11 12 13 14)
M V30 END COLLECTION
M V30 END CTAB
diff --git a/api/tests/integration/tests/formats/smiles.py b/api/tests/integration/tests/formats/smiles.py
index 60885b3514..e650df5a2c 100644
--- a/api/tests/integration/tests/formats/smiles.py
+++ b/api/tests/integration/tests/formats/smiles.py
@@ -117,7 +117,11 @@
print(indigo.loadMolecule(sm).smiles())
print("*** Atropisomers ***")
-mols_smiles = ["C1C(O)=C(C2C=CC(C)=CC=2N)C(C)=CC=1 |o1:3,r,wU:3.12|"]
+mols_smiles = [
+ "C1C(O)=C(C2C=CC(C)=CC=2N)C(C)=CC=1 |o1:3,r,wU:3.12|",
+ "C1=CC=C(C)C(C2=C(N)C=C(C)C=C2)=C1O |wU:5.4,wD:5.5|",
+ "C1=CC=C(C)C(C2=C(N)C=C(C)C=C2)=C1O |w:5.4,5.5|",
+]
for sm in mols_smiles:
print("atropisomer:")
mol = indigo.loadMolecule(sm)
diff --git a/bingo/tests/data/molecules/checkmolecule/std.json b/bingo/tests/data/molecules/checkmolecule/std.json
index 975559c2ee..a4d438ba0d 100644
--- a/bingo/tests/data/molecules/checkmolecule/std.json
+++ b/bingo/tests/data/molecules/checkmolecule/std.json
@@ -8352,17 +8352,17 @@
{
"query_id": 1671,
"query_type": "checkmolecule",
- "expected": "molfile loader: direction of bond #22 makes no sense"
+ "expected": "molfile loader: direction of bond #185 makes no sense"
},
{
"query_id": 1672,
"query_type": "checkmolecule",
- "expected": "molfile loader: direction of bond #22 makes no sense"
+ "expected": "molfile loader: direction of bond #185 makes no sense"
},
{
"query_id": 1673,
"query_type": "checkmolecule",
- "expected": "molfile loader: direction of bond #177 makes no sense"
+ "expected": "molfile loader: direction of bond #185 makes no sense"
},
{
"query_id": 1674,
diff --git a/bingo/tests/data/molecules/cml/std.json b/bingo/tests/data/molecules/cml/std.json
index 023a75fd81..3462218872 100644
--- a/bingo/tests/data/molecules/cml/std.json
+++ b/bingo/tests/data/molecules/cml/std.json
@@ -3722,7 +3722,7 @@
{
"query_id": 745,
"query_type": "cml",
- "expected": "\n\n \n \n \n \n \n 1\n \n \n 1\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 1\n \n \n \n \n \n 1\n \n \n 1\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 1\n \n \n 1\n \n \n \n \n \n 1\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n 1\n \n \n 1\n \n \n \n \n 1\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n T\n \n \n \n \n C\n \n \n \n C\n \n \n C\n \n \n \n C\n \n \n \n C\n \n \n \n C\n \n \n C\n \n \n \n C\n \n \n \n \n W\n \n \n \n \n \n W\n \n \n W\n \n \n \n \n \n \n \n W\n \n \n \n \n \n W\n \n \n W\n \n \n \n \n \n \n \n \n T\n \n \n \n T\n \n \n \n \n C\n \n \n \n C\n \n \n C\n \n \n \n C\n \n \n \n \n \n T\n \n \n \n T\n \n \n \n \n \n W\n \n \n \n \n \n W\n \n \n W\n \n \n \n \n \n \n \n \n T\n \n \n \n \n W\n \n \n \n \n \n W\n \n \n W\n \n \n \n \n \n \n \n \n T\n \n \n \n T\n \n \n \n \n C\n \n \n \n C\n \n \n C\n \n \n \n C\n \n \n \n \n\n"
+ "expected": "11111111111TCCCCCCCCWWWWWWTTCCCCTTWWWTWWWTTCCCC\n"
},
{
"query_id": 746,
diff --git a/bingo/tests/data/molecules/compactmolecule/std.json b/bingo/tests/data/molecules/compactmolecule/std.json
index 3402f39342..2a715c6499 100644
--- a/bingo/tests/data/molecules/compactmolecule/std.json
+++ b/bingo/tests/data/molecules/compactmolecule/std.json
@@ -3722,7 +3722,7 @@
{
"query_id": 745,
"query_type": "compactmolecule(0)",
- "expected": "942f6642b01222a2a8d1b953c4477764"
+ "expected": "757a56ddfcbfe7e377b87037fb415a40"
},
{
"query_id": 746,
diff --git a/bingo/tests/data/reactions/compactreaction/std.json b/bingo/tests/data/reactions/compactreaction/std.json
index 3e71814fab..cd8d134a43 100644
--- a/bingo/tests/data/reactions/compactreaction/std.json
+++ b/bingo/tests/data/reactions/compactreaction/std.json
@@ -1447,7 +1447,7 @@
{
"query_id": 290,
"query_type": "compactreaction(0)",
- "expected": "871fbada43b7c6c4b1c7a3298791bb1d"
+ "expected": "b0deb28fd1bd4350908254566b88b994"
},
{
"query_id": 291,
diff --git a/bingo/tests/data/reactions/rsmiles/std.json b/bingo/tests/data/reactions/rsmiles/std.json
index df1ee6bb33..d2014162c3 100644
--- a/bingo/tests/data/reactions/rsmiles/std.json
+++ b/bingo/tests/data/reactions/rsmiles/std.json
@@ -1447,7 +1447,7 @@
{
"query_id": 290,
"query_type": "rsmiles",
- "expected": "[C:1]1([O:48][CH2:4]1)([C@@:3]1([H])[CH2:9][CH2:17][C@@:14]2([H])[C@:24]3([H])[CH2:27][CH:29]=[C:30]4[CH2:33][C@H:35]([CH2:34][CH2:31][C@:28]4([CH3:32])[C@@:26]3([H])[CH2:25][CH2:15][C@:8]12[CH3:16])[O:36][Si](C)(C)C(C)(C)C)[CH:2](OS(=O)(=O)C)[C:6]1([Si](C)(C)C)[O:49][CH2:10]1>>[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10]F)=[CH:2]1.[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10][OH:49])=[CH:2]1 |w:0,34,40,a:3,7,9,15,18,20,24,47,51,53,57,63,65,69,78,82,84,88,94,96,100|"
+ "expected": "[C@:1]1([O:48][CH2:4]1)([C@@:3]1([H])[CH2:9][CH2:17][C@@:14]2([H])[C@:24]3([H])[CH2:27][CH:29]=[C:30]4[CH2:33][C@H:35]([CH2:34][CH2:31][C@:28]4([CH3:32])[C@@:26]3([H])[CH2:25][CH2:15][C@:8]12[CH3:16])[O:36][Si](C)(C)C(C)(C)C)[CH:2](OS(=O)(=O)C)[C:6]1([Si](C)(C)C)[O:49][CH2:10]1>>[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10]F)=[CH:2]1.[C@:8]12([CH3:16])[CH2:15][CH2:25][C@:26]3([H])[C@@:28]4([CH3:32])[CH2:31][CH2:34][C@H:35]([OH:36])[CH2:33][C:30]4=[CH:29][CH2:27][C@@:24]3([H])[C@:14]1([H])[CH2:17][CH2:9][C@:3]2([H])[C:1]1=[CH:4][O:48][C:6]([CH2:10][OH:49])=[CH:2]1 |a:0,3,7,9,15,18,20,24,47,51,53,57,63,65,69,78,82,84,88,94,96,100,w:34,40|"
},
{
"query_id": 291,
diff --git a/bingo/tests/test_rsmiles/test_rsmiles.py b/bingo/tests/test_rsmiles/test_rsmiles.py
index a6e774b14a..2d98f7639d 100644
--- a/bingo/tests/test_rsmiles/test_rsmiles.py
+++ b/bingo/tests/test_rsmiles/test_rsmiles.py
@@ -2,7 +2,6 @@
from ..helpers import assert_calculate_query, query_cases
-
class TestRsmiles:
@pytest.mark.parametrize("query_id, expected", query_cases("rsmiles"))
def test_molecular_weight(self, db, entities, query_id, expected):
diff --git a/core/indigo-core/molecule/base_molecule.h b/core/indigo-core/molecule/base_molecule.h
index 7b3256d2bd..51f33c6266 100644
--- a/core/indigo-core/molecule/base_molecule.h
+++ b/core/indigo-core/molecule/base_molecule.h
@@ -195,7 +195,6 @@ namespace indigo
void removeAttachmentPointsFromAtom(int atom_index);
int attachmentPointCount() const;
void removeAttachmentPoints();
-
void getAttachmentIndicesForAtom(int atom_idx, Array& res);
virtual bool isSaturatedAtom(int idx) = 0;
@@ -247,8 +246,6 @@ namespace indigo
void clearCIP();
CIPDesc getAtomCIP(int atom_idx);
CIPDesc getBondCIP(int bond_idx);
- bool isAtropisomerismReferenceAtom(int atom_idx);
- bool isRotationBond(int bond_idx);
void setAtomCIP(int atom_idx, CIPDesc cip);
void setBondCIP(int bond_idx, CIPDesc cip);
@@ -421,7 +418,7 @@ namespace indigo
const int* getPyramidStereocenters(int idx) const;
void markBondsStereocenters();
void markBondStereocenters(int atom_idx);
- bool hasAtropisomericCenter();
+ bool hasAtropoStereoBonds();
void addStereocenters(int atom_idx, int type, int group, const int pyramid[4]);
void addStereocenters(int atom_idx, int type, int group, bool inverse_pyramid);
@@ -433,6 +430,8 @@ namespace indigo
void buildFromBondsStereocenters(const StereocentersOptions& options, int* sensible_bonds_out);
void buildFrom3dCoordinatesStereocenters(const StereocentersOptions& options);
bool isPossibleStereocenter(int atom_idx, bool* possible_implicit_h = 0, bool* possible_lone_pair = 0);
+ bool isPossibleAtropocenter(int atom_idx, int& possible_atropo_bond);
+
void buildOnSubmoleculeStereocenters(const BaseMolecule& super, int* mapping);
// proxy methods for cis_trans
diff --git a/core/indigo-core/molecule/molecule_stereocenters.h b/core/indigo-core/molecule/molecule_stereocenters.h
index faa1e68218..1852980de6 100644
--- a/core/indigo-core/molecule/molecule_stereocenters.h
+++ b/core/indigo-core/molecule/molecule_stereocenters.h
@@ -19,6 +19,8 @@
#ifndef __molecule_stereocenters__
#define __molecule_stereocenters__
+#include
+
#include "base_cpp/red_black.h"
#include "math/algebra.h"
@@ -54,6 +56,7 @@ namespace indigo
void markBonds(BaseMolecule& baseMolecule);
void markBond(BaseMolecule& baseMolecule, int atom_idx);
+ void markAtropisomericBond(BaseMolecule& baseMolecule, int atom_idx);
// takes mapping from supermolecule to submolecule
void buildOnSubmolecule(BaseMolecule& baseMolecule, const BaseMolecule& super, int* mapping);
@@ -83,7 +86,10 @@ namespace indigo
void setType(int idx, int type, int group);
void setType(int idx, int type);
void setAtropisomeric(int idx, bool val);
- bool isAtropisomeric(int idx);
+ bool isAtropisomeric(int idx) const;
+ void setTetrahydral(int idx, bool val);
+ bool isTetrahydral(int idx) const;
+
void invertPyramid(int idx);
bool sameGroup(int idx1, int idx2);
@@ -111,6 +117,11 @@ namespace indigo
int getAtomIndex(int i) const;
bool isPossibleStereocenter(BaseMolecule& baseMolecule, int atom_idx, bool* possible_implicit_h = 0, bool* possible_lone_pair = 0);
+ bool isPossibleAtropocenter(BaseMolecule& baseMolecule, int atom_idx, int& possible_atropo_bond);
+ bool hasAtropoStereoBonds(BaseMolecule& baseMolecule, int atom_idx);
+ bool findAtropoStereobonds(BaseMolecule& baseMolecule, RedBlackMap& directions_map, int atom_idx, std::unordered_set& visited_bonds,
+ bool first_only = false, int* sensible_bonds_out = nullptr);
+ bool hasRing(BaseMolecule& baseMolecule, int atom_idx, std::unordered_set& visited_bonds);
public:
static bool checkSub(BaseMolecule& query, BaseMolecule& target, const int* mapping, bool reset_h_isotopes, Filter* stereocenters_vertex_filter = 0);
@@ -134,15 +145,25 @@ namespace indigo
private:
struct _Atom
{
+ _Atom() : type(-1), group(1), is_atropisomeric(false), is_tetrahydral(true), pyramid{-1, -1, -1, -1}
+ {
+ }
int type; // ANY, AND, OR, ABS
int group; // stereogroup index
// [X, Y, Z, W] -- atom indices or -1 for implicit hydrogen
// (X, Y, Z) go counterclockwise when looking from W.
// if there are pure (implicit) hydrogen, it is W
- bool is_atropisomeric = false;
+ bool is_atropisomeric;
+ bool is_tetrahydral;
int pyramid[4];
};
+ struct _AtropoCenter
+ {
+ int atropo_bond;
+ RedBlackMap bond_directions;
+ };
+
struct _EdgeIndVec
{
int edge_idx;
@@ -161,13 +182,14 @@ namespace indigo
};
RedBlackMap _stereocenters;
+ RedBlackObjMap _atropocenters;
static int _sign(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3);
static int _xyzzy(const Vec3f& v1, const Vec3f& v2, const Vec3f& u);
static int _onPlane(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4);
bool _buildOneCenter(BaseMolecule& baseMolecule, int atom_idx, int* sensible_bonds_out, bool bidirectional_mode, bool bidirectional_either_mode,
- const Array& bond_ignore);
+ const Array& bond_ignore, bool check_atropocenter = false);
void _buildOneFrom3dCoordinates(BaseMolecule& baseMolecule, int idx);
diff --git a/core/indigo-core/molecule/smiles_loader.h b/core/indigo-core/molecule/smiles_loader.h
index f80adafec4..8c6ee08247 100644
--- a/core/indigo-core/molecule/smiles_loader.h
+++ b/core/indigo-core/molecule/smiles_loader.h
@@ -156,6 +156,8 @@ namespace indigo
int _balance;
int _current_compno;
bool _inside_smarts_component;
+ bool _has_atom_coordinates = false;
+ bool _has_directions_on_rings = false;
BaseMolecule* _bmol;
QueryMolecule* _qmol;
diff --git a/core/indigo-core/molecule/smiles_saver.h b/core/indigo-core/molecule/smiles_saver.h
index 65981dff94..bd3c668e9c 100644
--- a/core/indigo-core/molecule/smiles_saver.h
+++ b/core/indigo-core/molecule/smiles_saver.h
@@ -129,6 +129,7 @@ namespace indigo
void _writeUnsaturated();
void _writeSubstitutionCounts();
void _writeWedges();
+ void _writeBondDirs(const std::string& tag, const std::vector>& bonds);
bool _shouldWriteAromaticBond(int bond_idx);
void _startExtension();
diff --git a/core/indigo-core/molecule/src/base_molecule.cpp b/core/indigo-core/molecule/src/base_molecule.cpp
index 6301750736..805391d563 100644
--- a/core/indigo-core/molecule/src/base_molecule.cpp
+++ b/core/indigo-core/molecule/src/base_molecule.cpp
@@ -4196,12 +4196,12 @@ void BaseMolecule::markBondsStereocenters()
stereocenters.markBonds(*this);
}
-bool BaseMolecule::hasAtropisomericCenter()
+bool BaseMolecule::hasAtropoStereoBonds()
{
for (int i = stereocenters.begin(); i != stereocenters.end(); i = stereocenters.next(i))
{
auto atom_idx = stereocenters.getAtomIndex(i);
- if (stereocenters.isAtropisomeric(atom_idx))
+ if (stereocenters.hasAtropoStereoBonds(*this, atom_idx))
return true;
}
return false;
@@ -4252,6 +4252,11 @@ bool BaseMolecule::isPossibleStereocenter(int atom_idx, bool* possible_implicit_
return stereocenters.isPossibleStereocenter(*this, atom_idx, possible_implicit_h, possible_lone_pair);
}
+bool BaseMolecule::isPossibleAtropocenter(int atom_idx, int& possible_atropo_bond)
+{
+ return stereocenters.isPossibleAtropocenter(*this, atom_idx, possible_atropo_bond);
+}
+
void BaseMolecule::buildOnSubmoleculeStereocenters(const BaseMolecule& super, int* mapping)
{
stereocenters.buildOnSubmolecule(*this, super, mapping);
@@ -4420,54 +4425,3 @@ void BaseMolecule::removeAlias(int atom_idx)
{
aliases.remove(atom_idx);
}
-
-bool BaseMolecule::isAtropisomerismReferenceAtom(int atom_idx)
-{
- // TODO: implement more accurate atropisomer detection
- if (vertexInRing(atom_idx)) // check if the atom belongs to ring
- {
- bool has_stereo = false;
- const Vertex& v = getVertex(atom_idx);
- // check if the atom has at least one stereo-bond
- for (int i = v.neiBegin(); i != v.neiEnd(); i = v.neiNext(i))
- {
- if (getBondDirection(v.neiEdge(i)))
- {
- has_stereo = true;
- break;
- }
- }
- if (has_stereo)
- {
- std::unordered_set rotation_bonds;
- // looking for a rotation bond
- for (int i = v.neiBegin(); i != v.neiEnd(); i = v.neiNext(i))
- {
- auto bond_idx = v.neiEdge(i);
- if (getBondDirection(bond_idx))
- continue;
- if (isRotationBond(bond_idx))
- rotation_bonds.insert(bond_idx);
- }
- if (rotation_bonds.size())
- return true;
- }
- }
- return false;
-}
-
-bool BaseMolecule::isRotationBond(int bond_idx)
-{
- // typically a rotation doesn't belong to a ring.
- // but there are some exclusions to be handled.
- if (getEdgeTopology(bond_idx) == TOPOLOGY_RING)
- return false;
- // remove the bond and check if an extra component appears.
- // if so this can be a rotation bond.
- std::unique_ptr mol(neu());
- mol->clone_KeepIndices(*this);
- int old_count = mol->countComponents();
- mol->removeBond(bond_idx);
- int new_count = mol->countComponents();
- return new_count > old_count;
-}
diff --git a/core/indigo-core/molecule/src/cml_loader.cpp b/core/indigo-core/molecule/src/cml_loader.cpp
index d64c53e4bf..2801243d70 100644
--- a/core/indigo-core/molecule/src/cml_loader.cpp
+++ b/core/indigo-core/molecule/src/cml_loader.cpp
@@ -1082,11 +1082,9 @@ void CmlLoader::_loadMoleculeElement(XMLHandle& handle)
if (_bmol->stereocenters.size() == 0 && BaseMolecule::hasCoord(*_bmol))
{
- QS_DEF(Array, sensible_bond_orientations);
-
- sensible_bond_orientations.clear_resize(_bmol->vertexEnd());
- _bmol->buildFromBondsStereocenters(stereochemistry_options, sensible_bond_orientations.ptr());
-
+ std::vector sensible_bond_orientations;
+ sensible_bond_orientations.resize(_bmol->edgeEnd(), 0);
+ _bmol->buildFromBondsStereocenters(stereochemistry_options, sensible_bond_orientations.data());
if (!stereochemistry_options.ignore_errors)
for (i = 0; i < _bmol->vertexCount(); i++)
if (_bmol->getBondDirection(i) > 0 && !sensible_bond_orientations[i])
diff --git a/core/indigo-core/molecule/src/cml_saver.cpp b/core/indigo-core/molecule/src/cml_saver.cpp
index fe5c90487d..f034b01d4e 100644
--- a/core/indigo-core/molecule/src/cml_saver.cpp
+++ b/core/indigo-core/molecule/src/cml_saver.cpp
@@ -368,7 +368,7 @@ void CmlSaver::_addMoleculeElement(XMLElement* elem, BaseMolecule& mol, bool que
}
}
- if (_mol->stereocenters.getType(i) > MoleculeStereocenters::ATOM_ANY)
+ if (_mol->stereocenters.getType(i) > MoleculeStereocenters::ATOM_ANY && _mol->stereocenters.isTetrahydral(i))
{
XMLElement* atomparity = _doc->NewElement("atomParity");
atom->LinkEndChild(atomparity);
diff --git a/core/indigo-core/molecule/src/inchi_wrapper.cpp b/core/indigo-core/molecule/src/inchi_wrapper.cpp
index 5da196f263..214a634cb9 100644
--- a/core/indigo-core/molecule/src/inchi_wrapper.cpp
+++ b/core/indigo-core/molecule/src/inchi_wrapper.cpp
@@ -523,6 +523,8 @@ void InchiWrapper::generateInchiInput(Molecule& mol, inchi_Input& input, Array mol(bmol.neu());
mol->clone_KeepIndices(bmol);
+
if (!BaseMolecule::hasCoord(*mol))
{
MoleculeLayout ml(*mol, false);
diff --git a/core/indigo-core/molecule/src/molecule_stereocenters.cpp b/core/indigo-core/molecule/src/molecule_stereocenters.cpp
index 87797f447c..072751255d 100644
--- a/core/indigo-core/molecule/src/molecule_stereocenters.cpp
+++ b/core/indigo-core/molecule/src/molecule_stereocenters.cpp
@@ -48,10 +48,14 @@ void MoleculeStereocenters::buildFromBonds(BaseMolecule& baseMolecule, const Ste
const Array& bonds_ignore = haworth_finder.getBondsMask();
const Array& atoms_ignore = haworth_finder.getAtomsMask();
+ bool check_atropisomery = false;
for (int i = baseMolecule.edgeBegin(); i != baseMolecule.edgeEnd(); i = baseMolecule.edgeNext(i))
{
- if (bonds_ignore[i] && baseMolecule.getBondDirection(i))
+ auto bdir = baseMolecule.getBondDirection(i);
+ if (bonds_ignore[i] && bdir)
sensible_bonds_out[i] = 1;
+ if (!check_atropisomery && bdir && baseMolecule.getBondTopology(i) == TOPOLOGY_RING)
+ check_atropisomery = true;
}
for (int i = baseMolecule.vertexBegin(); i != baseMolecule.vertexEnd(); i = baseMolecule.vertexNext(i))
@@ -63,7 +67,7 @@ void MoleculeStereocenters::buildFromBonds(BaseMolecule& baseMolecule, const Ste
bool found = false;
try
{
- found = _buildOneCenter(baseMolecule, i, sensible_bonds_out, false, options.bidirectional_mode, bonds_ignore);
+ found = _buildOneCenter(baseMolecule, i, sensible_bonds_out, false, options.bidirectional_mode, bonds_ignore, check_atropisomery);
}
catch (Error&)
{
@@ -85,6 +89,32 @@ void MoleculeStereocenters::buildFromBonds(BaseMolecule& baseMolecule, const Ste
}
}
}
+
+ for (int i = _stereocenters.begin(); i != _stereocenters.end(); i = _stereocenters.next(i))
+ {
+ _Atom& atom = _stereocenters.value(i);
+ if (atom.is_atropisomeric)
+ {
+ int atom_idx = _stereocenters.key(i);
+ _AtropoCenter& ac = _atropocenters.at(atom_idx);
+ std::unordered_set visited_bonds;
+ if (findAtropoStereobonds(baseMolecule, ac.bond_directions, atom_idx, visited_bonds, false, sensible_bonds_out))
+ {
+ auto bdir = baseMolecule.getBondDirection(ac.atropo_bond);
+ // include possible atropobond itself if its direction is not sensible, but direction is set
+ if (bdir && !sensible_bonds_out[ac.atropo_bond])
+ {
+ ac.bond_directions.insert(ac.atropo_bond, bdir);
+ sensible_bonds_out[ac.atropo_bond] = 1;
+ }
+ }
+ else
+ {
+ atom.is_atropisomeric = false;
+ _atropocenters.remove(atom_idx);
+ }
+ }
+ }
}
void MoleculeStereocenters::buildFrom3dCoordinates(BaseMolecule& baseMolecule, const StereocentersOptions& options)
@@ -193,6 +223,103 @@ void MoleculeStereocenters::_buildOneFrom3dCoordinates(BaseMolecule& baseMolecul
add(baseMolecule, idx, ATOM_ABS, 0, false);
}
+bool MoleculeStereocenters::hasAtropoStereoBonds(BaseMolecule& baseMolecule, int atom_idx)
+{
+ return _atropocenters.find(atom_idx) && _atropocenters.at(atom_idx).bond_directions.size();
+}
+
+bool MoleculeStereocenters::isPossibleAtropocenter(BaseMolecule& baseMolecule, int atom_idx, int& possible_atropo_bond)
+{
+ if (baseMolecule.vertexInRing(atom_idx)) // check if the atom belongs to ring
+ {
+ bool has_stereo = false;
+ const Vertex& v = baseMolecule.getVertex(atom_idx);
+ // check if the atom has at least one stereo-bond
+ for (int i = v.neiBegin(); i != v.neiEnd(); i = v.neiNext(i))
+ {
+ if (baseMolecule.getBondDirection(v.neiEdge(i)))
+ {
+ for (int i = v.neiBegin(); i != v.neiEnd(); i = v.neiNext(i))
+ {
+ auto bond_idx = v.neiEdge(i);
+ if (baseMolecule.getEdgeTopology(bond_idx) == TOPOLOGY_CHAIN && baseMolecule.getBondOrder(bond_idx) == BOND_SINGLE &&
+ baseMolecule.vertexInRing(v.neiVertex(i)))
+ {
+ std::unordered_set visited;
+ RedBlackMap dir_map;
+ visited.insert(bond_idx);
+ if (findAtropoStereobonds(baseMolecule, dir_map, atom_idx, visited, true))
+ {
+ possible_atropo_bond = bond_idx;
+ return true;
+ }
+ //{ // advanced rings search. currently not in use.
+ // visited.clear();
+ // visited.insert(bond_idx);
+ // if (hasRing(baseMolecule, v.neiVertex(i), visited))
+ // {
+ // possible_atropo_bond = bond_idx;
+ // return true;
+ // }
+ //}
+ }
+ }
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+// recursive search of for stereobonds withing connected rings
+bool MoleculeStereocenters::findAtropoStereobonds(BaseMolecule& baseMolecule, RedBlackMap& directions_map, int atom_idx,
+ std::unordered_set& visited_bonds, bool first_only, int* sensible_bonds_out)
+{
+ const Vertex& v = baseMolecule.getVertex(atom_idx);
+ for (int i = v.neiBegin(); i != v.neiEnd(); i = v.neiNext(i))
+ {
+ auto bond_idx = v.neiEdge(i);
+ if (visited_bonds.find(bond_idx) == visited_bonds.end())
+ {
+ visited_bonds.insert(bond_idx);
+ auto bdir = baseMolecule.getBondDirection(bond_idx);
+ if (baseMolecule.getBondTopology(bond_idx) == TOPOLOGY_RING)
+ {
+ if (bdir && !directions_map.find(bond_idx))
+ {
+ if (sensible_bonds_out)
+ {
+ if (sensible_bonds_out[bond_idx])
+ continue;
+ else
+ sensible_bonds_out[bond_idx] = 1;
+ }
+ directions_map.insert(bond_idx, bdir);
+ if (first_only)
+ return true;
+ }
+ findAtropoStereobonds(baseMolecule, directions_map, v.neiVertex(i), visited_bonds, first_only, sensible_bonds_out);
+ }
+ }
+ }
+ return directions_map.size();
+}
+
+bool MoleculeStereocenters::hasRing(BaseMolecule& baseMolecule, int atom_idx, std::unordered_set& visited_bonds)
+{
+ const Vertex& v = baseMolecule.getVertex(atom_idx);
+ for (int i = v.neiBegin(); i != v.neiEnd(); i = v.neiNext(i))
+ {
+ auto bond_idx = v.neiEdge(i);
+ if (visited_bonds.find(bond_idx) == visited_bonds.end())
+ {
+ visited_bonds.insert(bond_idx);
+ return baseMolecule.getBondTopology(bond_idx) == TOPOLOGY_RING ? true : hasRing(baseMolecule, v.neiVertex(i), visited_bonds);
+ }
+ }
+ return false;
+}
+
bool MoleculeStereocenters::isPossibleStereocenter(BaseMolecule& baseMolecule, int atom_idx, bool* possible_implicit_h, bool* possible_lone_pair)
{
const Vertex& vertex = baseMolecule.getVertex(atom_idx);
@@ -264,17 +391,33 @@ bool MoleculeStereocenters::isPossibleStereocenter(BaseMolecule& baseMolecule, i
// can be determined by normal direction then do not check if opposite directions
// contradicts original ones.
bool MoleculeStereocenters::_buildOneCenter(BaseMolecule& baseMolecule, int atom_idx, int* sensible_bonds_out, bool bidirectional_mode,
- bool bidirectional_either_mode, const Array& bond_ignore)
+ bool bidirectional_either_mode, const Array& bond_ignore, bool check_atropocenter)
{
- const Vertex& vertex = baseMolecule.getVertex(atom_idx);
-
- int degree = vertex.degree();
-
+ int possible_atropobond = -1;
_Atom stereocenter;
-
stereocenter.group = 1;
stereocenter.type = ATOM_ABS;
+ if (check_atropocenter && isPossibleAtropocenter(baseMolecule, atom_idx, possible_atropobond))
+ {
+ stereocenter.is_atropisomeric = true;
+ _AtropoCenter& ac = _atropocenters.findOrInsert(atom_idx);
+ ac.atropo_bond = possible_atropobond;
+ if (_stereocenters.find(atom_idx))
+ _stereocenters.at(atom_idx).is_atropisomeric = true;
+ else
+ {
+ stereocenter.is_tetrahydral = false;
+ _stereocenters.insert(atom_idx, stereocenter);
+ }
+ }
+
+ // check if there is a tetrahydral stereocenter already
+ if (_stereocenters.find(atom_idx) && _stereocenters.at(atom_idx).is_tetrahydral)
+ return true;
+
+ const Vertex& vertex = baseMolecule.getVertex(atom_idx);
+ int degree = vertex.degree();
int* pyramid = stereocenter.pyramid;
int nei_idx = 0;
_EdgeIndVec edge_ids[4];
@@ -295,6 +438,7 @@ bool MoleculeStereocenters::_buildOneCenter(BaseMolecule& baseMolecule, int atom
bool is_either = false;
bool zero_bond_length = false;
+ std::unordered_set atropo_bonds_ignore;
for (int i = vertex.neiBegin(); i != vertex.neiEnd(); i = vertex.neiNext(i))
{
@@ -304,6 +448,8 @@ bool MoleculeStereocenters::_buildOneCenter(BaseMolecule& baseMolecule, int atom
edge_ids[nei_idx].edge_idx = e_idx;
edge_ids[nei_idx].nei_idx = v_idx;
+ if (stereocenter.is_atropisomeric && baseMolecule.getBondDirection(e_idx) && baseMolecule.getBondTopology(e_idx) == TOPOLOGY_RING)
+ atropo_bonds_ignore.insert(e_idx);
if (baseMolecule.possibleAtomNumberAndIsotope(v_idx, ELEM_H, 0))
{
if (baseMolecule.getAtomNumber(v_idx) == ELEM_H && baseMolecule.getAtomIsotope(v_idx) == 0)
@@ -318,9 +464,7 @@ bool MoleculeStereocenters::_buildOneCenter(BaseMolecule& baseMolecule, int atom
if (!edge_ids[nei_idx].vec.normalize())
zero_bond_length = true;
- if (baseMolecule.getBondOrder(e_idx) == BOND_TRIPLE)
- return false;
- if (baseMolecule.getBondOrder(e_idx) == BOND_AROMATIC)
+ if (baseMolecule.getBondOrder(e_idx) == BOND_TRIPLE || baseMolecule.getBondOrder(e_idx) == BOND_AROMATIC)
return false;
if (baseMolecule.getBondOrder(e_idx) == BOND_DOUBLE)
@@ -336,263 +480,283 @@ bool MoleculeStereocenters::_buildOneCenter(BaseMolecule& baseMolecule, int atom
bool possible_implicit_h = false;
bool possible_lone_pair = false;
- int i;
- if (!isPossibleStereocenter(baseMolecule, atom_idx, &possible_implicit_h, &possible_lone_pair))
+ stereocenter.is_tetrahydral = isPossibleStereocenter(baseMolecule, atom_idx, &possible_implicit_h, &possible_lone_pair);
+
+ if (!stereocenter.is_tetrahydral && !stereocenter.is_atropisomeric)
return false;
// Local synonym to get bond direction
auto getDir = [&](int from, int to) {
int idx = baseMolecule.findEdgeIndex(from, to);
- if (bond_ignore[idx])
+ if (bond_ignore[idx] /* || atropo_bonds_ignore.find(idx) != atropo_bonds_ignore.end()*/)
return 0;
return _getDirection(baseMolecule, from, to, bidirectional_mode);
};
- if (is_either)
- {
- stereocenter.type = ATOM_ANY;
- for (i = 0; i < degree; i++)
- {
- stereocenter.pyramid[i] = edge_ids[i].nei_idx;
- if (getDir(atom_idx, edge_ids[i].nei_idx) > 0)
- sensible_bonds_out[edge_ids[i].edge_idx] = 1;
- }
- _stereocenters.insert(atom_idx, stereocenter);
- return true;
- }
-
- if (degree == 4)
+ if (stereocenter.is_tetrahydral)
{
- // sort by neighbor atom index (ascending)
- if (edge_ids[0].rank > edge_ids[1].rank)
- std::swap(edge_ids[0], edge_ids[1]);
- if (edge_ids[1].rank > edge_ids[2].rank)
- std::swap(edge_ids[1], edge_ids[2]);
- if (edge_ids[2].rank > edge_ids[3].rank)
- std::swap(edge_ids[2], edge_ids[3]);
- if (edge_ids[1].rank > edge_ids[2].rank)
- std::swap(edge_ids[1], edge_ids[2]);
- if (edge_ids[0].rank > edge_ids[1].rank)
- std::swap(edge_ids[0], edge_ids[1]);
- if (edge_ids[1].rank > edge_ids[2].rank)
- std::swap(edge_ids[1], edge_ids[2]);
-
- int main1 = -1, main2 = -1, side1 = -1, side2 = -1;
- int main_dir = 0;
-
- for (nei_idx = 0; nei_idx < 4; nei_idx++)
- {
- int stereo = getDir(atom_idx, edge_ids[nei_idx].nei_idx);
-
- if (stereo == BOND_UP || stereo == BOND_DOWN)
- {
- main1 = nei_idx;
- main_dir = stereo;
- break;
- }
- }
-
- if (main1 == -1)
- return false;
-
- if (zero_bond_length)
- throw Error("zero bond length near atom %d", atom_idx);
-
- if (n_pure_hydrogens > 1)
- throw Error("%d hydrogens near stereocenter %d", n_pure_hydrogens, atom_idx);
-
- int xyz1, xyz2;
-
- // find main2 as opposite to main1
- if (main2 == -1)
- {
- xyz1 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 1) % 4].vec, edge_ids[(main1 + 2) % 4].vec);
- xyz2 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 1) % 4].vec, edge_ids[(main1 + 3) % 4].vec);
-
- if (xyz1 + xyz2 == 3 || xyz1 + xyz2 == 12)
- {
- main2 = (main1 + 1) % 4;
- side1 = (main1 + 2) % 4;
- side2 = (main1 + 3) % 4;
- }
- }
- if (main2 == -1)
- {
- xyz1 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 2) % 4].vec, edge_ids[(main1 + 1) % 4].vec);
- xyz2 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 2) % 4].vec, edge_ids[(main1 + 3) % 4].vec);
-
- if (xyz1 + xyz2 == 3 || xyz1 + xyz2 == 12)
- {
- main2 = (main1 + 2) % 4;
- side1 = (main1 + 1) % 4;
- side2 = (main1 + 3) % 4;
- }
- }
- if (main2 == -1)
+ if (is_either)
{
- xyz1 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 3) % 4].vec, edge_ids[(main1 + 1) % 4].vec);
- xyz2 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 3) % 4].vec, edge_ids[(main1 + 2) % 4].vec);
-
- if (xyz1 + xyz2 == 3 || xyz1 + xyz2 == 12)
+ stereocenter.type = ATOM_ANY;
+ for (int i = 0; i < degree; i++)
{
- main2 = (main1 + 3) % 4;
- side1 = (main1 + 2) % 4;
- side2 = (main1 + 1) % 4;
+ stereocenter.pyramid[i] = edge_ids[i].nei_idx;
+ if (getDir(atom_idx, edge_ids[i].nei_idx) > 0)
+ sensible_bonds_out[edge_ids[i].edge_idx] = 1;
}
}
-
- if (main2 == -1)
- throw Error("internal error: can not find opposite bond near atom %d", atom_idx);
-
- if (main_dir == BOND_UP && getDir(atom_idx, edge_ids[main2].nei_idx) == BOND_DOWN)
- throw Error("stereo types of the opposite bonds mismatch near atom %d", atom_idx);
- if (main_dir == BOND_DOWN && getDir(atom_idx, edge_ids[main2].nei_idx) == BOND_UP)
- throw Error("stereo types of the opposite bonds mismatch near atom %d", atom_idx);
-
- if (main_dir == getDir(atom_idx, edge_ids[side1].nei_idx))
- throw Error("stereo types of non-opposite bonds match near atom %d", atom_idx);
- if (main_dir == getDir(atom_idx, edge_ids[side2].nei_idx))
- throw Error("stereo types of non-opposite bonds match near atom %d", atom_idx);
-
- if (main1 == 3 || main2 == 3)
- last_atom_dir = main_dir;
- else
- last_atom_dir = (main_dir == BOND_UP ? BOND_DOWN : BOND_UP);
-
- int sign = _sign(edge_ids[0].vec, edge_ids[1].vec, edge_ids[2].vec);
-
- if ((last_atom_dir == BOND_UP && sign > 0) || (last_atom_dir == BOND_DOWN && sign < 0))
- {
- pyramid[0] = edge_ids[0].nei_idx;
- pyramid[1] = edge_ids[1].nei_idx;
- pyramid[2] = edge_ids[2].nei_idx;
- }
else
{
- pyramid[0] = edge_ids[0].nei_idx;
- pyramid[1] = edge_ids[2].nei_idx;
- pyramid[2] = edge_ids[1].nei_idx;
- }
-
- pyramid[3] = edge_ids[3].nei_idx;
- }
- else if (degree == 3)
- {
- // sort by neighbor atom index (ascending)
- if (edge_ids[0].rank > edge_ids[1].rank)
- std::swap(edge_ids[0], edge_ids[1]);
- if (edge_ids[1].rank > edge_ids[2].rank)
- std::swap(edge_ids[1], edge_ids[2]);
- if (edge_ids[0].rank > edge_ids[1].rank)
- std::swap(edge_ids[0], edge_ids[1]);
-
- bool degenerate = true;
- int dirs[3] = {0, 0, 0};
- int main_nei = -1; // will be assigned if all three neighors belong to the same half-plane
- int n_up = 0, n_down = 0;
-
- for (nei_idx = 0; nei_idx < 3; nei_idx++)
- {
- dirs[nei_idx] = getDir(atom_idx, edge_ids[nei_idx].nei_idx);
- if (dirs[nei_idx] == BOND_UP)
- n_up++;
- else if (dirs[nei_idx] == BOND_DOWN)
- n_down++;
- }
-
- if (n_down == 0 && n_up == 0)
- return false;
-
- for (nei_idx = 0; nei_idx < 3; nei_idx++)
- {
- int xyzzy = _xyzzy(edge_ids[(nei_idx + 1) % 3].vec, edge_ids[(nei_idx + 2) % 3].vec, edge_ids[nei_idx].vec);
-
- if (xyzzy == 1)
- main_nei = nei_idx;
- if (xyzzy == 2)
- degenerate = false;
- }
-
- int dir = 1;
-
- if (main_nei != -1)
- {
- if (dirs[main_nei] != 0)
+ if (degree == 4)
{
- if (dirs[(main_nei + 1) % 3] == dirs[main_nei] || dirs[(main_nei + 2) % 3] == dirs[main_nei])
- throw Error("directions of neighbor stereo bonds match near atom %d", atom_idx);
- if (dirs[main_nei] == BOND_UP)
- dir = -1;
+ // sort by neighbor atom index (ascending)
+ if (edge_ids[0].rank > edge_ids[1].rank)
+ std::swap(edge_ids[0], edge_ids[1]);
+ if (edge_ids[1].rank > edge_ids[2].rank)
+ std::swap(edge_ids[1], edge_ids[2]);
+ if (edge_ids[2].rank > edge_ids[3].rank)
+ std::swap(edge_ids[2], edge_ids[3]);
+ if (edge_ids[1].rank > edge_ids[2].rank)
+ std::swap(edge_ids[1], edge_ids[2]);
+ if (edge_ids[0].rank > edge_ids[1].rank)
+ std::swap(edge_ids[0], edge_ids[1]);
+ if (edge_ids[1].rank > edge_ids[2].rank)
+ std::swap(edge_ids[1], edge_ids[2]);
+
+ int main1 = -1, main2 = -1, side1 = -1, side2 = -1;
+ int main_dir = 0;
+
+ for (nei_idx = 0; nei_idx < 4; nei_idx++)
+ {
+ int stereo = getDir(atom_idx, edge_ids[nei_idx].nei_idx);
+
+ if (stereo == BOND_UP || stereo == BOND_DOWN)
+ {
+ main1 = nei_idx;
+ main_dir = stereo;
+ break;
+ }
+ }
+
+ if (main1 != -1)
+ {
+ if (zero_bond_length)
+ throw Error("zero bond length near atom %d", atom_idx);
+
+ if (n_pure_hydrogens > 1)
+ throw Error("%d hydrogens near stereocenter %d", n_pure_hydrogens, atom_idx);
+
+ int xyz1, xyz2;
+
+ // find main2 as opposite to main1
+ if (main2 == -1)
+ {
+ xyz1 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 1) % 4].vec, edge_ids[(main1 + 2) % 4].vec);
+ xyz2 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 1) % 4].vec, edge_ids[(main1 + 3) % 4].vec);
+
+ if (xyz1 + xyz2 == 3 || xyz1 + xyz2 == 12)
+ {
+ main2 = (main1 + 1) % 4;
+ side1 = (main1 + 2) % 4;
+ side2 = (main1 + 3) % 4;
+ }
+ }
+ if (main2 == -1)
+ {
+ xyz1 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 2) % 4].vec, edge_ids[(main1 + 1) % 4].vec);
+ xyz2 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 2) % 4].vec, edge_ids[(main1 + 3) % 4].vec);
+
+ if (xyz1 + xyz2 == 3 || xyz1 + xyz2 == 12)
+ {
+ main2 = (main1 + 2) % 4;
+ side1 = (main1 + 1) % 4;
+ side2 = (main1 + 3) % 4;
+ }
+ }
+ if (main2 == -1)
+ {
+ xyz1 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 3) % 4].vec, edge_ids[(main1 + 1) % 4].vec);
+ xyz2 = _xyzzy(edge_ids[main1].vec, edge_ids[(main1 + 3) % 4].vec, edge_ids[(main1 + 2) % 4].vec);
+
+ if (xyz1 + xyz2 == 3 || xyz1 + xyz2 == 12)
+ {
+ main2 = (main1 + 3) % 4;
+ side1 = (main1 + 2) % 4;
+ side2 = (main1 + 1) % 4;
+ }
+ }
+
+ if (main2 == -1)
+ throw Error("internal error: can not find opposite bond near atom %d", atom_idx);
+
+ if (main_dir == BOND_UP && getDir(atom_idx, edge_ids[main2].nei_idx) == BOND_DOWN)
+ throw Error("stereo types of the opposite bonds mismatch near atom %d", atom_idx);
+ if (main_dir == BOND_DOWN && getDir(atom_idx, edge_ids[main2].nei_idx) == BOND_UP)
+ throw Error("stereo types of the opposite bonds mismatch near atom %d", atom_idx);
+
+ if (main_dir == getDir(atom_idx, edge_ids[side1].nei_idx))
+ throw Error("stereo types of non-opposite bonds match near atom %d", atom_idx);
+ if (main_dir == getDir(atom_idx, edge_ids[side2].nei_idx))
+ throw Error("stereo types of non-opposite bonds match near atom %d", atom_idx);
+
+ if (main1 == 3 || main2 == 3)
+ last_atom_dir = main_dir;
+ else
+ last_atom_dir = (main_dir == BOND_UP ? BOND_DOWN : BOND_UP);
+
+ int sign = _sign(edge_ids[0].vec, edge_ids[1].vec, edge_ids[2].vec);
+
+ if ((last_atom_dir == BOND_UP && sign > 0) || (last_atom_dir == BOND_DOWN && sign < 0))
+ {
+ pyramid[0] = edge_ids[0].nei_idx;
+ pyramid[1] = edge_ids[1].nei_idx;
+ pyramid[2] = edge_ids[2].nei_idx;
+ }
+ else
+ {
+ pyramid[0] = edge_ids[0].nei_idx;
+ pyramid[1] = edge_ids[2].nei_idx;
+ pyramid[2] = edge_ids[1].nei_idx;
+ }
+
+ pyramid[3] = edge_ids[3].nei_idx;
+ }
+ else
+ stereocenter.is_tetrahydral = false;
}
- else
+ else if (degree == 3)
{
- int d1 = dirs[(main_nei + 1) % 3];
- int d2 = dirs[(main_nei + 2) % 3];
-
- if (d1 == 0)
- d1 = d2;
- else if (d2 != 0 && d1 != d2)
- throw Error("directions of opposite stereo bonds do not match near atom %d", atom_idx);
-
- if (d1 == 0)
- return false;
+ // sort by neighbor atom index (ascending)
+ if (edge_ids[0].rank > edge_ids[1].rank)
+ std::swap(edge_ids[0], edge_ids[1]);
+ if (edge_ids[1].rank > edge_ids[2].rank)
+ std::swap(edge_ids[1], edge_ids[2]);
+ if (edge_ids[0].rank > edge_ids[1].rank)
+ std::swap(edge_ids[0], edge_ids[1]);
+
+ bool degenerate = true;
+ int dirs[3] = {0, 0, 0};
+ int main_nei = -1; // will be assigned if all three neighors belong to the same half-plane
+ int n_up = 0, n_down = 0;
+
+ for (nei_idx = 0; nei_idx < 3; nei_idx++)
+ {
+ dirs[nei_idx] = getDir(atom_idx, edge_ids[nei_idx].nei_idx);
+ if (dirs[nei_idx] == BOND_UP)
+ n_up++;
+ else if (dirs[nei_idx] == BOND_DOWN)
+ n_down++;
+ }
- if (d1 == BOND_DOWN)
- dir = -1;
+ if (n_down || n_up)
+ {
+ for (nei_idx = 0; nei_idx < 3; nei_idx++)
+ {
+ int xyzzy = _xyzzy(edge_ids[(nei_idx + 1) % 3].vec, edge_ids[(nei_idx + 2) % 3].vec, edge_ids[nei_idx].vec);
+
+ if (xyzzy == 1)
+ main_nei = nei_idx;
+ if (xyzzy == 2)
+ degenerate = false;
+ }
+
+ int dir = 1;
+
+ if (main_nei != -1)
+ {
+ if (dirs[main_nei] != 0)
+ {
+ if (dirs[(main_nei + 1) % 3] == dirs[main_nei] || dirs[(main_nei + 2) % 3] == dirs[main_nei])
+ throw Error("directions of neighbor stereo bonds match near atom %d", atom_idx);
+ if (dirs[main_nei] == BOND_UP)
+ dir = -1;
+ }
+ else
+ {
+ int d1 = dirs[(main_nei + 1) % 3];
+ int d2 = dirs[(main_nei + 2) % 3];
+
+ if (d1 == 0)
+ d1 = d2;
+ else if (d2 != 0 && d1 != d2)
+ throw Error("directions of opposite stereo bonds do not match near atom %d", atom_idx);
+
+ if (d1 == 0)
+ return false;
+
+ if (d1 == BOND_DOWN)
+ dir = -1;
+ }
+ }
+ else if (!degenerate)
+ {
+ if (n_down > 0 && n_up > 0)
+ throw Error("one bond up, one bond down -- indefinite case near atom %d", atom_idx);
+
+ if (!possible_lone_pair)
+ {
+ if (n_up == 3)
+ throw Error("all 3 bonds up near stereoatom %d", atom_idx);
+ if (n_down == 3)
+ throw Error("all 3 bonds down near stereoatom %d", atom_idx);
+ }
+ if (n_down > 0)
+ dir = -1;
+ }
+ else
+ throw Error("degenerate case for 3 bonds near stereoatom %d", atom_idx);
+
+ if (zero_bond_length)
+ throw Error("zero bond length near atom %d", atom_idx);
+
+ if (n_pure_hydrogens > 0 && !possible_lone_pair)
+ throw Error("have hydrogen(s) besides implicit hydrogen near stereocenter %d", atom_idx);
+
+ int sign = _sign(edge_ids[0].vec, edge_ids[1].vec, edge_ids[2].vec);
+
+ if (sign == dir)
+ {
+ pyramid[0] = edge_ids[0].nei_idx;
+ pyramid[1] = edge_ids[2].nei_idx;
+ pyramid[2] = edge_ids[1].nei_idx;
+ }
+ else
+ {
+ pyramid[0] = edge_ids[0].nei_idx;
+ pyramid[1] = edge_ids[1].nei_idx;
+ pyramid[2] = edge_ids[2].nei_idx;
+ }
+ pyramid[3] = -1;
+ }
+ else
+ stereocenter.is_tetrahydral = false;
}
- }
- else if (!degenerate)
- {
- if (n_down > 0 && n_up > 0)
- throw Error("one bond up, one bond down -- indefinite case near atom %d", atom_idx);
- if (!possible_lone_pair)
- {
- if (n_up == 3)
- throw Error("all 3 bonds up near stereoatom %d", atom_idx);
- if (n_down == 3)
- throw Error("all 3 bonds down near stereoatom %d", atom_idx);
- }
- if (n_down > 0)
- dir = -1;
+ if (stereocenter.is_tetrahydral)
+ for (int i = 0; i < degree; i++)
+ if (getDir(atom_idx, edge_ids[i].nei_idx) > 0)
+ sensible_bonds_out[edge_ids[i].edge_idx] = 1;
}
- else
- throw Error("degenerate case for 3 bonds near stereoatom %d", atom_idx);
-
- if (zero_bond_length)
- throw Error("zero bond length near atom %d", atom_idx);
-
- if (n_pure_hydrogens > 0 && !possible_lone_pair)
- throw Error("have hydrogen(s) besides implicit hydrogen near stereocenter %d", atom_idx);
-
- int sign = _sign(edge_ids[0].vec, edge_ids[1].vec, edge_ids[2].vec);
+ }
- if (sign == dir)
+ if (stereocenter.is_tetrahydral)
+ {
+ if (_stereocenters.find(atom_idx))
{
- pyramid[0] = edge_ids[0].nei_idx;
- pyramid[1] = edge_ids[2].nei_idx;
- pyramid[2] = edge_ids[1].nei_idx;
+ auto& sc = _stereocenters.at(atom_idx);
+ sc.is_tetrahydral = true;
+ std::copy(std::begin(stereocenter.pyramid), std::end(stereocenter.pyramid), std::begin(sc.pyramid));
}
else
- {
- pyramid[0] = edge_ids[0].nei_idx;
- pyramid[1] = edge_ids[1].nei_idx;
- pyramid[2] = edge_ids[2].nei_idx;
- }
- pyramid[3] = -1;
+ _stereocenters.insert(atom_idx, stereocenter);
+ return true;
}
-
- for (i = 0; i < degree; i++)
- if (getDir(atom_idx, edge_ids[i].nei_idx) > 0)
- sensible_bonds_out[edge_ids[i].edge_idx] = 1;
-
- _stereocenters.insert(atom_idx, stereocenter);
- return true;
+ return false;
}
// 1 -- in the smaller angle, 2 -- in the bigger angle,
-// 4 -- in the 'positive' straight angle, 8 -- in the 'negative' straight angle
+// 4 -- in t5he 'positive' straight angle, 8 -- in the 'negative' straight angle
int MoleculeStereocenters::_xyzzy(const Vec3f& v1, const Vec3f& v2, const Vec3f& u)
{
const float eps = 1e-3f;
@@ -713,11 +877,21 @@ void MoleculeStereocenters::setAtropisomeric(int idx, bool val)
_stereocenters.at(idx).is_atropisomeric = val;
}
-bool MoleculeStereocenters::isAtropisomeric(int idx)
+bool MoleculeStereocenters::isAtropisomeric(int idx) const
{
return _stereocenters.at(idx).is_atropisomeric;
}
+void MoleculeStereocenters::setTetrahydral(int idx, bool val)
+{
+ _stereocenters.at(idx).is_tetrahydral = val;
+}
+
+bool MoleculeStereocenters::isTetrahydral(int idx) const
+{
+ return _stereocenters.at(idx).is_tetrahydral;
+}
+
const int* MoleculeStereocenters::getPyramid(int idx) const
{
return _stereocenters.at(idx).pyramid;
@@ -912,7 +1086,7 @@ bool MoleculeStereocenters::checkSub(BaseMolecule& query, BaseMolecule& target,
if (stereocenters_vertex_filter != 0 && !stereocenters_vertex_filter->valid(iq))
continue;
- if (cq.type < ATOM_AND)
+ if (cq.type < ATOM_AND || !cq.is_tetrahydral)
continue;
int stereo_group_and = -1;
@@ -1229,41 +1403,61 @@ void MoleculeStereocenters::buildOnSubmolecule(BaseMolecule& baseMolecule, const
new_stereocenter.group = super_stereocenter.group;
new_stereocenter.type = super_stereocenter.type;
+ new_stereocenter.is_atropisomeric = super_stereocenter.is_atropisomeric;
+ new_stereocenter.is_tetrahydral = super_stereocenter.is_tetrahydral;
- for (j = 0; j < 4; j++)
+ // copy tetrahydral center
+ if (new_stereocenter.is_tetrahydral)
{
- int idx = super_stereocenter.pyramid[j];
-
- if (idx == -1)
- new_stereocenter.pyramid[j] = -1;
- else
+ for (j = 0; j < 4; j++)
{
- int val = mapping[idx];
- if (val != -1 && baseMolecule.findEdgeIndex(sub_idx, val) == -1)
- val = -1;
- new_stereocenter.pyramid[j] = val;
- }
- }
+ int idx = super_stereocenter.pyramid[j];
- moveMinimalToEnd(new_stereocenter.pyramid);
- if (new_stereocenter.pyramid[0] == -1 || new_stereocenter.pyramid[1] == -1 || new_stereocenter.pyramid[2] == -1)
- // pyramid is not mapped completely
- continue;
+ if (idx == -1)
+ new_stereocenter.pyramid[j] = -1;
+ else
+ {
+ int val = mapping[idx];
+ if (val != -1 && baseMolecule.findEdgeIndex(sub_idx, val) == -1)
+ val = -1;
+ new_stereocenter.pyramid[j] = val;
+ }
+ }
- _stereocenters.insert(sub_idx, new_stereocenter);
+ moveMinimalToEnd(new_stereocenter.pyramid);
+ // copy bond directions for tetrahydral center
+ const Vertex& super_vertex = super.getVertex(super_idx);
+ for (j = super_vertex.neiBegin(); j != super_vertex.neiEnd(); j = super_vertex.neiNext(j))
+ {
+ int super_edge = super_vertex.neiEdge(j);
+ if (mapping[super_vertex.neiVertex(j)] == -1)
+ continue;
- const Vertex& super_vertex = super.getVertex(super_idx);
+ int bdir = super.getBondDirection(super_edge);
+ if (bdir)
+ baseMolecule.setBondDirection(baseMolecule.findEdgeIndex(sub_idx, mapping[super_vertex.neiVertex(j)]), bdir);
+ }
+ }
- for (j = super_vertex.neiBegin(); j != super_vertex.neiEnd(); j = super_vertex.neiNext(j))
+ // copy atropocenter
+ if (new_stereocenter.is_atropisomeric && super.stereocenters._atropocenters.find(super_idx))
{
- int super_edge = super_vertex.neiEdge(j);
- if (mapping[super_vertex.neiVertex(j)] == -1)
- continue;
-
- int dir = super.getBondDirection(super_edge);
- if (dir != 0)
- baseMolecule.setBondDirection(baseMolecule.findEdgeIndex(sub_idx, mapping[super_vertex.neiVertex(j)]), dir);
+ const auto& ac_super = super.stereocenters._atropocenters.at(super_idx);
+ auto& ac_new = baseMolecule.stereocenters._atropocenters.findOrInsert(sub_idx);
+ const auto& e = super.getEdge(ac_super.atropo_bond);
+ ac_new.atropo_bond = baseMolecule.findEdgeIndex(mapping[e.beg], mapping[e.end]);
+ // copy bond directions for atropisomeric center
+ ac_new.bond_directions.clear();
+ for (j = ac_super.bond_directions.begin(); j != ac_super.bond_directions.end(); j = ac_super.bond_directions.next(j))
+ {
+ const auto& atropo_edge = super.getEdge(ac_super.bond_directions.key(j));
+ int atropo_edge_idx = baseMolecule.findEdgeIndex(mapping[atropo_edge.beg], mapping[atropo_edge.end]);
+ int bdir = ac_super.bond_directions.value(j);
+ ac_new.bond_directions.insert(atropo_edge_idx, bdir);
+ baseMolecule.setBondDirection(atropo_edge_idx, bdir);
+ }
}
+ _stereocenters.insert(sub_idx, new_stereocenter);
}
}
@@ -1546,143 +1740,167 @@ void MoleculeStereocenters::markBond(BaseMolecule& baseMolecule, int atom_idx)
return;
const _Atom& atom = *atom_ptr;
- int pyramid[4];
- int mult = 1;
- int size = 0;
- int j;
- memcpy(pyramid, atom.pyramid, 4 * sizeof(int));
-
- const Vertex& vertex = baseMolecule.getVertex(atom_idx);
- if (atom.type <= ATOM_ANY)
+ if (atom.is_tetrahydral)
{
- // fill the pyramid
- for (j = vertex.neiBegin(); j != vertex.neiEnd() && size < 4; j = vertex.neiNext(j))
- pyramid[size++] = vertex.neiVertex(j);
- }
- else
- size = (pyramid[3] == -1 ? 3 : 4);
+ int pyramid[4];
+ int mult = 1;
+ int size = 0;
+ int j;
- // clear bond directions that goes to this atom, and not from this atom because they can
- // be marked by other sterecenter
- for (j = vertex.neiBegin(); j != vertex.neiEnd(); j = vertex.neiNext(j))
- if (baseMolecule.getBondDirection2(atom_idx, vertex.neiVertex(j)) != 0)
- baseMolecule.setBondDirection(vertex.neiEdge(j), 0);
+ memcpy(pyramid, atom.pyramid, 4 * sizeof(int));
- int edge_idx = -1;
+ const Vertex& vertex = baseMolecule.getVertex(atom_idx);
+ if (atom.type <= ATOM_ANY)
+ {
+ // fill the pyramid
+ for (j = vertex.neiBegin(); j != vertex.neiEnd() && size < 4; j = vertex.neiNext(j))
+ pyramid[size++] = vertex.neiVertex(j);
+ }
+ else
+ size = (pyramid[3] == -1 ? 3 : 4);
- for (j = 0; j < size; j++)
- {
- edge_idx = baseMolecule.findEdgeIndex(atom_idx, pyramid[size - 1]);
- if (baseMolecule.getBondDirection(edge_idx) == 0 && baseMolecule.getVertex(pyramid[size - 1]).degree() == 1)
- break;
- rotatePyramid(pyramid);
- if (size == 4)
- mult = -mult;
- }
+ // clear bond directions that goes to this atom, and not from this atom because they can
+ // be marked by other sterecenter
+ for (j = vertex.neiBegin(); j != vertex.neiEnd(); j = vertex.neiNext(j))
+ if (baseMolecule.getBondDirection2(atom_idx, vertex.neiVertex(j)) != 0)
+ baseMolecule.setBondDirection(vertex.neiEdge(j), 0);
+
+ int edge_idx = -1;
- if (j == size)
- {
for (j = 0; j < size; j++)
{
edge_idx = baseMolecule.findEdgeIndex(atom_idx, pyramid[size - 1]);
- if (baseMolecule.getBondDirection(edge_idx) == 0 && baseMolecule.getBondTopology(edge_idx) == TOPOLOGY_CHAIN && getType(pyramid[size - 1]) == 0)
+ if (baseMolecule.getBondDirection(edge_idx) == 0 && baseMolecule.getVertex(pyramid[size - 1]).degree() == 1)
break;
rotatePyramid(pyramid);
if (size == 4)
mult = -mult;
}
- }
- if (j == size)
- {
- for (j = 0; j < size; j++)
+ if (j == size)
{
- edge_idx = baseMolecule.findEdgeIndex(atom_idx, pyramid[size - 1]);
- if (baseMolecule.getBondDirection(edge_idx) == 0 && getType(pyramid[size - 1]) == 0)
- break;
- rotatePyramid(pyramid);
- if (size == 4)
- mult = -mult;
+ for (j = 0; j < size; j++)
+ {
+ edge_idx = baseMolecule.findEdgeIndex(atom_idx, pyramid[size - 1]);
+ if (baseMolecule.getBondDirection(edge_idx) == 0 && baseMolecule.getBondTopology(edge_idx) == TOPOLOGY_CHAIN && getType(pyramid[size - 1]) == 0)
+ break;
+ rotatePyramid(pyramid);
+ if (size == 4)
+ mult = -mult;
+ }
}
- }
- if (j == size)
- {
- for (j = 0; j < size; j++)
+ if (j == size)
{
- edge_idx = baseMolecule.findEdgeIndex(atom_idx, pyramid[size - 1]);
- if (baseMolecule.getBondDirection(edge_idx) == 0 && baseMolecule.getBondTopology(edge_idx) == TOPOLOGY_CHAIN)
- break;
- rotatePyramid(pyramid);
- if (size == 4)
- mult = -mult;
+ for (j = 0; j < size; j++)
+ {
+ edge_idx = baseMolecule.findEdgeIndex(atom_idx, pyramid[size - 1]);
+ if (baseMolecule.getBondDirection(edge_idx) == 0 && getType(pyramid[size - 1]) == 0)
+ break;
+ rotatePyramid(pyramid);
+ if (size == 4)
+ mult = -mult;
+ }
}
- }
- if (j == size)
- {
- for (j = 0; j < size; j++)
+ if (j == size)
{
- edge_idx = baseMolecule.findEdgeIndex(atom_idx, pyramid[size - 1]);
- if (baseMolecule.getBondDirection(edge_idx) == 0)
- break;
- rotatePyramid(pyramid);
- if (size == 4)
- mult = -mult;
+ for (j = 0; j < size; j++)
+ {
+ edge_idx = baseMolecule.findEdgeIndex(atom_idx, pyramid[size - 1]);
+ if (baseMolecule.getBondDirection(edge_idx) == 0 && baseMolecule.getBondTopology(edge_idx) == TOPOLOGY_CHAIN)
+ break;
+ rotatePyramid(pyramid);
+ if (size == 4)
+ mult = -mult;
+ }
}
- }
-
- if (j == size)
- throw Error("no bond can be marked");
-
- if (baseMolecule.getEdge(edge_idx).beg != atom_idx)
- baseMolecule.swapEdgeEnds(edge_idx);
- if (atom.type > ATOM_ANY)
- {
- std::array dirs;
- dirs.fill({0.0, 0.0, 0.0});
- for (j = 0; j < size; j++)
+ if (j == size)
{
- dirs[j] = baseMolecule.getAtomXyz(pyramid[j]);
- dirs[j].sub(baseMolecule.getAtomXyz(atom_idx));
- if (!dirs[j].normalize())
- throw Error("zero bond length");
+ for (j = 0; j < size; j++)
+ {
+ edge_idx = baseMolecule.findEdgeIndex(atom_idx, pyramid[size - 1]);
+ if (baseMolecule.getBondDirection(edge_idx) == 0)
+ break;
+ rotatePyramid(pyramid);
+ if (size == 4)
+ mult = -mult;
+ }
}
- int sign = _sign(dirs[0], dirs[1], dirs[2]);
+ if (j == size)
+ throw Error("no bond can be marked");
- if (size == 3)
+ if (baseMolecule.getEdge(edge_idx).beg != atom_idx)
+ baseMolecule.swapEdgeEnds(edge_idx);
+
+ if (BaseMolecule::hasCoord(baseMolecule))
{
- // Check if all the three bonds belong to the same half-plane.
- // This is equal to that one of the bonds lies in the smaller
- // angle formed by the other two.
- if (_xyzzy(dirs[1], dirs[0], dirs[2]) == 1 || _xyzzy(dirs[2], dirs[1], dirs[0]) == 1 || _xyzzy(dirs[0], dirs[2], dirs[1]) == 1)
+ if (atom.type > ATOM_ANY)
{
- if (_xyzzy(dirs[1], dirs[0], dirs[2]) == 1)
- mult = -1;
- baseMolecule.setBondDirection(edge_idx, (sign * mult == 1) ? BOND_DOWN : BOND_UP);
+ std::array dirs;
+ dirs.fill({0.0, 0.0, 0.0});
+ for (j = 0; j < size; j++)
+ {
+ dirs[j] = baseMolecule.getAtomXyz(pyramid[j]);
+ dirs[j].sub(baseMolecule.getAtomXyz(atom_idx));
+ if (!dirs[j].normalize())
+ throw Error("zero bond length");
+ }
+
+ int sign = _sign(dirs[0], dirs[1], dirs[2]);
+
+ if (size == 3)
+ {
+ // Check if all the three bonds belong to the same half-plane.
+ // This is equal to that one of the bonds lies in the smaller
+ // angle formed by the other two.
+ if (_xyzzy(dirs[1], dirs[0], dirs[2]) == 1 || _xyzzy(dirs[2], dirs[1], dirs[0]) == 1 || _xyzzy(dirs[0], dirs[2], dirs[1]) == 1)
+ {
+ if (_xyzzy(dirs[1], dirs[0], dirs[2]) == 1)
+ mult = -1;
+ baseMolecule.setBondDirection(edge_idx, (sign * mult == 1) ? BOND_DOWN : BOND_UP);
+ }
+ else
+ baseMolecule.setBondDirection(edge_idx, (sign == 1) ? BOND_DOWN : BOND_UP);
+ }
+ else
+ baseMolecule.setBondDirection(edge_idx, (sign * mult == 1) ? BOND_UP : BOND_DOWN);
}
else
- baseMolecule.setBondDirection(edge_idx, (sign == 1) ? BOND_DOWN : BOND_UP);
+ baseMolecule.setBondDirection(edge_idx, BOND_EITHER);
}
- else
- baseMolecule.setBondDirection(edge_idx, (sign * mult == 1) ? BOND_UP : BOND_DOWN);
}
- else
- baseMolecule.setBondDirection(edge_idx, BOND_EITHER);
}
-void MoleculeStereocenters::markBonds(BaseMolecule& baseMolecule)
+void MoleculeStereocenters::markAtropisomericBond(BaseMolecule& baseMolecule, int atom_idx)
{
- for (int i = _stereocenters.begin(); i != _stereocenters.end(); i = _stereocenters.next(i))
+ const _Atom* atom_ptr = _stereocenters.at2(atom_idx);
+ if (atom_ptr == NULL)
+ return;
+ const _Atom& atom = *atom_ptr;
+ if (atom.is_atropisomeric)
{
- if (!_stereocenters.value(i).is_atropisomeric)
- markBond(baseMolecule, _stereocenters.key(i));
+ const auto& ac = _atropocenters.at(atom_idx);
+ for (int i = ac.bond_directions.begin(); i != ac.bond_directions.end(); i = ac.bond_directions.next(i))
+ {
+ int bond_idx = ac.bond_directions.key(i);
+ int bdir = ac.bond_directions.value(i);
+ baseMolecule.setBondDirection(bond_idx, bdir);
+ }
}
}
+void MoleculeStereocenters::markBonds(BaseMolecule& baseMolecule)
+{
+ for (int i = _stereocenters.begin(); i != _stereocenters.end(); i = _stereocenters.next(i))
+ markBond(baseMolecule, _stereocenters.key(i));
+ for (int i = _stereocenters.begin(); i != _stereocenters.end(); i = _stereocenters.next(i))
+ markAtropisomericBond(baseMolecule, _stereocenters.key(i));
+}
+
bool MoleculeStereocenters::isAutomorphism(BaseMolecule& mol, const Array& mapping, const Filter* filter)
{
MoleculeStereocenters& stereocenters = mol.stereocenters;
diff --git a/core/indigo-core/molecule/src/molfile_loader.cpp b/core/indigo-core/molecule/src/molfile_loader.cpp
index 970357a451..6384e76abf 100644
--- a/core/indigo-core/molecule/src/molfile_loader.cpp
+++ b/core/indigo-core/molecule/src/molfile_loader.cpp
@@ -57,9 +57,7 @@ void MolfileLoader::loadMolecule(Molecule& mol)
_mol = &mol;
_qmol = 0;
_loadMolecule();
-
mol.setIgnoreBadValenceFlag(ignore_bad_valence);
-
if (mol.stereocenters.size() == 0 && !skip_3d_chirality)
mol.buildFrom3dCoordinatesStereocenters(stereochemistry_options);
}
@@ -2063,12 +2061,7 @@ void MolfileLoader::_postLoad()
{
if (_bmol->stereocenters.getType(i) == 0)
{
- if (_bmol->isAtropisomerismReferenceAtom(i))
- {
- _bmol->stereocenters.add_ignore(*_bmol, i, _stereocenter_types[i], _stereocenter_groups[i], false);
- _bmol->stereocenters.setAtropisomeric(i, true);
- }
- else if (!stereochemistry_options.ignore_errors)
+ if (!stereochemistry_options.ignore_errors)
throw Error("stereo type specified for atom #%d, but the bond "
"directions does not say that it is a stereocenter",
i);
@@ -2077,14 +2070,16 @@ void MolfileLoader::_postLoad()
_bmol->stereocenters.setType(i, _stereocenter_types[i], _stereocenter_groups[i]);
}
+ _bmol->buildCisTrans(_ignore_cistrans.ptr());
+
for (i = 0; i < _bonds_num; i++)
- if (_bmol->getBondDirection(i) > 0 && !_sensible_bond_directions[i])
+ {
+ if (_bmol->getBondDirection(i) && !_sensible_bond_directions[i])
{
if (!stereochemistry_options.ignore_errors)
throw Error("direction of bond #%d makes no sense", i);
}
-
- _bmol->buildCisTrans(_ignore_cistrans.ptr());
+ }
// Remove adding default R-group logic behavior
/*
diff --git a/core/indigo-core/molecule/src/molfile_saver.cpp b/core/indigo-core/molecule/src/molfile_saver.cpp
index c39f250ff1..36e632edf5 100644
--- a/core/indigo-core/molecule/src/molfile_saver.cpp
+++ b/core/indigo-core/molecule/src/molfile_saver.cpp
@@ -1910,7 +1910,7 @@ void MolfileSaver::_checkSGroupIndices(BaseMolecule& mol, Array& sgs_list)
int MolfileSaver::_getStereocenterParity(BaseMolecule& mol, int idx)
{
int type = mol.stereocenters.getType(idx);
- if (type == 0)
+ if (type == 0 || !mol.stereocenters.isTetrahydral(idx))
return 0;
if (type == MoleculeStereocenters::ATOM_ANY)
return 3;
diff --git a/core/indigo-core/molecule/src/smiles_loader.cpp b/core/indigo-core/molecule/src/smiles_loader.cpp
index 71a519e3da..4e03d9144b 100644
--- a/core/indigo-core/molecule/src/smiles_loader.cpp
+++ b/core/indigo-core/molecule/src/smiles_loader.cpp
@@ -62,6 +62,7 @@ void SmilesLoader::loadMolecule(Molecule& mol)
_bmol = &mol;
_mol = &mol;
_qmol = 0;
+ _has_atom_coordinates = false;
_loadMolecule();
mol.setIgnoreBadValenceFlag(ignore_bad_valence);
@@ -317,6 +318,7 @@ void SmilesLoader::_readOtherStuff()
while (isdigit(_scanner.lookNext()))
{
int atom_idx = _scanner.readUnsigned();
+ // handle wiggly bonds
if (!wmode)
{
// This either bond can mark stereocenter or cis-trans double bond
@@ -326,7 +328,7 @@ void SmilesLoader::_readOtherStuff()
for (int nei : v.neighbors())
{
int edge_idx = v.neiEdge(nei);
- if (_bmol->getBondOrder(edge_idx) == BOND_DOUBLE)
+ if (_bmol->getBondOrder(edge_idx) == BOND_DOUBLE && _bmol->getBondTopology(edge_idx) != TOPOLOGY_RING)
{
cis_trans.ignore(edge_idx);
found = true;
@@ -335,16 +337,11 @@ void SmilesLoader::_readOtherStuff()
if (!found)
{
- if (!_bmol->isPossibleStereocenter(atom_idx))
- {
- if (!stereochemistry_options.ignore_errors)
- throw Error("chirality not possible on atom #%d", atom_idx);
- }
- else
+ if (_bmol->isPossibleStereocenter(atom_idx))
{
// Check if the stereocenter has already been marked as any
// For example [H]C1(O)c2ccnn2[C@@H](O)c2ccnn12 |r,w:1.0,1.1|
- if (_bmol->stereocenters.getType(atom_idx) != MoleculeStereocenters::ATOM_ANY)
+ if (!_bmol->stereocenters.exists(atom_idx))
_bmol->addStereocenters(atom_idx, MoleculeStereocenters::ATOM_ANY, 0, false);
}
}
@@ -354,21 +351,16 @@ void SmilesLoader::_readOtherStuff()
{
_scanner.skip(1);
auto bond_idx = _scanner.readUnsigned();
- if (wmode)
+ if (!_has_directions_on_rings)
+ _has_directions_on_rings = _bmol->getBondTopology(bond_idx) == TOPOLOGY_RING;
+ if (bond_idx < _bmol->edgeCount() && atom_idx < _bmol->vertexCount())
{
auto& v = _bmol->getEdge(bond_idx);
if (v.end == atom_idx)
_bmol->swapEdgeEnds(bond_idx);
+
if (v.beg == atom_idx)
- {
- _bmol->setBondDirection(bond_idx, wmode == 'U' ? BOND_UP : BOND_DOWN);
- if (_bmol->isAtropisomerismReferenceAtom(atom_idx))
- {
- if (!_bmol->stereocenters.exists(atom_idx))
- _bmol->addStereocenters(atom_idx, MoleculeStereocenters::ATOM_ANY, 0, false);
- _bmol->stereocenters.setAtropisomeric(atom_idx, true);
- }
- }
+ _bmol->setBondDirection(bond_idx, wmode == 'U' ? BOND_UP : (wmode == 'D' ? BOND_DOWN : BOND_EITHER));
}
}
@@ -391,7 +383,10 @@ void SmilesLoader::_readOtherStuff()
_overtly_defined_abs.insert(idx);
}
else
+ {
_bmol->addStereocenters(idx, MoleculeStereocenters::ATOM_ABS, 0, false);
+ _bmol->stereocenters.setTetrahydral(idx, false);
+ }
if (_scanner.lookNext() == ',')
_scanner.skip(1);
@@ -411,7 +406,10 @@ void SmilesLoader::_readOtherStuff()
if (_bmol->stereocenters.exists(idx))
_bmol->stereocenters.setType(idx, MoleculeStereocenters::ATOM_OR, groupno);
else
+ {
_bmol->addStereocenters(idx, MoleculeStereocenters::ATOM_OR, groupno, false);
+ _bmol->stereocenters.setTetrahydral(idx, false);
+ }
if (_scanner.lookNext() == ',')
_scanner.skip(1);
@@ -430,8 +428,10 @@ void SmilesLoader::_readOtherStuff()
if (_bmol->stereocenters.exists(idx))
_bmol->stereocenters.setType(idx, MoleculeStereocenters::ATOM_AND, groupno);
else
+ {
_bmol->addStereocenters(idx, MoleculeStereocenters::ATOM_AND, groupno, false);
-
+ _bmol->stereocenters.setTetrahydral(idx, false);
+ }
if (_scanner.lookNext() == ',')
_scanner.skip(1);
}
@@ -752,8 +752,7 @@ void SmilesLoader::_readOtherStuff()
}
if (_scanner.readChar() != ')')
throw Error("expected ')' after coordinates");
- _bmol->markBondsStereocenters();
- _bmol->markBondsAlleneStereo();
+ _has_atom_coordinates = true;
}
else if (c == 'h') // highlighting (Indigo's own extension)
{
@@ -1345,11 +1344,9 @@ void SmilesLoader::_validateStereoCenters()
for (int i = _bmol->stereocenters.begin(); i < _bmol->stereocenters.end(); i = _bmol->stereocenters.next(i))
{
auto atom_idx = _bmol->stereocenters.getAtomIndex(i);
- if (_bmol->isPossibleStereocenter(atom_idx) || _bmol->isAtropisomerismReferenceAtom(atom_idx))
+ if (_bmol->isPossibleStereocenter(atom_idx) || _bmol->stereocenters.isAtropisomeric(atom_idx))
continue;
- if (stereochemistry_options.ignore_errors)
- _bmol->stereocenters.remove(i);
- else
+ if (!stereochemistry_options.ignore_errors)
throw Error("atom %d is not a stereocenter", atom_idx);
}
}
@@ -1928,6 +1925,14 @@ void SmilesLoader::_loadParsedMolecule()
{
_scanner.skip(1);
_readOtherStuff();
+ if (_has_atom_coordinates || _has_directions_on_rings)
+ {
+ std::vector sensible_bond_directions;
+ sensible_bond_directions.resize(_bmol->edgeCount());
+ _bmol->buildFromBondsStereocenters(stereochemistry_options, sensible_bond_directions.data());
+ _bmol->markBondsStereocenters();
+ _bmol->markBondsAlleneStereo();
+ }
}
// Update attachment orders for rsites
diff --git a/core/indigo-core/molecule/src/smiles_saver.cpp b/core/indigo-core/molecule/src/smiles_saver.cpp
index f0ce525217..c75b660e98 100644
--- a/core/indigo-core/molecule/src/smiles_saver.cpp
+++ b/core/indigo-core/molecule/src/smiles_saver.cpp
@@ -27,6 +27,7 @@
#include "molecule/molecule.h"
#include "molecule/molecule_rgroups.h"
#include "molecule/molecule_savers.h"
+#include "molecule/molecule_stereocenter_options.h"
#include "molecule/molecule_stereocenters.h"
#include "molecule/query_molecule.h"
@@ -262,7 +263,7 @@ void SmilesSaver::_saveMolecule()
stereocenters.get(i, atom_idx, type, group, pyramid);
- if (type < MoleculeStereocenters::ATOM_AND || stereocenters.isAtropisomeric(atom_idx))
+ if (type < MoleculeStereocenters::ATOM_AND || !stereocenters.isTetrahydral(atom_idx))
continue;
int implicit_h_idx = -1;
@@ -384,7 +385,7 @@ void SmilesSaver::_saveMolecule()
int idx = _written_atoms[i];
- if (_atoms[idx].chirality == 0)
+ if (_atoms[idx].chirality == 0 || !stereocenters.isTetrahydral(idx))
continue;
int type = stereocenters.getType(idx);
@@ -625,7 +626,8 @@ void SmilesSaver::_saveMolecule()
_writeRingBonds();
_writeUnsaturated();
_writeSubstitutionCounts();
- _writeWedges();
+ if (_bmol->hasAtropoStereoBonds())
+ _writeWedges();
if (_comma)
_output.writeChar('|');
@@ -1500,7 +1502,6 @@ void SmilesSaver::_writeStereogroups()
{
int atom, type, group;
stereocenters.get(i, atom, type, group, 0);
-
if (type != MoleculeStereocenters::ATOM_ABS)
break;
}
@@ -1838,35 +1839,69 @@ void SmilesSaver::_writeSubstitutionCounts()
}
}
-void SmilesSaver::_writeWedges()
+void SmilesSaver::_writeBondDirs(const std::string& tag, const std::vector>& bonds)
{
bool is_first = true;
+ for (const auto& kvp : bonds)
+ {
+ if (is_first)
+ {
+ _startExtension();
+ _output.writeString(tag.c_str());
+ is_first = false;
+ }
+ else
+ _output.writeString(",");
+ _output.printf("%d.%d", kvp.first, kvp.second);
+ }
+}
+void SmilesSaver::_writeWedges()
+{
if (_bmol)
{
+ std::vector> down_dirs, up_dirs, wiggy_dirs;
for (int i = 0; i < _written_bonds.size(); ++i)
{
auto bond_idx = _written_bonds[i];
auto& e = _bmol->getEdge(bond_idx);
- if (_bmol->stereocenters.exists(e.beg) && _bmol->stereocenters.isAtropisomeric(e.beg))
+ auto bdir = _bmol->getBondDirection(bond_idx);
+ if (bdir)
{
- auto bdir = _bmol->getBondDirection(bond_idx);
- if (bdir && bdir < BOND_EITHER)
+ const auto& edge = _bmol->getEdge(bond_idx);
+ auto wa_idx = _written_atoms.find(edge.beg);
+ switch (bdir)
{
- if (is_first)
- {
- _startExtension();
- _output.writeString(bdir == BOND_UP ? "wU:" : "wD:");
- is_first = false;
- }
- else
- _output.writeString(",");
- const auto& edge = _bmol->getEdge(bond_idx);
- auto wa_idx = _written_atoms.find(edge.beg);
- _output.printf("%d.%d", wa_idx, i);
+ case BOND_UP:
+ up_dirs.emplace_back(wa_idx, i);
+ break;
+ case BOND_DOWN:
+ down_dirs.emplace_back(wa_idx, i);
+ break;
+ case BOND_EITHER:
+ wiggy_dirs.emplace_back(wa_idx, i);
+ break;
}
}
}
+
+ _writeBondDirs("wU:", up_dirs);
+ _writeBondDirs("wD:", down_dirs);
+ _writeBondDirs("w:", wiggy_dirs);
+
+ if ((down_dirs.size() || up_dirs.size() || wiggy_dirs.size()) && BaseMolecule::hasCoord(*_mol))
+ {
+ _output.writeString(",(");
+ for (int i = 0; i < _written_atoms.size(); ++i)
+ {
+ if (i)
+ _output.writeString(";");
+ auto atom_idx = _written_atoms[i];
+ const auto& pos = _mol->getAtomXyz(atom_idx);
+ _output.printf("%.2f,%.2f,", pos.x, pos.y);
+ }
+ _output.writeString(")");
+ }
}
}