User 870ab5b546
02-08-2006 05:22:30
This code allows you to specify the dihedral angle about any bond in a molecule.
The code comes from this jsp page, hence the getParameter() commands at the top, but you can easily adapt it to a Java page.
Requires a Molecule object or a molecule in a standard string format, four atom indices separated by commas or colons, and an angle in degrees.
The code comes from this jsp page, hence the getParameter() commands at the top, but you can easily adapt it to a Java page.
Requires a Molecule object or a molecule in a standard string format, four atom indices separated by commas or colons, and an angle in degrees.
Code: |
String moleculeStr = request.getParameter("molecule"); String atomString = request.getParameter("atomString"); String dihedralSetStr = request.getParameter("dihedralSet"); boolean doCalculation = true; Molecule molecule = null; if (moleculeStr != null) molecule = MolImporter.importMol(moleculeStr); else doCalculation = false; int[] atomIndex = new int[4]; if (atomString != null && atomString != "") { String[] atoms = atomString.split(":"); if (atoms.length == 1) atoms = atomString.split(","); if ((atoms.length == 4) && doCalculation) { int maxIndex = molecule.getAtomCount() - 1; for (int j=0; j<4; j++) { atomIndex[j] = Integer.parseInt(atoms[j]) - 1; if (atomIndex[j] > maxIndex) doCalculation = false; } } else doCalculation = false; } else doCalculation = false; // no atoms entered int dihedralSetDegrees = (dihedralSetStr == null || dihedralSetStr == "") ? 0 : Integer.parseInt(dihedralSetStr); double dihedralSetRadians = dihedralSetDegrees*Math.PI/180; if (doCalculation) { MolAtom originAtom = molecule.getAtom(atomIndex[1]); MolAtom pivotAtom = molecule.getAtom(atomIndex[2]); DPoint3 originLoc = originAtom.getLocation(); DPoint3 pivotLoc = pivotAtom.getLocation(); CTransform3D translate = new CTransform3D(); translate.setTranslation( -originLoc.x, -originLoc.y, -originLoc.z ); System.out.println("Before translation to put origin at bond midpoint: "); System.out.println(" " + originAtom.getSymbol() + (atomIndex[1]+1) + " has coords " + originLoc.x + "," + originLoc.y + "," + originLoc.z + ";" ); System.out.println(" " + pivotAtom.getSymbol() + (atomIndex[2]+1) + " has coords " + pivotLoc.x + "," + pivotLoc.y + "," + pivotLoc.z + "." ); molecule.transform(translate); originLoc = originAtom.getLocation(); pivotLoc = pivotAtom.getLocation(); System.out.println("After translation: "); System.out.println(" " + originAtom.getSymbol() + (atomIndex[1]+1) + " has coords " + originLoc.x + "," + originLoc.y + "," + originLoc.z + ";" ); System.out.println(" " + pivotAtom.getSymbol() + (atomIndex[2]+1) + " has coords " + pivotLoc.x + "," + pivotLoc.y + "," + pivotLoc.z + "." ); // now rotate entire molecule double lengthPivotOrigin = pivotLoc.distance(originLoc); // make rotation vector average of pivot atom and vector along // z axis with length same as pivot atom; then rotation angle of 180 degrees // puts pivot atom on Z axis DPoint3 vectorRotate = new DPoint3( (0 + pivotLoc.x)/2, (0 + pivotLoc.y)/2, (lengthPivotOrigin + pivotLoc.z)/2 ); CTransform3D rotate = new CTransform3D(); rotate.setRotationCenter(originLoc); rotate.setRotation(vectorRotate.x, vectorRotate.y, vectorRotate.z, Math.PI); molecule.transform(rotate); System.out.println("After rotation of whole molecule: "); originLoc = originAtom.getLocation(); pivotLoc = pivotAtom.getLocation(); System.out.println(" " + originAtom.getSymbol() + (atomIndex[1]+1) + " has coords " + originLoc.x + "," + originLoc.y + "," + originLoc.z + ";" ); System.out.println(" " + pivotAtom.getSymbol() + (atomIndex[2]+1) + " has coords " + pivotLoc.x + "," + pivotLoc.y + "," + pivotLoc.z + "." ); DPoint3 atom4Loc = molecule.getAtom(atomIndex[3]).getLocation(); DPoint3 atom1Loc = molecule.getAtom(atomIndex[0]).getLocation(); // get current dihedral angle double atom4angleOrig = Math.atan(atom4Loc.y/atom4Loc.x); if (atom4Loc.x < 0) atom4angleOrig += Math.PI; double atom1angleOrig = Math.atan(atom1Loc.y/atom1Loc.x); if (atom1Loc.x < 0) atom1angleOrig += Math.PI; double angleDiffOrig = atom4angleOrig - atom1angleOrig; double moveAngle = dihedralSetRadians - angleDiffOrig; for (int i=0; i<pivotAtom.getBondCount(); i++) { MolAtom ligand = (MolAtom) pivotAtom.getLigand(i); if (ligand != originAtom) { DPoint3 ligLoc = ligand.getLocation(); System.out.println(" Before bond rotation, " + ligand.getSymbol() + (molecule.indexOf(ligand)+1) + " has coords " + ligLoc.x + "," + ligLoc.y + "," + ligLoc.z + "." ); double ligAngle = Math.atan(ligLoc.y/ligLoc.x); double ligLength = Math.sqrt( Math.pow(ligLoc.x, 2) + Math.pow(ligLoc.y, 2) ); if (ligLoc.x < 0) ligAngle += Math.PI; ligAngle += moveAngle; DPoint3 newLoc = new DPoint3( Math.cos(ligAngle)*ligLength, Math.sin(ligAngle)*ligLength, ligLoc.z ); ligand.setLocation(newLoc); ligLoc = ligand.getLocation(); System.out.println(" After bond rotation, " + ligand.getSymbol() + (molecule.indexOf(ligand)+1) + " has coords " + ligLoc.x + "," + ligLoc.y + "," + ligLoc.z + "." ); } // if not the origin } // for each ligand of pivot atom // now rotate entire molecule back molecule.transform(rotate); System.out.println("After rotation of whole molecule back: "); originLoc = originAtom.getLocation(); pivotLoc = pivotAtom.getLocation(); System.out.println(" " + originAtom.getSymbol() + (atomIndex[1]+1) + " has coords " + originLoc.x + "," + originLoc.y + "," + originLoc.z + ";" ); System.out.println(" " + pivotAtom.getSymbol() + (atomIndex[2]+1) + " has coords " + pivotLoc.x + "," + pivotLoc.y + "," + pivotLoc.z + "." ); moleculeStr = molecule.toFormat("mrv"); } |