@Override public void initShape() { super.initShape(); myType = "axes"; font3d = g3d.getFont3D(JmolConstants.AXES_DEFAULT_FONTSIZE); int axesMode = viewer.getAxesMode(); if (fixedOrigin == null) originPoint.set(0, 0, 0); else originPoint.set(fixedOrigin); if (axesMode == JmolConstants.AXES_MODE_UNITCELL && modelSet.getCellInfos() != null) { SymmetryInterface unitcell = viewer.getCurrentUnitCell(); if (unitcell != null && unitcell.haveUnitCell()) { Point3f[] vectors = unitcell.getUnitCellVertices(); Point3f offset = unitcell.getCartesianOffset(); if (fixedOrigin == null) { originPoint.set(offset); } else { offset = fixedOrigin; } scale = viewer.getAxesScale() / 2f; // We must divide by 2 because that is the default for ALL axis types. // Not great, but it will have to do. axisPoints[0].scaleAdd(scale, vectors[4], offset); axisPoints[1].scaleAdd(scale, vectors[2], offset); axisPoints[2].scaleAdd(scale, vectors[1], offset); return; } } else if (axesMode == JmolConstants.AXES_MODE_BOUNDBOX) { if (fixedOrigin == null) originPoint.set(viewer.getBoundBoxCenter()); } setScale(viewer.getAxesScale() / 2f); }
public void applySymmetryAndSetTrajectory() throws Exception { if (iHaveUnitCell && doCheckUnitCell) { atomSetCollection.setCoordinatesAreFractional(iHaveFractionalCoordinates); atomSetCollection.setNotionalUnitCell( notionalUnitCell, matUnitCellOrientation, unitCellOffset); atomSetCollection.setAtomSetSpaceGroupName(spaceGroup); atomSetCollection.setSymmetryRange(symmetryRange); if (doConvertToFractional || fileCoordinatesAreFractional) { atomSetCollection.setLatticeCells( latticeCells, applySymmetryToBonds, doPackUnitCell, supercell); if (ignoreFileSpaceGroupName || !iHaveSymmetryOperators) { if (!merging || symmetry == null) getSymmetry(); if (symmetry.createSpaceGroup( desiredSpaceGroupIndex, (spaceGroup.indexOf("!") >= 0 ? "P1" : spaceGroup), notionalUnitCell)) { atomSetCollection.setAtomSetSpaceGroupName(symmetry.getSpaceGroupName()); atomSetCollection.applySymmetry(symmetry); } } else { atomSetCollection.applySymmetry(); } } if (iHaveFractionalCoordinates && merging && symmetry != null) { // when merging (with appendNew false), we must return cartesians atomSetCollection.toCartesian(symmetry); atomSetCollection.setCoordinatesAreFractional(false); // We no longer allow merging of multiple-model files // when the file to be appended has fractional coordinates and vibrations addVibrations = false; } } if (isTrajectory) atomSetCollection.setTrajectory(); initializeSymmetry(); }
private void checkUnitCellOffset() { if (symmetry == null || fileOffsetFractional == null) return; fileOffset.set(fileOffsetFractional); if (unitCellOffsetFractional != fileCoordinatesAreFractional) { if (unitCellOffsetFractional) symmetry.toCartesian(fileOffset, false); else symmetry.toFractional(fileOffset, false); } }
public void setAtomCoord(Atom atom) { // fileScaling is used by the PLOT command to // put data into PDB format, preserving name/residue information, // and still get any xyz data into the allotted column space. if (fileScaling != null) { atom.x = atom.x * fileScaling.x + fileOffset.x; atom.y = atom.y * fileScaling.y + fileOffset.y; atom.z = atom.z * fileScaling.z + fileOffset.z; } if (doConvertToFractional && !fileCoordinatesAreFractional && symmetry != null) { if (!symmetry.haveUnitCell()) symmetry.setUnitCell(notionalUnitCell); symmetry.toFractional(atom, false); iHaveFractionalCoordinates = true; } doCheckUnitCell = true; }
private void setSymmetry(boolean setOperators) { double[][] a; // Part 1: Get sigma_nu // van Smaalen, p. 92. Logger.info("[subsystem " + code + "]"); Matrix winv = w.inverse(); Logger.info("w=" + w); Logger.info("w_inv=" + winv); // w33 w3d van Smaalen, p. 94, Eqn. 4.15 // w = // wd3 wdd Matrix w33 = w.getSubmatrix(0, 0, 3, 3); Matrix wd3 = w.getSubmatrix(3, 0, d, 3); Matrix w3d = w.getSubmatrix(0, 3, 3, d); Matrix wdd = w.getSubmatrix(3, 3, d, d); Matrix sigma = msRdr.getSigma(); // Eqn. 4.16 Matrix sigma_nu = wdd.mul(sigma).add(wd3).mul(w3d.mul(sigma).add(w33).inverse()); Matrix tFactor = wdd.sub(sigma_nu.mul(w3d)); Logger.info("sigma_nu = " + sigma_nu); // Part 2: Get the new unit cell and symmetry operators SymmetryInterface s0 = msRdr.cr.asc.getSymmetry(); V3[] vu43 = s0.getUnitCellVectors(); V3[] vr43 = reciprocalsOf(vu43); // using full matrix math here: // // mar3 = just 3x3 matrix of ai* (a*, b*, c*) // mard3 = full (3+d)x3 matrix of ai* (a*, b*, c*, x4*, x5*,....) // = [ mard3 | sigma * mard3 ] // Matrix mard3 = new Matrix(null, 3 + d, 3); Matrix mar3 = new Matrix(null, 3, 3); double[][] mard3a = mard3.getArray(); double[][] mar3a = mar3.getArray(); for (int i = 0; i < 3; i++) mard3a[i] = mar3a[i] = new double[] {vr43[i + 1].x, vr43[i + 1].y, vr43[i + 1].z}; Matrix sx = sigma.mul(mar3); a = sx.getArray(); for (int i = 0; i < d; i++) mard3a[i + 3] = a[i]; a = w.mul(mard3).getArray(); // back to vector notation and direct lattice V3[] uc_nu = new V3[4]; uc_nu[0] = vu43[0]; // origin for (int i = 0; i < 3; i++) uc_nu[i + 1] = V3.new3((float) a[i][0], (float) a[i][1], (float) a[i][2]); uc_nu = reciprocalsOf(uc_nu); symmetry = ((Symmetry) msRdr.cr.getInterface("org.jmol.symmetry.Symmetry")) .getUnitCell(uc_nu, false, null); modMatrices = new Matrix[] {sigma_nu, tFactor}; if (!setOperators) return; isFinalized = true; // Part 3: Transform the operators // Logger.info("unit cell parameters: " + symmetry.getUnitCellInfo()); symmetry.createSpaceGroup(-1, "[subsystem " + code + "]", new Lst<M4>()); int nOps = s0.getSpaceGroupOperationCount(); for (int iop = 0; iop < nOps; iop++) { Matrix rv = s0.getOperationRsVs(iop); Matrix r0 = rv.getRotation(); Matrix v0 = rv.getTranslation(); Matrix r = w.mul(r0).mul(winv); Matrix v = w.mul(v0); String code = this.code; if (isMixed(r)) { // This operator mixes x4,x5... into x1,x2,x3. // It is not a pure operation. Instead, it correlates one // subsystem with another. Our job is to find the other // subsystem "j" that will satisfy the following condition: // // (Wj R Wi_inv).submatrix(0,3,3,d) == all_zeros // for (Entry<String, Subsystem> e : msRdr.htSubsystems.entrySet()) { Subsystem ss = e.getValue(); if (ss == this) continue; Matrix rj = ss.w.mul(r0).mul(winv); if (!isMixed(rj)) { // We have found the corresponding subsystem. // The result of this operation will be in other system, // and the operation itself will be used to rotate the modulation. // ss.code will be used to mark any atom created by this operation as // part of the other system. r = rj; v = ss.w.mul(v0); code = ss.code; break; } } } String jf = symmetry.addOp(code, r, v, sigma_nu); Logger.info( this.code + "." + (iop + 1) + (this.code.equals(code) ? " " : ">" + code + " ") + jf); } }
public void checkLineForScript() { if (line.indexOf("Jmol") >= 0) { if (line.indexOf("Jmol PDB-encoded data") >= 0) { atomSetCollection.setAtomSetCollectionAuxiliaryInfo("jmolData", line); if (!line.endsWith("#noautobond")) line += "#noautobond"; } if (line.indexOf("Jmol data min") >= 0) { Logger.info(line); // The idea here is to use a line such as the following: // // REMARK 6 Jmol data min = {-1 -1 -1} max = {1 1 1} // unScaledXyz = xyz / {10 10 10} + {0 0 0} // plotScale = {100 100 100} // // to pass on to Jmol how to graph non-molecular data. // The format allows for the actual data to be linearly transformed // so that it fits into the PDB format for x, y, and z coordinates. // This adapter will then unscale the data and also pass on to // Jmol the unit cell equivalent that takes the actual data (which // will be considered the fractional coordinates) to Jmol coordinates, // which will be a cube centered at {0 0 0} and ranging from {-100 -100 -100} // to {100 100 100}. // // Jmol 12.0.RC23 uses this to pass through the adapter a quaternion, // ramachandran, or other sort of plot. float[] data = new float[15]; parseStringInfestedFloatArray( line.substring(10).replace('=', ' ').replace('{', ' ').replace('}', ' '), data); Point3f minXYZ = new Point3f(data[0], data[1], data[2]); Point3f maxXYZ = new Point3f(data[3], data[4], data[5]); fileScaling = new Point3f(data[6], data[7], data[8]); fileOffset = new Point3f(data[9], data[10], data[11]); Point3f plotScale = new Point3f(data[12], data[13], data[14]); if (plotScale.x <= 0) plotScale.x = 100; if (plotScale.y <= 0) plotScale.y = 100; if (plotScale.z <= 0) plotScale.z = 100; if (fileScaling.y == 0) fileScaling.y = 1; if (fileScaling.z == 0) fileScaling.z = 1; setFractionalCoordinates(true); latticeCells = new int[3]; atomSetCollection.setLatticeCells(latticeCells, true, false, supercell); setUnitCell( plotScale.x * 2 / (maxXYZ.x - minXYZ.x), plotScale.y * 2 / (maxXYZ.y - minXYZ.y), plotScale.z * 2 / (maxXYZ.z == minXYZ.z ? 1 : maxXYZ.z - minXYZ.z), 90, 90, 90); /* unitCellOffset = new Point3f(minXYZ); symmetry.toCartesian(unitCellOffset); System.out.println(unitCellOffset); unitCellOffset = new Point3f(maxXYZ); symmetry.toCartesian(unitCellOffset); System.out.println(unitCellOffset); */ unitCellOffset = new Point3f(plotScale); unitCellOffset.scale(-1); symmetry.toFractional(unitCellOffset, false); unitCellOffset.scaleAdd(-1f, minXYZ, unitCellOffset); symmetry.setUnitCellOffset(unitCellOffset); /* Point3f pt = new Point3f(minXYZ); symmetry.toCartesian(pt); System.out.println("ASCR minXYZ " + pt); pt.set(maxXYZ); symmetry.toCartesian(pt); System.out.println("ASCR maxXYZ " + pt); */ atomSetCollection.setAtomSetCollectionAuxiliaryInfo( "jmolDataScaling", new Point3f[] {minXYZ, maxXYZ, plotScale}); } } if (line.endsWith("#noautobond")) { line = line.substring(0, line.lastIndexOf('#')).trim(); atomSetCollection.setNoAutoBond(); } int pt = line.indexOf("jmolscript:"); if (pt >= 0) { String script = line.substring(pt + 11, line.length()); if (script.indexOf("#") >= 0) { script = script.substring(0, script.indexOf("#")); } addJmolScript(script); line = line.substring(0, pt).trim(); } }