Revision: 20476 http://sourceforge.net/p/jmol/code/20476 Author: hansonr Date: 2015-05-03 18:46:39 +0000 (Sun, 03 May 2015) Log Message: ----------- Jmol.___JmolVersion="14.3.13_2015.05.03"
new feature: for msCIF (modulated structure files), setting modulation or using vibration ON now also indicates occupancy changes Modified Paths: -------------- trunk/Jmol/src/javajs/util/CifDataParser.java trunk/Jmol/src/org/jmol/adapter/readers/cif/MSRdr.java trunk/Jmol/src/org/jmol/modelset/Atom.java trunk/Jmol/src/org/jmol/modelset/AtomCollection.java trunk/Jmol/src/org/jmol/modelset/ModelLoader.java trunk/Jmol/src/org/jmol/render/HalosRenderer.java trunk/Jmol/src/org/jmol/render/ShapeRenderer.java trunk/Jmol/src/org/jmol/render/SticksRenderer.java trunk/Jmol/src/org/jmol/renderspecial/VectorsRenderer.java trunk/Jmol/src/org/jmol/script/T.java trunk/Jmol/src/org/jmol/scriptext/CmdExt.java trunk/Jmol/src/org/jmol/shape/Labels.java trunk/Jmol/src/org/jmol/shapespecial/Dots.java trunk/Jmol/src/org/jmol/util/Modulation.java trunk/Jmol/src/org/jmol/util/ModulationSet.java trunk/Jmol/src/org/jmol/util/Vibration.java trunk/Jmol/src/org/jmol/viewer/GlobalSettings.java trunk/Jmol/src/org/jmol/viewer/JC.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties trunk/Jmol/src/org/jmol/viewer/ShapeManager.java trunk/Jmol/src/org/jmol/viewer/TransformManager.java trunk/Jmol/src/org/jmol/viewer/Viewer.java Modified: trunk/Jmol/src/javajs/util/CifDataParser.java =================================================================== --- trunk/Jmol/src/javajs/util/CifDataParser.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/javajs/util/CifDataParser.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -280,13 +280,14 @@ while ((str = peekToken()) != null && str.charAt(0) == '_') { if (ret != null) ret.append(str).append("\n"); - getTokenPeeked(); - n++; + getTokenPeeked(); + n++; } int m = 0; while ((str = getNextDataToken()) != null) { - if (ret != null) - ret.append(str).append(" "); + if (ret == null) + continue; + ret.append(str).append(" "); if ((++m % n) == 0) ret.append("\n"); } Modified: trunk/Jmol/src/org/jmol/adapter/readers/cif/MSRdr.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/cif/MSRdr.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/adapter/readers/cif/MSRdr.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -350,8 +350,7 @@ if (modTUV != null) cr.appendLoadNote("modTUV=" + modTUV); cr.asc.setInfo("modulationOn", modTUV == null ? Boolean.TRUE : modTUV); - cr.addJmolScript((haveOccupancy && !isCommensurate ? ";display occupancy >= 0.5" - : "")); + cr.addJmolScript("set modulateOccupancy " + (haveOccupancy && !isCommensurate ? true: false)); } finalized = true; } @@ -857,8 +856,8 @@ // because we are going to repurpose that. ModulationSet ms = new ModulationSet().setMod(a.index + " " + a.atomName, getAtomR0(cr.asc.atoms[a.atomSite]), getAtomR0(a), - modDim, list, gammaE, getMatrices(a), iop, getSymmetry(a), - a.vib instanceof Vibration ? (Vibration) a.vib : null); + modDim, list, gammaE, getMatrices(a), getSymmetry(a), nOps, iop, + a.vib instanceof Vibration ? (Vibration) a.vib : null, isCommensurate); ms.calculate(modTUV, false); @@ -866,30 +865,8 @@ // vibrations, and anisotropy tensors. if (!Float.isNaN(ms.vOcc)) { - double[] pt = getMod("J_O#0;" + a.atomName); - float occ0 = ms.vOcc0; - double occ; - if (Float.isNaN(occ0)) { - // Crenel - occ = ms.vOcc; - } else if (pt == null) { - // cif Fourier - // _atom_site_occupancy + SUM - occ = a.foccupancy + ms.vOcc; - } else if (a.vib != null) { - // cif with m40 Fourier - // occ_site * (occ_0 + SUM) - double site_mult = a.vib.x; - double o_site = a.foccupancy * site_mult / nOps / pt[1]; - occ = o_site * (pt[1] + ms.vOcc); - } else { - // m40 Fourier - // occ_site * (occ_0 + SUM) - occ = pt[0] * (pt[1] + ms.vOcc); - } - // 49/50 is an important range for cutoffs -- we let this range be void - a.foccupancy = (occ > 0.49 && occ < 0.50 ? 0.489f : (float) Math.min(1, - Math.max(0, occ))); + // a.vib may be used to temporarily store an M40 site multiplicity + a.foccupancy = ms.setOccupancy(getMod("J_O#0;" + a.atomName), a.foccupancy, (a.vib == null ? 0 : a.vib.x)); //Logger.info("atom " + a.atomName + " occupancy = " + a.foccupancy); } if (ms.htUij != null) { Modified: trunk/Jmol/src/org/jmol/modelset/Atom.java =================================================================== --- trunk/Jmol/src/org/jmol/modelset/Atom.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/modelset/Atom.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -56,6 +56,18 @@ public class Atom extends Point3fi implements BNode { + // ATOM_IN_FRAME simply associates an atom with the current model + // but doesn't necessarily mean it is visible + // ATOM_VIS_SET and ATOM_VISIBLE are checked once only for each atom per rendering + + public final static int ATOM_INFRAME = 1; + public final static int ATOM_VISSET = 2; // have carried out checkVisible() + public final static int ATOM_VISIBLE = 4; // set from checkVisible() + public final static int ATOM_NOTHIDDEN = 8; + public final static int ATOM_NOFLAGS = ~63; // all of the above, plus balls and sticks + public final static int ATOM_INFRAME_NOTHIDDEN = ATOM_INFRAME | ATOM_NOTHIDDEN; + public final static int ATOM_SHAPE_VIS_MASK = ~ATOM_INFRAME_NOTHIDDEN; + private final static byte VIBRATION_VECTOR_FLAG = 1; private final static byte IS_HETERO_FLAG = 2; private final static byte FLAG_MASK = 3; @@ -376,9 +388,15 @@ // a percentage value in the range 0-100 public int getOccupancy100() { float[] occupancies = group.chain.model.ms.occupancies; - return occupancies == null ? 100 : Math.round(occupancies[i]); + return (occupancies == null ? 100 : Math.round(occupancies[i])); } + // a percentage value in the range 0-100 + public boolean isOccupied() { + float[] occupancies = group.chain.model.ms.occupancies; + return (occupancies == null || occupancies[i] >= 50); + } + // This is called bfactor100 because it is stored as an integer // 100 times the bfactor(temperature) value public int getBfactor100() { @@ -947,9 +965,9 @@ } public boolean checkVisible() { - if (isVisible(JC.ATOM_VISSET)) - return isVisible(JC.ATOM_VISIBLE); - boolean isVis = isVisible(JC.ATOM_INFRAME_NOTHIDDEN); + if (isVisible(ATOM_VISSET)) + return isVisible(ATOM_VISIBLE); + boolean isVis = isVisible(ATOM_INFRAME_NOTHIDDEN); if (isVis) { int flags = shapeVisibilityFlags; // Is its PDB group visible in any way (cartoon, e.g.)? @@ -963,16 +981,16 @@ // We know that (flags & AIM), so now we must remove that flag // and check to see if any others are remaining. // Only then is the atom considered visible. - flags &= JC.ATOM_SHAPE_VIS_MASK; + flags &= ATOM_SHAPE_VIS_MASK; // problem with display of bond-only when not clickable. // bit of a kludge here. if (flags == JC.VIS_BOND_FLAG && clickabilityFlags == 0) flags = 0; isVis = (flags != 0); if (isVis) - shapeVisibilityFlags |= JC.ATOM_VISIBLE; + shapeVisibilityFlags |= ATOM_VISIBLE; } - shapeVisibilityFlags |= JC.ATOM_VISSET; + shapeVisibilityFlags |= ATOM_VISSET; return isVis; } Modified: trunk/Jmol/src/org/jmol/modelset/AtomCollection.java =================================================================== --- trunk/Jmol/src/org/jmol/modelset/AtomCollection.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/modelset/AtomCollection.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -96,7 +96,7 @@ int[] atomResnos; int[] atomSeqIDs; public Vibration[] vibrations; - float[] occupancies; + public float[] occupancies; short[] bfactor100s; float[] partialCharges; float[] bondingRadii; @@ -2443,11 +2443,11 @@ haveBSClickable = false; } - public void getRenderable(BS bsAtoms) { + public void getAtomsInFrame(BS bsAtoms) { clearVisibleSets(); bsAtoms.clearAll(); for (int i = ac; --i >= 0;) - if (at[i].isVisible(JC.ATOM_INFRAME)) + if (at[i].isVisible(Atom.ATOM_INFRAME)) bsAtoms.set(i); } Modified: trunk/Jmol/src/org/jmol/modelset/ModelLoader.java =================================================================== --- trunk/Jmol/src/org/jmol/modelset/ModelLoader.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/modelset/ModelLoader.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -1069,7 +1069,7 @@ int modelIndex = -1; SymmetryInterface c = null; boolean isFractional = false; - boolean roundCoords = !vwr.getBoolean(T.legacyjavafloat); + boolean roundCoords = !vwr.g.legacyJavaFloat; for (int i = baseAtomIndex; i < ms.ac; i++) { if (atoms[i].mi != modelIndex) { modelIndex = atoms[i].mi; Modified: trunk/Jmol/src/org/jmol/render/HalosRenderer.java =================================================================== --- trunk/Jmol/src/org/jmol/render/HalosRenderer.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/render/HalosRenderer.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -40,8 +40,7 @@ protected boolean render() { Halos halos = (Halos) shape; boolean showOnce = vwr.getShowSelectedOnce(); - boolean selectDisplayTrue = vwr.getSelectionHalosEnabled() || showOnce; - System.out.println(showOnce + " testhalos"); + boolean selectDisplayTrue = (vwr.getSelectionHalosEnabled() || showOnce); boolean showHiddenSelections = (selectDisplayTrue && vwr.getBoolean(T.showhiddenselectionhalos)); if (halos.mads == null && halos.bsHighlight == null && !selectDisplayTrue) return false; @@ -53,7 +52,7 @@ g3d.addRenderer(T.circle); for (int i = ms.ac; --i >= 0;) { Atom atom = atoms[i]; - if ((atom.shapeVisibilityFlags & JC.ATOM_INFRAME) == 0) + if ((atom.shapeVisibilityFlags & Atom.ATOM_INFRAME) == 0) continue; boolean isHidden = ms.isAtomHidden(i); mad = (halos.mads == null ? 0 : halos.mads[i]); Modified: trunk/Jmol/src/org/jmol/render/ShapeRenderer.java =================================================================== --- trunk/Jmol/src/org/jmol/render/ShapeRenderer.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/render/ShapeRenderer.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -85,7 +85,7 @@ } protected boolean isVisibleForMe(Atom a) { - return a.isVisible(myVisibilityFlag | JC.ATOM_INFRAME_NOTHIDDEN); + return a.isVisible(myVisibilityFlag | Atom.ATOM_INFRAME_NOTHIDDEN); } Modified: trunk/Jmol/src/org/jmol/render/SticksRenderer.java =================================================================== --- trunk/Jmol/src/org/jmol/render/SticksRenderer.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/render/SticksRenderer.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -154,8 +154,8 @@ } } if (!isPass2 - && (!a.isVisible(JC.ATOM_INFRAME_NOTHIDDEN) - || !b.isVisible(JC.ATOM_INFRAME_NOTHIDDEN) + && (!a.isVisible(Atom.ATOM_INFRAME_NOTHIDDEN) + || !b.isVisible(Atom.ATOM_INFRAME_NOTHIDDEN) || !g3d.isInDisplayRange(a.sX, a.sY) || !g3d.isInDisplayRange(b.sX, b.sY))) return false; Modified: trunk/Jmol/src/org/jmol/renderspecial/VectorsRenderer.java =================================================================== --- trunk/Jmol/src/org/jmol/renderspecial/VectorsRenderer.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/renderspecial/VectorsRenderer.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -33,6 +33,7 @@ import org.jmol.shape.Shape; import org.jmol.shapespecial.Vectors; import org.jmol.util.GData; +import org.jmol.util.Point3fi; import javajs.util.P3; import javajs.util.P3i; @@ -43,8 +44,8 @@ private final static float arrowHeadOffset = -0.2f; private final P3 pointVectorStart = new P3(); - private final P3 ptTemp = new P3(); - private final P3 pointVectorEnd = new P3(); + private final Point3fi ptTemp = new Point3fi(); + private final Point3fi pointVectorEnd = new Point3fi(); private final P3 pointArrowHead = new P3(); private final P3i screenVectorStart = new P3i(); private final P3i screenVectorEnd = new P3i(); Modified: trunk/Jmol/src/org/jmol/script/T.java =================================================================== --- trunk/Jmol/src/org/jmol/script/T.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/script/T.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -1043,19 +1043,20 @@ public final static int minimizationrefresh = booleanparam | 105; public final static int minimizationsilent = booleanparam | 106; public final static int modelkitmode = booleanparam | 107; // 12.0.RC15 - public final static int monitorenergy = booleanparam | 108; - public final static int multiprocessor = booleanparam | 109; - public final static int navigatesurface = booleanparam | 110; - public final static int navigationmode = booleanparam | 111; - public final static int navigationperiodic = booleanparam | 112; - public final static int partialdots = booleanparam | 113; // 12.1.46 - public final static int pdbaddhydrogens = booleanparam | 114; - public final static int pdbgetheader = booleanparam | 115; - public final static int pdbsequential = booleanparam | 116; - public final static int perspectivedepth = booleanparam | 117; - public final static int preservestate = booleanparam | 118; - public final static int rangeselected = booleanparam | 119; - public final static int refreshing = booleanparam | 120; + public final static int modulateoccupancy = booleanparam | 108; // 14.3.13 + public final static int monitorenergy = booleanparam | 109; + public final static int multiprocessor = booleanparam | 110; + public final static int navigatesurface = booleanparam | 111; + public final static int navigationmode = booleanparam | 112; + public final static int navigationperiodic = booleanparam | 113; + public final static int partialdots = booleanparam | 114; // 12.1.46 + public final static int pdbaddhydrogens = booleanparam | 115; + public final static int pdbgetheader = booleanparam | 116; + public final static int pdbsequential = booleanparam | 117; + public final static int perspectivedepth = booleanparam | 118; + public final static int preservestate = booleanparam | 119; + public final static int rangeselected = booleanparam | 120; + public final static int refreshing = booleanparam | 121; public final static int ribbonborder = booleanparam | 122; public final static int rocketbarrels = booleanparam | 124; public final static int saveproteinstructurestate = booleanparam | 126; @@ -2562,6 +2563,7 @@ "minimizationRefresh", "minimizationSilent", "modelkitMode", + "modulateOccupancy", "monitorEnergy", "multipleBondRadiusFactor", "multipleBondSpacing", @@ -3586,6 +3588,7 @@ minimizationrefresh, // "minimizationRefresh" minimizationsilent, // "minimizationSilent" modelkitmode, // "modelkitMode" + modulateoccupancy, monitorenergy, // "monitorEnergy" multiplebondradiusfactor, // "multipleBondRadiusFactor" multiplebondspacing, // "multipleBondSpacing" Modified: trunk/Jmol/src/org/jmol/scriptext/CmdExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -1402,7 +1402,7 @@ BS bsExclude = new BS(); vwr.ms.setPdbConectBonding(0, 0, bsExclude); if (isAuto) { - boolean isLegacy = eval.isStateScript && vwr.g.legacyAutoBonding; + boolean isLegacy = eval.isStateScript && vwr.getBoolean(T.legacyautobonding); vwr.ms.autoBondBs4(null, null, bsExclude, null, vwr.getMadBond(), isLegacy); vwr.addStateScript( (isLegacy ? "set legacyAutoBonding TRUE;connect PDB AUTO;set legacyAutoBonding FALSE;" Modified: trunk/Jmol/src/org/jmol/shape/Labels.java =================================================================== --- trunk/Jmol/src/org/jmol/shape/Labels.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/shape/Labels.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -684,7 +684,7 @@ int imin = -1; float zmin = Float.MAX_VALUE; for (Map.Entry<Integer, float[]> entry : labelBoxes.entrySet()) { - if (!atoms[entry.getKey().intValue()].isVisible(vf | JC.ATOM_INFRAME_NOTHIDDEN)) + if (!atoms[entry.getKey().intValue()].isVisible(vf | Atom.ATOM_INFRAME_NOTHIDDEN)) continue; float[] boxXY = entry.getValue(); float dx = x - boxXY[0]; Modified: trunk/Jmol/src/org/jmol/shapespecial/Dots.java =================================================================== --- trunk/Jmol/src/org/jmol/shapespecial/Dots.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/shapespecial/Dots.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -131,7 +131,7 @@ ec.setMads(null); mads = new short[ac]; for (int i = 0; i < ac; i++) - if (atoms[i].isVisible(JC.ATOM_INFRAME | vf)) + if (atoms[i].isVisible(Atom.ATOM_INFRAME | vf)) // was there a reason we were not checking for hidden? try { mads[i] = (short) (ec.getAppropriateRadius(i) * 1000); Modified: trunk/Jmol/src/org/jmol/util/Modulation.java =================================================================== --- trunk/Jmol/src/org/jmol/util/Modulation.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/util/Modulation.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -147,10 +147,12 @@ case TYPE_U_LEGENDRE: // not implemented in reader, but all set here case TYPE_DISP_LEGENDRE: - ms.vOcc0 = Float.NaN; // absolute + ms.occAbsolute = true; nt -= Math.floor(nt); - if (!range(nt)) + if (!range(nt)) { + ms.vOcc = 0; return; + } ms.vOcc = 1; // normalize to [-1,1] double x = (nt - center) / delta2; @@ -175,15 +177,15 @@ // p(x4)=1 if x4 belongs to the interval [c-w/2,c+w/2] // p(x4)=0 if x4 is outside the interval [c-w/2,c+w/2], + ms.occAbsolute = true; ms.vOcc = (range(nt - Math.floor(nt)) ? 1 : 0); - ms.vOcc0 = Float.NaN; // absolute - //System.out.println("MOD " + ms.r + " " + ms.delta + " " + ms.epsilon + " " + ms.id + " " + ms.v + " l=" + left + " x=" + x4 + " r=" + right); + //System.out.println("MOD " + ms.id + " v=" + ms.vOcc + " l=" + left + " x=" + nt + " r=" + right); return; case TYPE_SPIN_SAWTOOTH: isSpin = true; //$FALL-THROUGH$ case TYPE_DISP_SAWTOOTH: - + ms.occAbsolute = true; // _atom_site_displace_special_func_sawtooth_ items are the // adjustable parameters of a sawtooth function. A displacive sawtooth // function along the internal space is defined as follows: @@ -199,8 +201,11 @@ // here we have set a1 = 2a_xyz/w nt -= Math.floor(nt); - if (!range(nt)) + if (!range(nt)) { + ms.vOcc = 0; return; + } + ms.vOcc = 1; // x < L < c // @@ -261,7 +266,7 @@ } if (isSpin) { - float[] f = ms.getAxesLengths(); + float[] f = ms.axesLengths; switch (axis) { case 'x': ms.mxyz.x += v / f[0]; Modified: trunk/Jmol/src/org/jmol/util/ModulationSet.java =================================================================== --- trunk/Jmol/src/org/jmol/util/ModulationSet.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/util/ModulationSet.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -24,55 +24,165 @@ public class ModulationSet extends Vibration implements JmolModulationSet { - public float vOcc = Float.NaN; - public Map<String, Float> htUij; - public float vOcc0; - + /** + * an identifier for this modulation + * + */ String id; + + /** + * the unmodulated original position of this atom; + * note that x,y,z extended from Vibration(V3) is the current displacement modulation itself + * + */ + private P3 r0; - private Lst<Modulation> mods; + + /** + * the space group appropriate to this atom + * + */ + private SymmetryInterface symmetry; + + /** + * unit cell axes -- used in Modulation for calculating magnetic modulations + */ + float[] axesLengths; + + /** + * the number of operators in this space group -- needed for occupancy calculation + */ + private int nOps; + + /** + * the symmetry operation used to generate this atom + */ private int iop; - private P3 r0; + /** + * a string description of the atom's symmetry operator + */ + private String strop; + + /** + * the spin operation for this atom: +1/0/-1 + */ + private float spinOp; + + /** + * the matrix representation for this atom's symmetry operation + * + */ + private Matrix rsvs; + + /** * vib is a spin vector when the model has modulation; otherwise an * unmodulated vibration. * */ public Vibration vib; - public V3 mxyz; + + /** + * the list of all modulations associated with this atom + */ + private Lst<Modulation> mods; + + /** + * subsystems can deliver their own unique unit cell; + * they are commensurate + * + */ + private boolean isSubsystem; + + @Override + public SymmetryInterface getSubSystemUnitCell() { + return (isSubsystem ? symmetry : null); + } - private SymmetryInterface symmetry; - private M3 gammaE; - private Matrix gammaIinv; - private Matrix sigma; - private Matrix tau; + /** + * commensurate modulations cannot be "undone" + * and they cannot be turned off + * + */ + private boolean isCommensurate; - private boolean enabled; - private float scale = 1; + // parameters necessary for calculating occValue + + private double fileOcc; + private double[] occParams; + private double occSiteMultiplicity; + /** + * for Crenels (simple occupational modulation or Legendre displacement modulation, + * the value determined here is absolute (0 or 1), not an adjustment; + * set in calculate() by one of the modulations + * + */ + boolean occAbsolute; + + /** + * modCalc is used for calculations independent of + * what the current setting is + * + */ + private ModulationSet modCalc; + + /** + * the modulated magnetic spin + */ + public V3 mxyz; + + /** + * current value of anisotropic parameter modulation + * + */ + public Map<String, Float> htUij; + + /** + * the current value of the occupancy modulation + */ + public float vOcc = Float.NaN; + + /** + * final occupancy value -- absolute; in range [0,1] + */ + private float occValue = Float.NaN; + + // values set in setModTQ + private P3 qtOffset = new P3(); private boolean isQ; - private Matrix rI; + /** + * indicates state of modulated or unmodulated + */ + private boolean enabled; - private ModulationSet modTemp; - private String strop; - private boolean isSubsystem; + @Override + public boolean isEnabled() { + return enabled; + } - private Matrix tFactorInv; - private Matrix rsvs; - private float spinOp; + /** + * an adjustable scaling factor, as for vibrations + * + */ + private float scale = 1; @Override public float getScale() { return scale; } - @Override - public boolean isEnabled() { - return enabled; - } + // generator parameters + private M3 gammaE; + private Matrix gammaIinv; + private Matrix sigma; + private Matrix tau; + private Matrix rI; + private Matrix tFactorInv; // for subsystems + public ModulationSet() { } @@ -91,10 +201,12 @@ * @param gammaE * @param factors * including sigma and tFactor + * @param symmetry * @param iop - * @param symmetry + * @param nOps * @param v * TODO + * @param isCommensurate TODO * @return this * * @@ -102,8 +214,9 @@ public ModulationSet setMod(String id, P3 r00, P3 r0, int d, Lst<Modulation> mods, M3 gammaE, - Matrix[] factors, int iop, - SymmetryInterface symmetry, Vibration v) { + Matrix[] factors, + SymmetryInterface symmetry, int nOps, int iop, + Vibration v, boolean isCommensurate) { // The superspace operation matrix is (3+d+1)x(3+d+1) rotation/translation matrix // that can be blocked as follows: @@ -221,14 +334,16 @@ //// need to bring in, sigma and tFactor, and two we need to compute, //// GammaIinv and tau. - this.id = id + "_" + symmetry.getSpaceGroupName(); + this.id = id;// + "_" + symmetry.getSpaceGroupName(); + this.symmetry = symmetry; strop = symmetry.getSpaceGroupXyz(iop, false); + this.iop = iop; + this.nOps = nOps; + this.r0 = r0; modDim = d; rI = new Matrix(null, d, 1); this.mods = mods; - this.iop = iop; - this.symmetry = symmetry; this.gammaE = gammaE; // gammaE_nu, R, the real 3x3 rotation matrix, as M3 sigma = factors[0]; if (factors[1] != null) { @@ -243,6 +358,7 @@ vib = v; vib.modScale = 1; mxyz = new V3(); // modulations of spin + axesLengths = symmetry.getUnitCellParams(); // required for calculating mxyz } Matrix vR00 = Matrix.newT(r00, true); Matrix vR0 = Matrix.newT(r0, true); @@ -263,11 +379,6 @@ return this; } - @Override - public SymmetryInterface getSubSystemUnitCell() { - return (isSubsystem ? symmetry : null); - } - /** * Calculate r_I internal d-space coordinate of an atom. * @@ -367,6 +478,8 @@ if (isQ) qtOffset = null; calculate(qtOffset, isQ); + if (!Float.isNaN(vOcc)) + occValue = getOccupancy(); } if (isOn) { addTo(a, 1); @@ -420,22 +533,24 @@ @Override public Object getModulation(char type, T3 tuv) { - getModTemp(); + getModCalc(); switch (type) { case 'D': // return r0 if t456 is null, otherwise calculate dx,dy,dz for a given t4,5,6 - return P3.newP(tuv == null ? r0 : modTemp.calculate(tuv, false)); + return P3.newP(tuv == null ? r0 : modCalc.calculate(tuv, false)); case 'M': - // return r0 if t456 is null, otherwise calculate dx,dy,dz for a given t4,5,6 - return P3.newP(tuv == null ? v0 : modTemp.calculate(tuv, false).mxyz); + // return v0 if t456 is null, otherwise calculate vx,vy,vz for a given t4,5,6 + return P3.newP(tuv == null ? v0 : modCalc.calculate(tuv, false).mxyz); case 'T': - modTemp.calculate(tuv, false); - double[][] ta = modTemp.rI.getArray(); + // do a calculation and return the t-value for the first three dimensions of modulation + modCalc.calculate(tuv, false); + double[][] ta = modCalc.rI.getArray(); return P3.new3((float) ta[0][0], (modDim > 1 ? (float) ta[1][0] : 0), (modDim > 2 ? (float) ta[2][0] : 0)); case 'O': - // return vOcc current or calculated - return Float.valueOf((tuv == null ? vOcc : modTemp.calculate(tuv, false).vOcc) * 100); + // return the currently modulated or calculated occupation on [0,100] + return Float.valueOf(Math.abs(tuv == null ? getOccupancy100(false) + : modCalc.calculate(tuv, false).getOccupancy100(false))); } return null; } @@ -443,35 +558,45 @@ P3 ptTemp = new P3(); private V3 v0; + /** + * get updated value for offset vector and for occupancy + */ @Override - public void setTempPoint(T3 a, T3 t456, float vibScale, float scale) { - if (!enabled) - return; - getModTemp(); - addTo(a, Float.NaN); - modTemp.calculate(t456, false).addTo(a, scale); + public T3 setCalcPoint(T3 pt, T3 t456, float vibScale, float scale) { + if (enabled) { + addTo(pt, Float.NaN); + getModCalc().calculate(t456, false).addTo(pt, scale); + //System.out.println("MS setTempPoint " + id + " v=" + vOcc); + // note: this does not include setting occValue + } + return pt; } - private void getModTemp() { - if (modTemp == null) { - modTemp = new ModulationSet(); - modTemp.id = id; - modTemp.tau = tau; - modTemp.spinOp = spinOp; - modTemp.mods = mods; - modTemp.gammaE = gammaE; - modTemp.modDim = modDim; - modTemp.gammaIinv = gammaIinv; - modTemp.sigma = sigma; - modTemp.r0 = r0; - modTemp.v0 = v0; - modTemp.vib = vib; - modTemp.symmetry = symmetry; - modTemp.rI = rI; - if (mxyz != null) { - modTemp.mxyz = new V3(); - } + private ModulationSet getModCalc() { + if (modCalc == null) { + modCalc = new ModulationSet(); + modCalc.id = id; + modCalc.tau = tau; + modCalc.spinOp = spinOp; + modCalc.mods = mods; + modCalc.gammaE = gammaE; + modCalc.modDim = modDim; + modCalc.gammaIinv = gammaIinv; + modCalc.sigma = sigma; + modCalc.r0 = r0; + modCalc.v0 = v0; + modCalc.vib = vib; + modCalc.symmetry = symmetry; + modCalc.rI = rI; + modCalc.fileOcc = fileOcc; + modCalc.occParams = occParams; + modCalc.occSiteMultiplicity = occSiteMultiplicity; + modCalc.nOps = nOps; + modCalc.enabled = true; + if (mxyz != null) + modCalc.mxyz = new V3(); } + return modCalc; } @Override @@ -548,11 +673,60 @@ && (mxyz.x != 0 || mxyz.y != 0 || mxyz.z != 0); } - private float[] axesLengths; + /** + * + * get the occupancy, first from the reader, then from renderer + * + * @param pt + * @param foccupancy + * @param siteMult or 0 is this is not relevant + * + * @return occupancy on [0,1] + */ + public float setOccupancy(double[] pt, double foccupancy, + double siteMult) { + occParams = pt; + fileOcc = foccupancy; + occSiteMultiplicity = siteMult; + return getOccupancy(); + } + + @Override + public int getOccupancy100(boolean isTemp) { + if (isCommensurate || Float.isNaN(vOcc)) + return Integer.MIN_VALUE; + if (!isTemp && !enabled) + return (int) (-fileOcc * 100); + if (isTemp && modCalc != null) { + modCalc.getOccupancy(); + return modCalc.getOccupancy100(false); + } + return (int) (occValue * 100); + } - float[] getAxesLengths() { - return (axesLengths == null ? (axesLengths = symmetry.getUnitCellParams()) - : axesLengths); + private float getOccupancy() { + double occ; + if (occAbsolute) { + // Crenel + occ = vOcc; + } else if (occParams == null) { + // cif Fourier + // _atom_site_occupancy + SUM + occ = fileOcc + vOcc; + } else if (occSiteMultiplicity > 0) { + // cif with m40 Fourier + // occ_site * (occ_0 + SUM) + double o_site = fileOcc * occSiteMultiplicity / nOps / occParams[1]; + occ = o_site * (occParams[1] + vOcc); + } else { + // m40 Fourier + // occ_site * (occ_0 + SUM) + occ = occParams[0] * (occParams[1] + vOcc); + } + // 49/50 is an important range for cutoffs -- we never return a value in this range + occ = (occ > 0.49 && occ < 0.50 ? 0.489 : Math.min(1, Math.max(0, occ))); + return occValue = (float) occ; } + } Modified: trunk/Jmol/src/org/jmol/util/Vibration.java =================================================================== --- trunk/Jmol/src/org/jmol/util/Vibration.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/util/Vibration.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -35,8 +35,9 @@ * @param t456 * @param scale * @param modulationScale + * @return pt */ - public void setTempPoint(T3 pt, T3 t456, float scale, float modulationScale) { + public T3 setCalcPoint(T3 pt, T3 t456, float scale, float modulationScale) { switch (modDim) { // case TYPE_DISPLACEMENT: // break; @@ -46,6 +47,7 @@ pt.scaleAdd2((float) (Math.cos(t456.x * twoPI) * scale), this, pt); break; } + return pt; } public void getInfo(Map<String, Object> info) { @@ -78,4 +80,12 @@ return x != 0 || y != 0 || z != 0; } + /** + * @param isTemp used only in ModulationSet + * @return Integer.MIN_VALUE if not applicable, occupancy if enabled, -occupancy if not enabled + */ + public int getOccupancy100(boolean isTemp) { + return Integer.MIN_VALUE; + } + } Modified: trunk/Jmol/src/org/jmol/viewer/GlobalSettings.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/GlobalSettings.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/viewer/GlobalSettings.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -454,10 +454,12 @@ int smallMoleculeMaxAtoms = 40000; boolean smartAromatic = true; boolean zeroBasedXyzRasmol = false; - public boolean legacyAutoBonding = false; + boolean legacyAutoBonding = false; public boolean legacyHAddition = false; - public boolean legacyJavaFloat = false; + public boolean legacyJavaFloat = false; // float/double issue with crystallographic symmetry before Jmol 14.2.5 + boolean modulateOccupancy = true; + //centering and perspective boolean allowRotateSelected = false; Modified: trunk/Jmol/src/org/jmol/viewer/JC.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/JC.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/viewer/JC.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -696,18 +696,6 @@ public final static int SHAPE_HOVER = 35; public final static int SHAPE_FRANK = 36; public final static int SHAPE_MAX = SHAPE_FRANK + 1; - - // ATOM_IN_FRAME simply associates an atom with the current model - // but doesn't necessarily mean it is visible - // ATOM_VIS_SET and ATOM_VISIBLE are checked once only for each atom per rendering - - public final static int ATOM_INFRAME = 1; - public final static int ATOM_VISSET = 2; - public final static int ATOM_VISIBLE = 4; - public final static int ATOM_NOTHIDDEN = 8; - public final static int ATOM_NOFLAGS = ~63; // all of the above, plus balls and sticks - public final static int ATOM_INFRAME_NOTHIDDEN = ATOM_INFRAME | ATOM_NOTHIDDEN; - public final static int ATOM_SHAPE_VIS_MASK = ~ATOM_INFRAME_NOTHIDDEN; public final static int getShapeVisibilityFlag(int shapeID) { return 16 << Math.min(shapeID, SHAPE_LAST_ATOM_VIS_FLAG); Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-05-03 18:46:39 UTC (rev 20476) @@ -14,8 +14,14 @@ TODO: remove HTML5 dependency on synchronous file loading (check SCRIPT command for problems) -Jmol.___JmolVersion="14.3.13_2015.05.02" +Jmol.___JmolVersion="14.3.13_2015.05.03" +new feature: for msCIF (modulated structure files), setting modulation or using vibration ON + now also indicates occupancy changes + + +JmolVersion="14.3.13_2015.05.02" + bug fix: color atoms property vxyz crashes Jmol if no vibrations bug fix: with msCIF, select subsystem=1 does not select anything bug fix: vibrations in trajectories not animating (14.3.6_2014.08.14) Modified: trunk/Jmol/src/org/jmol/viewer/ShapeManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/ShapeManager.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/viewer/ShapeManager.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -355,8 +355,8 @@ } /** - * Sets shape visibility flags, including ATOM_VIS_INFRAME - * and ATOM_VIS_NOTHIDDEN. + * Sets shape visibility flags, including ATOM_VIS_INFRAME and + * ATOM_VIS_NOTHIDDEN. * */ void setModelVisibility() { @@ -372,7 +372,7 @@ // so isTranslucent = isTranslucent || f() would NOT work. BS bs = vwr.getVisibleFramesBitSet(); - + // i=2 skips balls and sticks // as these are handled differently. @@ -381,32 +381,36 @@ for (int i = JC.SHAPE_MIN_HAS_SETVIS; i < JC.SHAPE_MAX_HAS_SETVIS; i++) if (shapes[i] != null) shapes[i].setModelVisibilityFlags(bs); - + // now check ATOM_IN_FRAME, and ATOM_NOTHIDDEN, VIS_BALLS_FLAG - -// todo: deleted atoms not showing up in state + + // todo: deleted atoms not showing up in state boolean showHydrogens = vwr.getBoolean(T.showhydrogens); BS bsDeleted = vwr.slm.bsDeleted; Atom[] atoms = ms.at; - for (int i = ms.ac; --i >= 0;) { - Atom atom = atoms[i]; - atom.shapeVisibilityFlags &= JC.ATOM_NOFLAGS; - if (bsDeleted != null && bsDeleted.get(i) || !showHydrogens - && atom.getElementNumber() == 1) - continue; - if (bs.get(atom.mi)) { - int f = JC.ATOM_INFRAME; - if (!ms.isAtomHidden(i)) { - f |= JC.ATOM_NOTHIDDEN; - if (atom.madAtom != 0) - f |= JC.VIS_BALLS_FLAG; - atom.setShapeVisibility(f, true); + ms.clearVisibleSets(); + if (atoms.length > 0) { + for (int i = ms.ac; --i >= 0;) { + Atom atom = atoms[i]; + atom.shapeVisibilityFlags &= Atom.ATOM_NOFLAGS; + if (bsDeleted != null && bsDeleted.get(i)) + continue; + if (bs.get(atom.mi)) { + int f = Atom.ATOM_INFRAME; + if (!ms.isAtomHidden(i) + && (showHydrogens || atom.getElementNumber() != 1)) { + f |= Atom.ATOM_NOTHIDDEN; + if (atom.madAtom != 0) + f |= JC.VIS_BALLS_FLAG; + atom.setShapeVisibility(f, true); + } } } } + setShapeVis(); + } - ms.clearVisibleSets(); - + private void setShapeVis() { //set clickability -- this enables measures and such for (int i = 0; i < JC.SHAPE_MAX; ++i) { Shape shape = shapes[i]; @@ -432,17 +436,19 @@ vwr.setAtomCoordsRelative(pt, bsAtoms); ptOffset.set(0, 0, 0); } - ms.getRenderable(bs); - Object[] vibrationVectors = ms.vibrations; + ms.getAtomsInFrame(bs); + Vibration[] vibrationVectors = ms.vibrations; boolean vibs = (vibrationVectors != null && tm.vibrationOn); + boolean checkOccupancy = (ms.bsModulated != null); Atom[] atoms = ms.at; + boolean haveMods = false; for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) { // note that this vibration business is not compatible with // PDB objects such as cartoons and traces, which // use Cartesian coordinates, not screen coordinates Atom atom = atoms[i]; P3i screen = (vibs && atom.hasVibration() ? tm.transformPtVib(atom, - (Vibration) vibrationVectors[i]) : tm.transformPt(atom)); + vibrationVectors[i]) : tm.transformPt(atom)); atom.sX = screen.x; atom.sY = screen.y; atom.sZ = screen.z; @@ -450,7 +456,24 @@ if (d == Atom.MAD_GLOBAL) d = (int) (vwr.getFloat(T.atoms) * 2000); atom.sD = (short) vwr.tm.scaleToScreen(screen.z, d); + if (checkOccupancy) { + int occ = vibrationVectors[i].getOccupancy100(vibs); + if (occ != Integer.MIN_VALUE) { + //System.out.println(atom + " " + occ); + haveMods = true; + atom.setShapeVisibility(Atom.ATOM_VISSET, false); + if (occ >= 0 && occ < 50) + atom.setShapeVisibility(Atom.ATOM_NOTHIDDEN | JC.VIS_BALLS_FLAG, + false); + else + atom.setShapeVisibility(Atom.ATOM_NOTHIDDEN + | (atom.madAtom > 0 ? JC.VIS_BALLS_FLAG : 0), true); + ms.occupancies[atom.i] = Math.abs(occ); + } + } } + if (haveMods) + setShapeVis(); GData gdata = vwr.gdata; if (tm.slabEnabled) { boolean slabByMolecule = vwr.getBoolean(T.slabbymolecule); Modified: trunk/Jmol/src/org/jmol/viewer/TransformManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/TransformManager.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/viewer/TransformManager.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -1365,7 +1365,7 @@ protected final P3 point3fScreenTemp = new P3(); protected final P3i point3iScreenTemp = new P3i(); - private final Point3fi ptVibTemp = new Point3fi(); + final Point3fi ptVibTemp = new Point3fi(); public boolean navigating = false; public int mode = MODE_STANDARD; @@ -1526,11 +1526,17 @@ ptVibTemp.setT(ptXYZ); return applyPerspective(getVibrationPoint(v, ptVibTemp, Float.NaN), ptXYZ); } - + + /** + * return + * @param v + * @param pt temporary value; also returned + * @param scale + * @return pt + */ public T3 getVibrationPoint(Vibration v, T3 pt, float scale) { - v.setTempPoint(pt, vibrationT, + return v.setCalcPoint(pt, vibrationT, (Float.isNaN(scale) ? vibrationScale : scale), vwr.g.modulationScale); - return pt; } public void transformPt3f(T3 ptXYZ, P3 screen) { Modified: trunk/Jmol/src/org/jmol/viewer/Viewer.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Viewer.java 2015-05-02 17:47:14 UTC (rev 20475) +++ trunk/Jmol/src/org/jmol/viewer/Viewer.java 2015-05-03 18:46:39 UTC (rev 20476) @@ -5052,9 +5052,6 @@ case T.legacyhaddition: // aargh -- Some atoms missed before Jmol 13.1.17 return g.legacyHAddition; - case T.legacyjavafloat: - // float/double issue with crystallographic symmetry before Jmol 14.2.5 - return g.legacyJavaFloat; case T.loggestures: return g.logGestures; case T.measureallmodels: @@ -5878,6 +5875,10 @@ private void setBooleanPropertyTok(String key, int tok, boolean value) { boolean doRepaint = true; switch (tok) { + case T.modulateoccupancy: + // 12.0.RC6 + g.modulateOccupancy = value; + break; case T.legacyjavafloat: // 14.3.5 g.legacyJavaFloat = value; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ One dashboard for servers and applications across Physical-Virtual-Cloud Widest out-of-the-box monitoring support with 50+ applications Performance metrics, stats and reports that give you Actionable Insights Deep dive visibility with transaction tracing using APM Insight. http://ad.doubleclick.net/ddm/clk/290420510;117567292;y _______________________________________________ Jmol-commits mailing list Jmol-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jmol-commits