User 870ab5b546
31-03-2010 01:27:17
Target: [H]CCCC(C)=O
Query: [H]CC(=O)CCC
This code correctly returns false when exactExplicitHMatching is true:
public static boolean matchPrecise(Molecule respMol, Molecule authMol,
boolean exactExplicitHMatching, int stereoType)
throws MolFileException {
final String SELF = "MolFunctions.matchPrecise: ";
debugPrint(SELF + "exactExplicitHMatching = ", exactExplicitHMatching,
", stereoType = ", stereoType);
final MolSearch search = new MolSearch();
final MolSearchOptions searchOpts = new MolSearchOptions();
searchOpts.setSearchType(SearchConstants.DUPLICATE);
searchOpts.setVagueBondLevel(SearchConstants.VAGUE_BOND_OFF);
searchOpts.setStereoModel(SearchConstants.STEREO_MODEL_GLOBAL);
// required for comparing nonaromatized aromatic rings
final boolean ignore2D = ((stereoType & IGNORE_DBL_BOND_STEREO) != 0);
final boolean ignore3D = ((stereoType & IGNORE_TETRAHEDRAL_STEREO) != 0);
final boolean wavyAnd = ((stereoType & WAVY_AND) != 0);
boolean addWavyBondMatcher = false;
if (ignore2D) {
debugPrint(SELF + "ignoring 2D stereochemistry.");
searchOpts.setDoubleBondStereoMatchingMode(StereoConstants.DBS_NONE);
} // if ignore2D
if (ignore3D) {
debugPrint(SELF + "ignoring 3D stereochemistry.");
searchOpts.setStereoSearchType(SearchConstants.STEREO_IGNORE);
} else if (wavyAnd) {
addWavyBondMatcher = true;
// following line needed to avoid bug in JChem 5.1.3_2 and earlier
searchOpts.setKeepQueryOrder(true);
} // if ignore3D
search.setSearchOptions(searchOpts);
if (addWavyBondMatcher) {
debugPrint(SELF + "adding WavyBondMatcher.");
search.addComparator(new WavyBondMatcher());
} else debugPrint(SELF + "not adding WavyBondMatcher.");
if (exactExplicitHMatching) {
debugPrint(SELF + "adding ExplicitHMatcher.");
search.addComparator(new ExplicitHMatcher());
} else debugPrint(SELF + "not adding ExplicitHMatcher.");
search.setTarget(respMol);
search.setQuery(authMol);
debugPrintMRV(SELF + "respMol:\n", respMol);
debugPrintMRV(SELF + "authMol:\n", authMol);
try {
final boolean match = search.isMatching();
debugPrint(SELF + "search result is ", match);
return match;
} catch (SearchException e2) {
Utils.alwaysPrint("Error in " + SELF);
e2.printStackTrace();
throw new MolFileException(ERROR + e2.getMessage());
}
} // matchPrecise(Molecule, Molecule, boolean)
This code incorrectly returns true when exactExplicitHMatching is true:
public static boolean matchPrecise(Molecule respMol, Molecule authMol,
boolean exactExplicitHMatching, int stereoType)
throws MolFileException {
final String SELF = "MolFunctions.matchPrecise: ";
debugPrint(SELF + "exactExplicitHMatching = ", exactExplicitHMatching,
", stereoType = ", stereoType);
final MolSearch search = new MolSearch();
final MolSearchOptions searchOpts = new MolSearchOptions();
searchOpts.setSearchType(SearchConstants.DUPLICATE);
searchOpts.setVagueBondLevel(SearchConstants.VAGUE_BOND_OFF);
searchOpts.setStereoModel(SearchConstants.STEREO_MODEL_GLOBAL);
// required for comparing nonaromatized aromatic rings
final boolean ignore2D = ((stereoType & IGNORE_DBL_BOND_STEREO) != 0);
final boolean ignore3D = ((stereoType & IGNORE_TETRAHEDRAL_STEREO) != 0);
final boolean wavyAnd = ((stereoType & WAVY_AND) != 0);
boolean addWavyBondMatcher = false;
if (exactExplicitHMatching) {
debugPrint(SELF + "adding ExplicitHMatcher.");
search.addComparator(new ExplicitHMatcher());
} else debugPrint(SELF + "not adding ExplicitHMatcher.");
if (ignore2D) {
debugPrint(SELF + "ignoring 2D stereochemistry.");
searchOpts.setDoubleBondStereoMatchingMode(StereoConstants.DBS_NONE);
} // if ignore2D
if (ignore3D) {
debugPrint(SELF + "ignoring 3D stereochemistry.");
searchOpts.setStereoSearchType(SearchConstants.STEREO_IGNORE);
} else if (wavyAnd) {
addWavyBondMatcher = true;
// following line needed to avoid bug in JChem 5.1.3_2 and earlier
searchOpts.setKeepQueryOrder(true);
} // if ignore3D
search.setSearchOptions(searchOpts);
if (addWavyBondMatcher) {
debugPrint(SELF + "adding WavyBondMatcher.");
search.addComparator(new WavyBondMatcher());
} else debugPrint(SELF + "not adding WavyBondMatcher.");
search.setTarget(respMol);
search.setQuery(authMol);
debugPrintMRV(SELF + "respMol:\n", respMol);
debugPrintMRV(SELF + "authMol:\n", authMol);
try {
final boolean match = search.isMatching();
debugPrint(SELF + "search result is ", match);
return match;
} catch (SearchException e2) {
Utils.alwaysPrint("Error in " + SELF);
e2.printStackTrace();
throw new MolFileException(ERROR + e2.getMessage());
}
} // matchPrecise(Molecule, Molecule, boolean)
The only difference is whether the ExplicitHMatcher comparator is added to the MolSearch object before or after some of the MolSearchOptions are added. The comparator is disabled (debug output shows it is never called) if the search options are added to the MolSearch object after the comparator is added to it.
I have trouble believing this is anything but a bug.
Code of ExplicitHMatcher.compareAtoms():
public boolean compareAtoms(int queryAtomNum, int targetAtomNum) {
debugPrint("Entering ExplicitHMatcher.compareAtoms: "
+ "query = ", query, ", target = ", target);
final int qAtomNumOrig = getOrigQueryAtom(queryAtomNum);
int qHCount = 0;
if (qAtomNumOrig != -1) {
final MolAtom qAtom = query.getAtom(qAtomNumOrig);
qHCount = qAtom.getExplicitHcount();
debugPrint("qAtom ", qAtom, qAtomNumOrig + 1,
" has ", qHCount, " explicit H atoms.");
} else debugPrint("qAtom H is implicit.");
final int tAtomNumOrig = getOrigTargetAtom(targetAtomNum);
int tHCount = 0;
if (tAtomNumOrig != -1) {
final MolAtom tAtom = target.getAtom(tAtomNumOrig);
tHCount = tAtom.getExplicitHcount();
debugPrint("tAtom ", tAtom, tAtomNumOrig + 1,
" has ", tHCount, " explicit H atoms.");
} else debugPrint("tAtom H is implicit.");
final boolean match = (qHCount == tHCount);
debugPrint(match ? "Atoms match." : "Atoms do not match.");
return match;
} // compareAtoms(int, int)