Skip to content

Commit

Permalink
feat: expose Reactor
Browse files Browse the repository at this point in the history
  • Loading branch information
lpatiny committed Jan 4, 2023
1 parent 0d645c3 commit 5eb1c26
Show file tree
Hide file tree
Showing 9 changed files with 456 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ It contains a structure viewer and a structure editor for browser applications.
- [DrugScoreCalculator](https://cheminfo.github.io/openchemlib-js/modules/DrugScoreCalculator.html)
- [ForceFieldMMFF94](https://cheminfo.github.io/openchemlib-js/classes/ForceFieldMMFF94.html)
- [MoleculeProperties](https://cheminfo.github.io/openchemlib-js/classes/MoleculeProperties.html)
- [ReactionEncoder](https://cheminfo.github.io/openchemlib-js/classes/ReactionEncoder.html)
- [Reactor](https://cheminfo.github.io/openchemlib-js/classes/Reactor.html)
- [ToxicityPredictor](https://cheminfo.github.io/openchemlib-js/classes/ToxicityPredictor.html)
- [Transformer](https://cheminfo.github.io/openchemlib-js/classes/Transformer.html)

Expand Down
144 changes: 144 additions & 0 deletions __tests__/Reactor.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
'use strict';

const { getMF } = require('openchemlib-utils');

const { Reactor, Molecule, Reaction, ReactionEncoder } = require('../core');

// the actelion reaction ID is encoded in the RXN file !!!
// this code has priority so if it is there the rest of the RXN file is ignored
// Currently we generate RXN files using ChemDraw

describe('Reactor class', () => {
it('deshydratation', () => {
const reaction = ReactionEncoder.decode(
'eMHAIhH!eF@HhP#QF Qd#!R_vq?DqtJ_@ !R@Fp]Agp',
);

const reactor = new Reactor(reaction);

const match = reactor.setReactant(0, Molecule.fromSmiles('OC(C)CCCO'));
if (!match) return;

const products = reactor.getProducts();

const smiles = [];
for (let i = 0; i < products.length; i++) {
for (let j = 0; j < products[i].length; j++) {
smiles.push(products[i][j].toSmiles());
}
}

expect(smiles).toStrictEqual(['C(CCCO)=C', 'C(C)=CCCO', 'OC(C)CC=C']);
});

it('protonation, we add a H+ on the O', () => {
const rxn = `$RXN
1 1
$MOL
Actelion Java MolfileCreator 1.0
3 2 0 0 0 0 0 0 0 0999 V2000
1.7321 -0.5000 -0.0000 O 0 0 0 0 0 0 0 0 0 1 0 0
0.8660 -0.0000 -0.0000 C 0 0 0 0 0 0 0 0 0 2 0 0
0.0000 -0.5000 -0.0000 C 0 0 0 0 0 0 0 0 0 3 0 0
1 2 1 0 0 0 0
2 3 1 0 0 0 0
M END
$MOL
Actelion Java MolfileCreator 1.0
3 2 0 0 0 0 0 0 0 0999 V2000
1.7321 -0.5000 -0.0000 O 0 3 0 0 0 0 0 0 0 1 0 0
0.8660 -0.0000 -0.0000 C 0 0 0 0 0 0 0 0 0 2 0 0
0.0000 -0.5000 -0.0000 C 0 0 0 0 0 0 0 0 0 3 0 0
1 2 1 0 0 0 0
2 3 1 0 0 0 0
M END`;

const reaction = Reaction.fromRxn(rxn);

const reactor = new Reactor(reaction);

const match = reactor.setReactant(0, Molecule.fromSmiles('OC(C)CCCO'));
if (!match) return;

const products = reactor.getProducts();

const smiles = [];
for (let i = 0; i < products.length; i++) {
for (let j = 0; j < products[i].length; j++) {
smiles.push(products[i][j].toSmiles());
}
}
expect(smiles).toStrictEqual(['[OH2+]C(CCCO)C', 'OC(C)CCC[OH2+]']);
});

it('charge O and break bond', () => {
const rxn = `$RXN
test.rxn
ChemDraw01042314002D
1 2
$MOL
3 2 0 0 0 0 0 0 0 0999 V2000
-0.7145 -0.2062 0.0000 C 0 0 0 0 0 0 0 0 0 2 0 0
-0.0000 0.2062 0.0000 C 0 0 0 0 0 0 0 0 0 1 0 0
0.7145 -0.2062 0.0000 O 0 0 0 0 0 0 0 0 0 3 0 0
1 2 1 0 4
2 3 1 0 0
M END
$MOL
1 0 0 0 0 0 0 0 0 0999 V2000
0.0000 0.0000 0.0000 C 0 4 0 0 0 0 0 0 0 2 0 0
M RAD 1 1 2
M END
$MOL
2 1 0 0 0 0 0 0 0 0999 V2000
-0.3268 0.2643 0.0000 C 0 0 0 0 0 0 0 0 0 1 0 0
0.3268 -0.2643 0.0000 O 0 3 0 0 0 0 0 0 0 3 0 0
1 2 1 0 0
M CHG 1 2 1
M END
`;

const reaction = Reaction.fromRxn(rxn);

const reactor = new Reactor(reaction);

const match = reactor.setReactant(0, Molecule.fromSmiles('OC(C)CCCO'));
if (!match) return;

const products = reactor.getProducts();

const smiles = [];
const mfs = [];
for (let i = 0; i < products.length; i++) {
for (let j = 0; j < products[i].length; j++) {
smiles.push(products[i][j].toSmiles());
mfs.push(getMF(products[i][j]).mf);
}
}
expect(mfs).toStrictEqual([
'CH3',
'C4H11O2(+)',
'C3H7O',
'C2H7O(+)',
'C4H9O',
'CH5O(+)',
]);
});
});
9 changes: 9 additions & 0 deletions __tests__/__snapshots__/library.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,13 @@ exports[`prototype properties of MoleculeProperties 1`] = `[]`;

exports[`prototype properties of ReactionEncoder 1`] = `[]`;

exports[`prototype properties of Reactor 1`] = `
[
"getProducts",
"setReactant",
]
`;

exports[`prototype properties of SDFileParser 1`] = `
[
"getField",
Expand Down Expand Up @@ -637,6 +644,8 @@ exports[`static properties of ReactionEncoder 1`] = `
]
`;

exports[`static properties of Reactor 1`] = `[]`;

exports[`static properties of SDFileParser 1`] = `[]`;

exports[`static properties of SSSearcher 1`] = `[]`;
Expand Down
1 change: 1 addition & 0 deletions __tests__/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const coreAPI = [
'ForceFieldMMFF94',
'MoleculeProperties',
'ReactionEncoder',
'Reactor',
'ToxicityPredictor',
'Transformer',
];
Expand Down
1 change: 1 addition & 0 deletions core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export {
IParameterizedString,
MoleculeProperties,
ReactionEncoder,
Reactor,
Transformer,
ToxicityPredictor,
} from './types';
Loading

0 comments on commit 5eb1c26

Please sign in to comment.