diff --git a/api/tests/integration/ref/formats/custom_query.py.out b/api/tests/integration/ref/formats/custom_query.py.out index b74cda7718..e18909f816 100644 --- a/api/tests/integration/ref/formats/custom_query.py.out +++ b/api/tests/integration/ref/formats/custom_query.py.out @@ -2,3 +2,5 @@ [#6]1-[#6]=[#6]-[#6]=[#6]-[b;r;3;s&2,X3]=1 OK. Expected string found. **** #1331 wrong smarts for ring bond count as drawn **** ket_with_rb_as_drawn.ket OK. Smarts equals expected string '[#6](-[#6])(-[#6;x0])-[#6]' +**** #1337 wrong smarts for ring bond count as drawn **** +ket_with_custom_query_with_list.ket OK. Smarts equals expected string '[#6]1-[#6]=[Cl,Br,I,Na,O]-[#6]=[#6]-[#6]=1' diff --git a/api/tests/integration/tests/formats/custom_query.py b/api/tests/integration/tests/formats/custom_query.py index 7ce4565849..352ee17edb 100644 --- a/api/tests/integration/tests/formats/custom_query.py +++ b/api/tests/integration/tests/formats/custom_query.py @@ -45,3 +45,8 @@ def test_ket_to_smarts(filename, expected_str): ) print("**** #1331 wrong smarts for ring bond count as drawn ****") test_ket_to_smarts("ket_with_rb_as_drawn.ket", "[#6](-[#6])(-[#6;x0])-[#6]") + +print("**** #1337 wrong smarts for ring bond count as drawn ****") +fname = "ket_with_custom_query_with_list.ket" +expected = "[#6]1-[#6]=[Cl,Br,I,Na,O]-[#6]=[#6]-[#6]=1" +test_ket_to_smarts(fname, expected) diff --git a/api/tests/integration/tests/formats/ref/ket_with_custom_query_with_list.ket b/api/tests/integration/tests/formats/ref/ket_with_custom_query_with_list.ket new file mode 100644 index 0000000000..359b0b5b21 --- /dev/null +++ b/api/tests/integration/tests/formats/ref/ket_with_custom_query_with_list.ket @@ -0,0 +1,123 @@ +{ + "root": { + "nodes": [ + { + "$ref": "mol0" + } + ] + }, + "mol0": { + "type": "molecule", + "atoms": [ + { + "label": "C", + "location": [ + 6.3348493576049809, + -5.550074577331543, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 8.06515121459961, + -5.549589157104492, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 7.2016377449035648, + -5.049966812133789, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 8.06515121459961, + -6.55053186416626, + 0.0 + ] + }, + { + "label": "C", + "location": [ + 6.3348493576049809, + -6.555019855499268, + 0.0 + ] + }, + { + "label": "", + "location": [ + 7.203820705413818, + -7.050033092498779, + 0.0 + ], + "queryProperties": { + "customQuery": "Cl,Br,I,Na,O" + } + } + ], + "bonds": [ + { + "type": 2, + "atoms": [ + 2, + 0 + ] + }, + { + "type": 2, + "atoms": [ + 3, + 1 + ] + }, + { + "type": 1, + "atoms": [ + 0, + 4 + ] + }, + { + "type": 1, + "atoms": [ + 1, + 2 + ] + }, + { + "type": 2, + "atoms": [ + 4, + 5 + ] + }, + { + "type": 1, + "atoms": [ + 5, + 3 + ] + } + ], + "sgroups": [ + { + "type": "MUL", + "atoms": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "mul": 1 + } + ] + } +} \ No newline at end of file diff --git a/core/indigo-core/molecule/src/smiles_loader.cpp b/core/indigo-core/molecule/src/smiles_loader.cpp index c8e85dde01..ae61be37bf 100644 --- a/core/indigo-core/molecule/src/smiles_loader.cpp +++ b/core/indigo-core/molecule/src/smiles_loader.cpp @@ -2872,7 +2872,10 @@ void SmilesLoader::_readAtom(Array& atom_str, bool first_in_brackets, _Ato if (strchr("esfog", scanner.lookNext()) == NULL) { if (first_in_brackets) + { element = ELEM_H; + aromatic = ATOM_ALIPHATIC; + } else { atom.hydrogens = 1; @@ -2883,7 +2886,10 @@ void SmilesLoader::_readAtom(Array& atom_str, bool first_in_brackets, _Ato } } else + { element = Element::fromTwoChars('H', scanner.readChar()); + aromatic = ATOM_ALIPHATIC; + } } // The 'A' symbol is weird too. It can be the 'aliphatic' atomic primitive, // and can also be Al, Ar, As, Ag, Au, At, Ac, or Am. @@ -2899,7 +2905,10 @@ void SmilesLoader::_readAtom(Array& atom_str, bool first_in_brackets, _Ato subatom = std::make_unique(QueryMolecule::ATOM_AROMATICITY, ATOM_ALIPHATIC); } else + { element = Element::fromTwoChars('A', scanner.readChar()); + aromatic = ATOM_ALIPHATIC; + } } // Similarly, 'R' can start Rb, Ru, Rh, Re, Rn, Ra, Rf, Rg else if (next == 'R') @@ -2934,7 +2943,10 @@ void SmilesLoader::_readAtom(Array& atom_str, bool first_in_brackets, _Ato } } else + { element = Element::fromTwoChars('R', scanner.readChar()); + aromatic = ATOM_ALIPHATIC; + } } // Yet 'D' can start Db, Ds, Dy else if (next == 'D') @@ -2954,7 +2966,10 @@ void SmilesLoader::_readAtom(Array& atom_str, bool first_in_brackets, _Ato subatom = std::make_unique(QueryMolecule::ATOM_SUBSTITUENTS, degree); } else + { element = Element::fromTwoChars('D', scanner.readChar()); + aromatic = ATOM_ALIPHATIC; + } } // ... and 'X' can start Xe else if (next == 'X') @@ -2974,7 +2989,10 @@ void SmilesLoader::_readAtom(Array& atom_str, bool first_in_brackets, _Ato subatom = std::make_unique(QueryMolecule::ATOM_CONNECTIVITY, conn); } else + { element = Element::fromTwoChars('X', scanner.readChar()); + aromatic = ATOM_ALIPHATIC; + } } else if (next == '*') { @@ -3181,13 +3199,14 @@ void SmilesLoader::_readAtom(Array& atom_str, bool first_in_brackets, _Ato element = Element::fromTwoChars2(next, scanner.lookNext()); scanner.skip(1); if (smarts_mode) - if (element == ELEM_As || element == ELEM_Se) - aromatic = ATOM_ALIPHATIC; + // if (element == ELEM_As || element == ELEM_Se) + aromatic = ATOM_ALIPHATIC; } else if ((next == 'C' && scanner.lookNext() == 'n') && first_in_brackets) { scanner.skip(1); element = ELEM_Cn; + aromatic = ATOM_ALIPHATIC; } else { @@ -3195,8 +3214,8 @@ void SmilesLoader::_readAtom(Array& atom_str, bool first_in_brackets, _Ato element = Element::fromChar(next); if (smarts_mode) - if (element == ELEM_B || element == ELEM_C || element == ELEM_N || element == ELEM_O || element == ELEM_P || element == ELEM_S) - aromatic = ATOM_ALIPHATIC; + // if (element == ELEM_B || element == ELEM_C || element == ELEM_N || element == ELEM_O || element == ELEM_P || element == ELEM_S) + aromatic = ATOM_ALIPHATIC; } } else if (next == '@')