Skip to content

Commit

Permalink
feat: add molecule.getBondQueryFeaturesObject (#210)
Browse files Browse the repository at this point in the history
  • Loading branch information
lpatiny authored May 28, 2024
1 parent 768259c commit 2844831
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 56 deletions.
1 change: 1 addition & 0 deletions __tests__/__snapshots__/library.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ exports[`prototype properties of Molecule 1`] = `
"getBondParity",
"getBondPreferredStereoBond",
"getBondQueryFeatures",
"getBondQueryFeaturesObject",
"getBondRingSize",
"getBondType",
"getBondTypeSimple",
Expand Down
43 changes: 29 additions & 14 deletions __tests__/molecule.queryFeatures.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,37 @@

const { Molecule } = require('../minimal');

test('queryFeatures more than 2 neighbours', () => {
test('atom query features more than 2 neighbours', () => {
const molecule = Molecule.fromIDCode('eF@Hp[qp');

const firstQueryFeatures = molecule.getAtomQueryFeaturesObject(0);
expect(firstQueryFeatures.not0Neighbours).toBe(true);
expect(firstQueryFeatures.not1Neighbours).toBe(true);
expect(firstQueryFeatures.not2Neighbours).toBe(true);
expect(firstQueryFeatures.not3Neighbours).toBe(false);
const firstAtomQueryFeatures = molecule.getAtomQueryFeaturesObject(0);
expect(firstAtomQueryFeatures.not0Neighbours).toBe(true);
expect(firstAtomQueryFeatures.not1Neighbours).toBe(true);
expect(firstAtomQueryFeatures.not2Neighbours).toBe(true);
expect(firstAtomQueryFeatures.not3Neighbours).toBe(false);

});

test('queryFeatures exactly 2 hydrogens', () => {
test('atom query features exactly 2 hydrogens', () => {
const molecule = Molecule.fromIDCode('eF@Hp_Qh');
const firstQueryFeatures = molecule.getAtomQueryFeaturesObject(0);
expect(firstQueryFeatures.not0Hydrogen).toBe(true);
expect(firstQueryFeatures.not1Hydrogen).toBe(true);
expect(firstQueryFeatures.not2Hydrogen).toBe(false);
expect(firstQueryFeatures.not3Hydrogen).toBe(true);
});
const firstAtomQueryFeatures = molecule.getAtomQueryFeaturesObject(0);
expect(firstAtomQueryFeatures.not0Hydrogen).toBe(true);
expect(firstAtomQueryFeatures.not1Hydrogen).toBe(true);
expect(firstAtomQueryFeatures.not2Hydrogen).toBe(false);
expect(firstAtomQueryFeatures.not3Hydrogen).toBe(true);
});

test('bond query features cycle of 4 atoms with aromatic bond', () => {
const molecule = Molecule.fromIDCode('eM@HzC~TFLP');
const firstBondQueryFeatures = molecule.getBondQueryFeaturesObject(0);
expect(firstBondQueryFeatures.ringSize).toBe(4);
expect(firstBondQueryFeatures.aromatic).toBe(true);
expect(firstBondQueryFeatures.nonAromatic).toBe(false);
})

test('bond query features atom bridge 2 to 7', () => {
const molecule = Molecule.fromIDCode('eM@HzCNDh');
const firstBondQueryFeatures = molecule.getBondQueryFeaturesObject(0);
expect(firstBondQueryFeatures.brigdeMin).toBe(2);
expect(firstBondQueryFeatures.brigdeSpan).toBe(5);
expect(firstBondQueryFeatures.nonAromatic).toBe(false);
})
3 changes: 3 additions & 0 deletions src/com/actelion/research/gwt/minimal/JSMolecule.java
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,9 @@ public JavaScriptObject getAtomQueryFeaturesObject(int atom) {
return MoleculeQueryFeatures.getAtomQueryFeatures(oclMolecule, atom);
}

public JavaScriptObject getBondQueryFeaturesObject(int atom) {
return MoleculeQueryFeatures.getBondQueryFeatures(oclMolecule, atom);
}

public int getAtomRadical(int atom) {
return oclMolecule.getAtomRadical(atom);
Expand Down
107 changes: 65 additions & 42 deletions src/com/actelion/research/gwt/minimal/MoleculeQueryFeatures.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,79 +6,102 @@

class MoleculeQueryFeatures {
public static JavaScriptObject getAtomQueryFeatures(StereoMolecule oclMolecule, int atom) {
PlainJSObject moleculeQueryFeatures = PlainJSObject.create();
PlainJSObject toReturn = PlainJSObject.create();
long atomQueryFeatures = oclMolecule.getAtomQueryFeatures(atom);

moleculeQueryFeatures.setPropertyBoolean("aromatic",
(atomQueryFeatures & Molecule.cAtomQFAromatic) > 0);
moleculeQueryFeatures.setPropertyBoolean("notAromatic",
toReturn.setPropertyBoolean("aromatic", (atomQueryFeatures & Molecule.cAtomQFAromatic) > 0);
toReturn.setPropertyBoolean("notAromatic",
(atomQueryFeatures & Molecule.cAtomQFNotAromatic) > 0);

moleculeQueryFeatures.setPropertyBoolean("notChain",
(atomQueryFeatures & Molecule.cAtomQFNotChain) > 0);
moleculeQueryFeatures.setPropertyBoolean("not2RingBonds",
toReturn.setPropertyBoolean("notChain", (atomQueryFeatures & Molecule.cAtomQFNotChain) > 0);
toReturn.setPropertyBoolean("not2RingBonds",
(atomQueryFeatures & Molecule.cAtomQFNot2RingBonds) > 0);
moleculeQueryFeatures.setPropertyBoolean("not3RingBonds",
toReturn.setPropertyBoolean("not3RingBonds",
(atomQueryFeatures & Molecule.cAtomQFNot3RingBonds) > 0);
moleculeQueryFeatures.setPropertyBoolean("not4RingBonds",
toReturn.setPropertyBoolean("not4RingBonds",
(atomQueryFeatures & Molecule.cAtomQFNot4RingBonds) > 0);

moleculeQueryFeatures.setPropertyBoolean("noMoreNeighbours",
toReturn.setPropertyBoolean("noMoreNeighbours",
(atomQueryFeatures & Molecule.cAtomQFNoMoreNeighbours) > 0);
moleculeQueryFeatures.setPropertyBoolean("moreNeighbours",
toReturn.setPropertyBoolean("moreNeighbours",
(atomQueryFeatures & Molecule.cAtomQFMoreNeighbours) > 0);
moleculeQueryFeatures.setPropertyBoolean("matchStereo",
toReturn.setPropertyBoolean("matchStereo",
(atomQueryFeatures & Molecule.cAtomQFMatchStereo) > 0);

moleculeQueryFeatures.setPropertyBoolean("not0PiElectrons",
toReturn.setPropertyBoolean("not0PiElectrons",
(atomQueryFeatures & Molecule.cAtomQFNot0PiElectrons) > 0);
moleculeQueryFeatures.setPropertyBoolean("not1PiElectrons",
toReturn.setPropertyBoolean("not1PiElectrons",
(atomQueryFeatures & Molecule.cAtomQFNot1PiElectron) > 0);
moleculeQueryFeatures.setPropertyBoolean("not2PiElectrons",
toReturn.setPropertyBoolean("not2PiElectrons",
(atomQueryFeatures & Molecule.cAtomQFNot2PiElectrons) > 0);

moleculeQueryFeatures.setPropertyBoolean("not0Hydrogen",
toReturn.setPropertyBoolean("not0Hydrogen",
(atomQueryFeatures & Molecule.cAtomQFNot0Hydrogen) > 0);
moleculeQueryFeatures.setPropertyBoolean("not1Hydrogen",
toReturn.setPropertyBoolean("not1Hydrogen",
(atomQueryFeatures & Molecule.cAtomQFNot1Hydrogen) > 0);
moleculeQueryFeatures.setPropertyBoolean("not2Hydrogen",
toReturn.setPropertyBoolean("not2Hydrogen",
(atomQueryFeatures & Molecule.cAtomQFNot2Hydrogen) > 0);
moleculeQueryFeatures.setPropertyBoolean("not3Hydrogen",
toReturn.setPropertyBoolean("not3Hydrogen",
(atomQueryFeatures & Molecule.cAtomQFNot3Hydrogen) > 0);

moleculeQueryFeatures.setPropertyBoolean("not0Neighbours",
toReturn.setPropertyBoolean("not0Neighbours",
(atomQueryFeatures & Molecule.cAtomQFNot0Neighbours) > 0);
moleculeQueryFeatures.setPropertyBoolean("not1Neighbours",
toReturn.setPropertyBoolean("not1Neighbours",
(atomQueryFeatures & Molecule.cAtomQFNot0Neighbours) > 0);
moleculeQueryFeatures.setPropertyBoolean("not2Neighbours",
toReturn.setPropertyBoolean("not2Neighbours",
(atomQueryFeatures & Molecule.cAtomQFNot2Neighbours) > 0);
moleculeQueryFeatures.setPropertyBoolean("not3Neighbours",
toReturn.setPropertyBoolean("not3Neighbours",
(atomQueryFeatures & Molecule.cAtomQFNot3Neighbours) > 0);
moleculeQueryFeatures.setPropertyBoolean("not4Neighbours",
toReturn.setPropertyBoolean("not4Neighbours",
(atomQueryFeatures & Molecule.cAtomQFNot4Neighbours) > 0);

moleculeQueryFeatures.setPropertyBoolean("notChargeNeg",
toReturn.setPropertyBoolean("notChargeNeg",
(atomQueryFeatures & Molecule.cAtomQFNotChargeNeg) > 0);
moleculeQueryFeatures.setPropertyBoolean("notCharge0",
(atomQueryFeatures & Molecule.cAtomQFNotCharge0) > 0);
moleculeQueryFeatures.setPropertyBoolean("noChargePos",
toReturn.setPropertyBoolean("notCharge0", (atomQueryFeatures & Molecule.cAtomQFNotCharge0) > 0);
toReturn.setPropertyBoolean("noChargePos",
(atomQueryFeatures & Molecule.cAtomQFNotChargePos) > 0);

moleculeQueryFeatures.setPropertyBoolean("ringSize0",
(atomQueryFeatures & Molecule.cAtomQFRingSize0) > 0);
moleculeQueryFeatures.setPropertyBoolean("ringSize3",
(atomQueryFeatures & Molecule.cAtomQFRingSize3) > 0);
moleculeQueryFeatures.setPropertyBoolean("ringSize4",
(atomQueryFeatures & Molecule.cAtomQFRingSize4) > 0);
moleculeQueryFeatures.setPropertyBoolean("ringSize5",
(atomQueryFeatures & Molecule.cAtomQFRingSize5) > 0);
moleculeQueryFeatures.setPropertyBoolean("ringSize6",
(atomQueryFeatures & Molecule.cAtomQFRingSize6) > 0);
moleculeQueryFeatures.setPropertyBoolean("ringSize7",
(atomQueryFeatures & Molecule.cAtomQFRingSize7) > 0);
moleculeQueryFeatures.setPropertyBoolean("ringSizeLarge",
toReturn.setPropertyBoolean("ringSize0", (atomQueryFeatures & Molecule.cAtomQFRingSize0) > 0);
toReturn.setPropertyBoolean("ringSize3", (atomQueryFeatures & Molecule.cAtomQFRingSize3) > 0);
toReturn.setPropertyBoolean("ringSize4", (atomQueryFeatures & Molecule.cAtomQFRingSize4) > 0);
toReturn.setPropertyBoolean("ringSize5", (atomQueryFeatures & Molecule.cAtomQFRingSize5) > 0);
toReturn.setPropertyBoolean("ringSize6", (atomQueryFeatures & Molecule.cAtomQFRingSize6) > 0);
toReturn.setPropertyBoolean("ringSize7", (atomQueryFeatures & Molecule.cAtomQFRingSize7) > 0);
toReturn.setPropertyBoolean("ringSizeLarge",
(atomQueryFeatures & Molecule.cAtomQFRingSizeLarge) > 0);

return moleculeQueryFeatures;
return toReturn;
}

public static JavaScriptObject getBondQueryFeatures(StereoMolecule oclMolecule, int bond) {
PlainJSObject toReturn = PlainJSObject.create();
long bondQueryFeatures = oclMolecule.getBondQueryFeatures(bond);

toReturn.setPropertyBoolean("single", (bondQueryFeatures & Molecule.cBondQFSingle) > 0);
toReturn.setPropertyBoolean("double", (bondQueryFeatures & Molecule.cBondQFDouble) > 0);
toReturn.setPropertyBoolean("triple", (bondQueryFeatures & Molecule.cBondQFTriple) > 0);
toReturn.setPropertyBoolean("delocalized",
(bondQueryFeatures & Molecule.cBondQFDelocalized) > 0);
toReturn.setPropertyBoolean("metalLigand",
(bondQueryFeatures & Molecule.cBondQFMetalLigand) > 0);
toReturn.setPropertyBoolean("quadruple", (bondQueryFeatures & Molecule.cBondQFQuadruple) > 0);
toReturn.setPropertyBoolean("quintuple", (bondQueryFeatures & Molecule.cBondQFQuintuple) > 0);

toReturn.setPropertyBoolean("notRing", (bondQueryFeatures & Molecule.cBondQFNotRing) > 0);
toReturn.setPropertyBoolean("ring", (bondQueryFeatures & Molecule.cBondQFRing) > 0);

toReturn.setPropertyBoolean("aromatic", (bondQueryFeatures & Molecule.cBondQFAromatic) > 0);
toReturn.setPropertyBoolean("nonAromatic",
(bondQueryFeatures & Molecule.cBondQFNotAromatic) > 0);

toReturn.setPropertyInt("ringSize",
(int) (bondQueryFeatures & Molecule.cBondQFRingSize) >> Molecule.cBondQFRingSizeShift);

toReturn.setPropertyInt("brigdeMin",
(int) (bondQueryFeatures & Molecule.cBondQFBridgeMin) >> Molecule.cBondQFBridgeMinShift);
toReturn.setPropertyInt("brigdeSpan",
(int) (bondQueryFeatures & Molecule.cBondQFBridgeSpan) >> Molecule.cBondQFBridgeSpanShift);

return toReturn;
}
}
23 changes: 23 additions & 0 deletions types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ export interface AtomQueryFeatures {
ringSizeLarge: boolean;
}

export interface BondQueryFeatures {
single: boolean;
double: boolean;
triple: boolean;
delocalized: boolean;
metalLigand: boolean;
quadruple: boolean;
quintuple: boolean;
notRing: boolean;
ring: boolean;
aromatic: boolean;
nonAromatic: boolean;
ringSize: number;
brigdeMin: number;
brigdeSpan: number;
}

export interface IMoleculeToSVGOptions extends IDepictorOptions {
/**
* Factor used to compute the size of text nodes.
Expand Down Expand Up @@ -945,6 +962,12 @@ export declare class Molecule {
*/
getAtomQueryFeaturesObject(atom: number): AtomQueryFeatures;

/**
* Get the bond query features as an object
* @param bond
*/
getBondQueryFeaturesObject(bond: number): BondQueryFeatures;

/**
* The list of atoms that are allowed at this position during sub-structure
* search. (or refused atoms, if atom query feature cAtomQFAny is set).
Expand Down

0 comments on commit 2844831

Please sign in to comment.