Here we will present some code snippets for handling basic molecular operations.
For loading molecules we can load them sequentially from molecules files or all can be loaded at once into memory, which is only recommended for smaller data sets or when you want process a (sub)set of molecules very often.
Example 9-1. Load molecules from large files sequentially
// open file input stream String inputFile="yourInputFile.sdf"; FileInputStream input = null; try { input = new FileInputStream(inputFile); } catch (Exception ex) { ex.printStackTrace(); // TODO: handle exception } // create simple reader and // estimate file format by file extension SimpleReader reader = null; try { // estimate input file type IOType inType = IOTypeHolder.instance().filenameToType(inputFile); if (inType == null) { // TODO: handle unkown input file type } // open simple reader reader = new SimpleReader(input, inType); } catch (IOException e) { e.printStackTrace(); // TODO: handle exception } // load molecules sequentially // set output type to input type JOEMol mol = new JOEMol(inType, inType); for (;;) { try { if (!reader.readNext(mol)) { // process all molecules until // they are all processed break; } } catch (IOException ex) { // TODO: handle input/output exception } catch (MoleculeIOException ex) { // TODO: handle molecule parsing exception } // now the molecule is loaded !;-) // TODO: implement your molecule operation methods }
A (sub)set of molecules can be loaded a molecule vector which has vector analogue properties.
Example 9-2. Load molecules from smaller files into memory
// open file input stream String inputFile="yourInputFile.sdf"; FileInputStream input = null; try { input = new FileInputStream(inputFile); } catch (Exception ex) { ex.printStackTrace(); // TODO: handle exception } // estimate file format by file extension try { // estimate input file type IOType inType = IOTypeHolder.instance().filenameToType(inputFile); if (inType == null) { // TODO: handle unkown input file type } } catch (IOException e) { e.printStackTrace(); // TODO: handle exception } // load molecules into memory JOEMolVector molecules=null; try { // set output type to input type // skip molecules with corrupted molecule entries ! molecules = new JOEMolVector(input, inType, inType); } catch (IOException e) { e.printStackTrace(); // TODO: handle exception }
Adding atoms is a little bit critical and the required steps will be explained in example Example 9-3. When atoms are removed beginModify() and endModify() must be called also or strange results will be obtained. Adding and removing bonds is trivial and is not explained in detail.
Example 9-3. Add atoms to a molecule
// mol is a new molecule or an already loaded molecule //begin molecule modification //modifications will only be processed if the modification counter is 0!!! mol.beginModify(); // let's assume we will add 1 atoms // This is only essentially if many atoms will be added // to avoid multiple internal array swappings int natoms=mol.numAtoms()+1; mol.reserveAtoms(natoms); // get last atom to which we will add the new atoms JOEAtom atom2add=mol.getAtom(mol.numAtoms()); JOEAtom atom = new JOEAtom(); XYZVector v = new XYZVector(); boolean createCoords=true; if(createCoords) { // get non-corrected bond radii for the atoms, because for the new one // the hybridizations are not really available double bondlen =JOEElementTable.instance().getCovalentRad(nbr.getAtomicNum())+ JOEElementTable.instance().getCovalentRad(frag1.getAtomicNum()); atom2add.getNewBondVector(v, bondlen); } else{ v.setX(0.0); v.setY(0.0); v.setZ(0.0); } // set atom positions atom.setVector(v); String elementType="C"; int atomicNumber = JOEElementTable.instance().getAtomicNum(elementType); if (atomicNumber == 0) { // TODO: handle an unknown element type } // set atomic nnumber atom.setAtomicNum(atomicNumber); // set element type atom.setType(elementType); // add atom to the molecule if (!mol.addAtom(atom)) { // TODO: atom can not be added } // clear atom object if you want to use it to // add more atoms to the molecule atom.clear(); //modifications will only be processed if the modification counter is 0!!! //If you have called beginModify/endModify twice you can not expect //that these changes are already available correctly. //This fits especially for deleted and added atoms, because endModify //updates the atomId's, writes the atom coordinates to the rotamer //arrays and checks the aromaticity. mol.endModify();
Example 9-4. Access atoms using a for statement
int atoms = mol.numAtoms(); JOEAtom atom; for (int i=1; i<=atoms; i++) { atom=mol.getAtom(i); // TODO: do something with atoms }
Example 9-5. Access atoms using an AtomIterator
AtomIterator ait = mol.atomIterator(); JOEAtom atom; while (ait.hasNext()) { atom = ait.nextAtom(); // TODO: do something with atoms }