diff --git a/__tests__/__snapshots__/reaction.test.ts.snap b/__tests__/__snapshots__/reaction.test.ts.snap index 47cdd152..ebbdd1cd 100644 --- a/__tests__/__snapshots__/reaction.test.ts.snap +++ b/__tests__/__snapshots__/reaction.test.ts.snap @@ -152,3 +152,167 @@ OCL_RXN_V1.0:!#### 0 0 " `; + +exports[`Reaction class > toRXN options keepIdCode one product 1`] = ` +"$RXN + + + + 0 1 +$MOL + +Actelion Java MolfileCreator 1.0 + + 3 2 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 2 3 2 0 0 0 0 +M END +" +`; + +exports[`Reaction class > toRXN options keepIdCode one product 2`] = ` +"$RXN +Hello world! + +OCL_RXN_V1.0:!eMDARU@##!R_?y??kH@@@## + 0 1 +$MOL + +Actelion Java MolfileCreator 1.0 + + 3 2 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 2 3 2 0 0 0 0 +M END +" +`; + +exports[`Reaction class > toRXN options keepIdCode one reagent 1`] = ` +"$RXN + + + + 1 0 +$MOL + +Actelion Java MolfileCreator 1.0 + + 1 0 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 +M END +" +`; + +exports[`Reaction class > toRXN options keepIdCode one reagent 2`] = ` +"$RXN +Hello world! + +OCL_RXN_V1.0:fH@@!##!RGP@@## + 1 0 +$MOL + +Actelion Java MolfileCreator 1.0 + + 1 0 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 +M END +" +`; + +exports[`Reaction class > toRXN options keepIdCode two products 1`] = ` +"$RXN + + + + 0 2 +$MOL + +Actelion Java MolfileCreator 1.0 + + 1 0 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 +M END +$MOL + +Actelion Java MolfileCreator 1.0 + + 1 0 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 +M END +" +`; + +exports[`Reaction class > toRXN options keepIdCode two products 2`] = ` +"$RXN +Hello world! + +OCL_RXN_V1.0:!fH@@ fI@@##!RGP@@ !RGP@@## + 0 2 +$MOL + +Actelion Java MolfileCreator 1.0 + + 1 0 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 +M END +$MOL + +Actelion Java MolfileCreator 1.0 + + 1 0 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 +M END +" +`; + +exports[`Reaction class > toRXN options keepIdCode two reagents 1`] = ` +"$RXN + + + + 2 0 +$MOL + +Actelion Java MolfileCreator 1.0 + + 1 0 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 +M END +$MOL + +Actelion Java MolfileCreator 1.0 + + 1 0 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 +M END +" +`; + +exports[`Reaction class > toRXN options keepIdCode two reagents 2`] = ` +"$RXN +Hello world! + +OCL_RXN_V1.0:fH@@ fI@@!##!RGP@@ !RGP@@## + 2 0 +$MOL + +Actelion Java MolfileCreator 1.0 + + 1 0 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 +M END +$MOL + +Actelion Java MolfileCreator 1.0 + + 1 0 0 0 0 0 0 0 0 0999 V2000 + 0.0000 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 +M END +" +`; diff --git a/__tests__/reaction.test.ts b/__tests__/reaction.test.ts index a5154fca..19209cda 100644 --- a/__tests__/reaction.test.ts +++ b/__tests__/reaction.test.ts @@ -43,7 +43,90 @@ describe('Reaction class', () => { keepIdCode: true, programName: 'Hello world!', }); - // this test could fail once this bug is fixed: https://github.com/Actelion/openchemlib/issues/158 + expect(rxn2).toMatchSnapshot(); + }); + + it('toRXN options keepIdCode one reagent', () => { + const reaction = Reaction.create(); + const methane = Molecule.fromSmiles('C'); + reaction.addReactant(methane); + expect(reaction.getReactants()).toBe(1); + expect(reaction.getProducts()).toBe(0); + expect(reaction.getCatalysts()).toBe(0); + const rxn = reaction.toRxn(); + expect(rxn).toMatchSnapshot(); + const reaction2 = Reaction.fromRxn(rxn); + expect(reaction2.getReactants()).toBe(1); + expect(reaction2.getProducts()).toBe(0); + expect(reaction2.getCatalysts()).toBe(0); + const rxn2 = reaction2.toRxn({ + keepIdCode: true, + programName: 'Hello world!', + }); + expect(rxn2).toMatchSnapshot(); + }); + + it('toRXN options keepIdCode two reagents', () => { + const reaction = Reaction.create(); + const methane = Molecule.fromSmiles('C'); + const oxygen = Molecule.fromSmiles('O'); + reaction.addReactant(methane); + reaction.addReactant(oxygen); + expect(reaction.getReactants()).toBe(2); + expect(reaction.getProducts()).toBe(0); + expect(reaction.getCatalysts()).toBe(0); + const rxn = reaction.toRxn(); + expect(rxn).toMatchSnapshot(); + const reaction2 = Reaction.fromRxn(rxn); + expect(reaction2.getReactants()).toBe(2); + expect(reaction2.getProducts()).toBe(0); + expect(reaction2.getCatalysts()).toBe(0); + const rxn2 = reaction2.toRxn({ + keepIdCode: true, + programName: 'Hello world!', + }); + expect(rxn2).toMatchSnapshot(); + }); + + it('toRXN options keepIdCode one product', () => { + const reaction = Reaction.create(); + const carbonDioxide = Molecule.fromSmiles('O=C=O'); + reaction.addProduct(carbonDioxide); + expect(reaction.getReactants()).toBe(0); + expect(reaction.getProducts()).toBe(1); + expect(reaction.getCatalysts()).toBe(0); + const rxn = reaction.toRxn(); + expect(rxn).toMatchSnapshot(); + const reaction2 = Reaction.fromRxn(rxn); + expect(reaction2.getReactants()).toBe(0); + expect(reaction2.getProducts()).toBe(1); + expect(reaction2.getCatalysts()).toBe(0); + const rxn2 = reaction2.toRxn({ + keepIdCode: true, + programName: 'Hello world!', + }); + expect(rxn2).toMatchSnapshot(); + }); + + it('toRXN options keepIdCode two products', () => { + const reaction = Reaction.create(); + const carbon = Molecule.fromSmiles('C'); + reaction.addProduct(carbon); + const oxygen = Molecule.fromSmiles('O'); + reaction.addProduct(oxygen); + expect(reaction.getReactants()).toBe(0); + expect(reaction.getProducts()).toBe(2); + expect(reaction.getCatalysts()).toBe(0); + const rxn = reaction.toRxn(); + expect(rxn).toMatchSnapshot(); + const reaction2 = Reaction.fromRxn(rxn); + expect(reaction2.getReactants()).toBe(0); + expect(reaction2.getProducts()).toBe(2); + expect(reaction2.getCatalysts()).toBe(0); + const rxn2 = reaction2.toRxn({ + keepIdCode: true, + programName: 'Hello world!', + }); expect(rxn2).toMatchSnapshot(); }); diff --git a/openchemlib b/openchemlib index 68a858e6..eafa47bc 160000 --- a/openchemlib +++ b/openchemlib @@ -1 +1 @@ -Subproject commit 68a858e6e08e2fdf5f6ce856bc9562ebf34cf26f +Subproject commit eafa47bc3a36b6228833668094e934b166ddc30c diff --git a/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/IDCodeParserWithoutCoordinateInvention.java b/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/IDCodeParserWithoutCoordinateInvention.java index 9c7458b3..638c613c 100644 --- a/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/IDCodeParserWithoutCoordinateInvention.java +++ b/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/IDCodeParserWithoutCoordinateInvention.java @@ -99,7 +99,7 @@ public StereoMolecule getCompactMolecule(byte[] idcode) { /** * Creates and returns a molecule from the idcode with its atom and bond arrays being * just as large as needed to hold the molecule. Use this to conserve memory if no - * atoms or bonds are added to the molecule afterwards. + * atoms or bonds are added to the molecule afterward. * @param idcode may be null * @param coordinates may be null * @return @@ -112,7 +112,7 @@ public StereoMolecule getCompactMolecule(String idcode, String coordinates) { /** * Creates and returns a molecule from the idcode with its atom and bond arrays being * just as large as needed to hold the molecule. Use this to conserve memory if no - * atoms or bonds are added to the molecule afterwards. + * atoms or bonds are added to the molecule afterward. * @param idcode may be null * @param coordinates may be null * @return diff --git a/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/calc/AminoAcids.java b/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/calc/AminoAcids.java index cd45f207..3b7931fa 100644 --- a/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/calc/AminoAcids.java +++ b/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/calc/AminoAcids.java @@ -101,7 +101,7 @@ public static Molecule3D createResidue(String label, Map atom if (mol != null) { Molecule3D aminoAcid = new Molecule3D(mol); - for (int atom=0; atom atom aminoAcid.setAtomX(atom, coords3d.x); aminoAcid.setAtomY(atom, coords3d.y); aminoAcid.setAtomZ(atom, coords3d.z); + + AtomRecord bridgeRecord = record.getCovalentBridgeAtom(); + if (bridgeRecord != null) { + int bridgeAtom = aminoAcid.addAtom(0); + aminoAcid.setAtomCustomLabel(bridgeAtom,"]cov"); + aminoAcid.setAtomX(bridgeAtom, (bridgeRecord.getX() + record.getX()) / 2); + aminoAcid.setAtomY(bridgeAtom, (bridgeRecord.getY() + record.getY()) / 2); + aminoAcid.setAtomZ(bridgeAtom, (bridgeRecord.getZ() + record.getZ()) / 2); + aminoAcid.addBond(atom, bridgeAtom, Molecule.cBondTypeSingle); + aminoAcid.setCovalentLigand(true); + } } }; diff --git a/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/AtomRecord.java b/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/AtomRecord.java index 1819362a..84649ea1 100644 --- a/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/AtomRecord.java +++ b/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/AtomRecord.java @@ -43,7 +43,6 @@ public class AtomRecord implements Comparable { private boolean isHetAtom; - private int serialId; // From field atom name @@ -53,30 +52,19 @@ public class AtomRecord implements Comparable { // Alternate location indicator. private String labelAltID; - private int labelSeqID; - private String authCompID; - private String authAsymId; - private String insertionCode; - private int authSeqID; - private double x,y,z; - private double occupancy; - private double tempFactor; - private String element; - private String charge; - private String anisou; - private boolean isTerminalC; + private AtomRecord covalentBridgeAtom; public AtomRecord() {} @@ -204,6 +192,14 @@ public void setTerminalC(boolean isTerminalC) { this.isTerminalC = isTerminalC; } + public void setCovalentBridgeAtom(AtomRecord atom) { + covalentBridgeAtom = atom; + } + + public AtomRecord getCovalentBridgeAtom() { + return covalentBridgeAtom; + } + @Override public int compareTo(AtomRecord o) { return Integer.compare(serialId, o.serialId); diff --git a/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/Residue.java b/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/Residue.java index a0d8583d..a91f00d3 100644 --- a/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/Residue.java +++ b/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/Residue.java @@ -136,6 +136,16 @@ else if (!altLoc.equals(record.getLabelAltID())) fragment.setAtomX(atom,record.getX()); fragment.setAtomY(atom,record.getY()); fragment.setAtomZ(atom,record.getZ()); + AtomRecord bridgeRecord = record.getCovalentBridgeAtom(); + if (bridgeRecord != null) { + int bridgeAtom = fragment.addAtom(0); + fragment.setAtomCustomLabel(bridgeAtom,"]cov"); + fragment.setAtomX(bridgeAtom, (bridgeRecord.getX() + record.getX()) / 2); + fragment.setAtomY(bridgeAtom, (bridgeRecord.getY() + record.getY()) / 2); + fragment.setAtomZ(bridgeAtom, (bridgeRecord.getZ() + record.getZ()) / 2); + fragment.addBond(atom, bridgeAtom, Molecule.cBondTypeSingle); + fragment.setCovalentLigand(true); + } } if (mAddBonds) { diff --git a/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/StructureAssembler.java b/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/StructureAssembler.java index 0b2d8611..db2e87ba 100644 --- a/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/StructureAssembler.java +++ b/src/com/actelion/research/gwt/chemlib/com/actelion/research/chem/io/pdb/parser/StructureAssembler.java @@ -240,8 +240,13 @@ private void buildBonds(Molecule3D mol, boolean isProtein) { if (!isProtein) addConnections(mol, mTemplateConnectionList, sequenceToAtomMap, existingBondSet); try { - if (!isProtein && mol.getAllBonds() < mol.getAllAtoms()) // template records didn't properly cover this molecule + if (!isProtein && mol.getAllBonds() < mol.getAllAtoms()) { // template records didn't properly cover this molecule BondsCalculator.createBonds(mol, true, null); + for (int bond=0; bond