From: <ha...@us...> - 2010-03-08 04:12:30
|
Revision: 12575 http://jmol.svn.sourceforge.net/jmol/?rev=12575&view=rev Author: hansonr Date: 2010-03-08 04:12:22 +0000 (Mon, 08 Mar 2010) Log Message: ----------- reader code; crystal reader for properties/vibrations of conventional cell. Modified Paths: -------------- trunk/Jmol/src/org/jmol/adapter/readers/cifpdb/PdbReader.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/AdfReader.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/GamessUKReader.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/GamessUSReader.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/GaussianReader.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/GaussianWfnReader.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/MOReader.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/PsiReader.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/QchemReader.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/SpartanSmolReader.java trunk/Jmol/src/org/jmol/adapter/readers/quantum/WebMOReader.java trunk/Jmol/src/org/jmol/adapter/readers/simple/AmpacReader.java trunk/Jmol/src/org/jmol/adapter/readers/simple/HyperChemReader.java trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlReader.java trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlVaspReader.java trunk/Jmol/src/org/jmol/adapter/readers/xtal/CrystalReader.java trunk/Jmol/src/org/jmol/adapter/readers/xtal/ShelxReader.java trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java trunk/Jmol/src/org/jmol/symmetry/SpaceGroup.java Modified: trunk/Jmol/src/org/jmol/adapter/readers/cifpdb/PdbReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/cifpdb/PdbReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/cifpdb/PdbReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -124,7 +124,6 @@ modelNumber = (bsModels == null ? modelNo : modelNumber + 1); if (!doGetModel(modelNumber)) return checkLastModel(); - iHaveAtoms = true; atomSetCollection.connectAll(maxSerial); if (atomCount > 0) applySymmetryAndSetTrajectory(); @@ -139,7 +138,7 @@ * actually supports this. So you can't concatinate PDB files the way you * can CIF files. --Bob Hanson 8/30/06 */ - if (isMultiModel && !iHaveAtoms) + if (isMultiModel && !doProcessLines) return true; if (isAtom) { getHeader = false; Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/AdfReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/AdfReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/AdfReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -83,7 +83,6 @@ || line.indexOf("G E O M E T R Y ***") >= 0) { if (!doGetModel(++modelNumber)) return checkLastModel(); - iHaveAtoms = true; readCoordinates(); return true; } @@ -91,7 +90,7 @@ readMolecularOrbitals(getTokens(symLine)[1]); return true; } - if (!iHaveAtoms) + if (!doProcessLines) return true; if (line.indexOf("Energy:") >= 0) { Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/GamessUKReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/GamessUKReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/GamessUKReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -55,10 +55,9 @@ return checkLastModel(); atomNames = new Vector(); readAtomsInBohrCoordinates(); - iHaveAtoms = true; return true; } - if (!iHaveAtoms) + if (!doProcessLines) return true; if (line.indexOf("FREQUENCY_INFO_WOULD_BE_HERE") >= 0) { // not implemented for readFrequencies(); Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/GamessUSReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/GamessUSReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/GamessUSReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -103,10 +103,9 @@ readAtomsInBohrCoordinates(); else readAtomsInAngstromCoordinates(); - iHaveAtoms = true; return true; } - if (!iHaveAtoms) + if (!doProcessLines) return true; if (line.indexOf("FREQUENCIES IN CM") >= 0) { readFrequencies(); Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/GaussianReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/GaussianReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/GaussianReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -130,10 +130,9 @@ + " equivalentAtomSet " + equivalentAtomSets + " calculation " + calculationNumber + " scan point " + scanPoint + line); readAtoms(); - iHaveAtoms = true; return false; } - if (!iHaveAtoms) + if (!doProcessLines) return true; if (line.startsWith(" Energy=")) { setEnergy(); Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/GaussianWfnReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/GaussianWfnReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/GaussianWfnReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -26,15 +26,11 @@ import org.jmol.adapter.smarter.*; - -import java.io.BufferedReader; -//import java.io.IOException; //import java.util.Hashtable; //import java.util.Vector; //import javax.vecmath.Vector3f; -//import org.jmol.api.JmolAdapter; //import org.jmol.util.Logger; /** @@ -78,28 +74,20 @@ TYPE ASSIGNMENTS 3 4 5 6 7 8 9 10 EXPONENTS 0.2068882D+04 0.3106496D+03 0.7068303D+02 0.1986108D+02 0.6299305D+01 */ - /** - * Reads a Collection of AtomSets from a BufferedReader. - * - * - * @param reader BufferedReader associated with the Gaussian output text. - **/ - public void readAtomSetCollection(BufferedReader reader) { -/* - this.reader = reader; - atomSetCollection = new AtomSetCollection("wfn"); - try { - readHeader(); - readAtoms(); - readBasis(); - readMolecularOrbitals(); - } catch (Exception e) { - setError(e); - } -*/ + protected void initializeReader() { + continuing = false; } + /* + public void initializeReader() throws Exception { + readHeader(); + readAtoms(); + readBasis(); + readMolecularOrbitals(); + } +*/ + /* private int nMo, nPrimitive; // GAUSSIAN 14 MOL ORBITALS 168 PRIMITIVES 6 NUCLEI Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/MOReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/MOReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/MOReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -106,7 +106,6 @@ final protected int HEADER_NONE = 0; protected void initializeReader() throws Exception { - iHaveAtoms = false; line = "\nNBOs in the AO basis:"; getNBOs = filterMO(); line = "\nNBOcharges"; Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/PsiReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/PsiReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/PsiReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -42,6 +42,8 @@ * -- no frequencies * -- no orbitals (Can't handle irreducible representations here.) * + * -- not processing specified model option in LOAD command + * **/ public class PsiReader extends MOReader { @@ -54,13 +56,17 @@ if (line .indexOf("-Geometry after Center-of-Mass shift and reorientation (a.u.):") >= 0) { readAtoms(true); // initial geometry - iHaveAtoms = true; + doProcessLines = true; + return true; } if (line - .indexOf("-Unique atoms in the canonical coordinate system (a.u.):") >= 0) + .indexOf("-Unique atoms in the canonical coordinate system (a.u.):") >= 0) { readUniqueAtoms(); - if (!iHaveAtoms) + doProcessLines = true; return true; + } + if (!doProcessLines) + return true; if (line.indexOf("New Cartesian Geometry in a.u.") >= 0) { readAtoms(false); // replaced with final geometry return true; Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/QchemReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/QchemReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/QchemReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -481,7 +481,7 @@ MOInfo info = new MOInfo(); info.ne = ne; info.label = spin[e]; - if (haveSym) info.symmetry = tokens[j]+tokens[j+1]; + if (haveSym) info.moSymmetry = tokens[j]+tokens[j+1]; moInfos[nMO] = info; nMO++; } @@ -654,7 +654,7 @@ if (restricted) label = "V"; else label = "V"+label; // keep spin information for the orbital } - mos[i].put("symmetry", moInfo.symmetry+" "+label +"("+(moid[i]+1)+")"); + mos[i].put("symmetry", moInfo.moSymmetry+" "+label +"("+(moid[i]+1)+")"); orbitals.addElement(mos[i]); } nMOs += nMO; @@ -667,6 +667,6 @@ protected class MOInfo { int ne = 0; // 0 or 1 String label = "???"; - String symmetry = "???"; + String moSymmetry = "???"; } } Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/SpartanSmolReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/SpartanSmolReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/SpartanSmolReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -54,7 +54,6 @@ bondData = ""; if (!doGetModel(++modelNumber)) return checkLastModel(); - iHaveAtoms = true; atomSetCollection.newAtomSet(); moData = new Hashtable(); if (modelNo == Integer.MIN_VALUE) { @@ -71,7 +70,7 @@ atomSetCollection.setAtomSetNumber(modelNo); return true; } - if (iHaveModelStatement && !iHaveAtoms) + if (iHaveModelStatement && !doProcessLines) return true; if ((line.indexOf("BEGIN") == 0)) { String lcline = line.toLowerCase(); Modified: trunk/Jmol/src/org/jmol/adapter/readers/quantum/WebMOReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/quantum/WebMOReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/quantum/WebMOReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -79,7 +79,6 @@ if (!doGetModel(++modelNumber)) return checkLastModel(); readMolecularOrbital(); - iHaveAtoms = true; return false; } return true; Modified: trunk/Jmol/src/org/jmol/adapter/readers/simple/AmpacReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/simple/AmpacReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/simple/AmpacReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -44,15 +44,16 @@ if (line.indexOf("CARTESIAN COORDINATES") >= 0) { if (!doGetModel(++modelNumber)) return checkLastModel(); - iHaveAtoms = true; readCoordinates(); return true; } - if (iHaveAtoms && line.indexOf("NET ATOMIC CHARGES") >= 0) { + if (!doProcessLines) + return true; + if (line.indexOf("NET ATOMIC CHARGES") >= 0) { readPartialCharges(); return true; } - if (iHaveAtoms && line.indexOf("VIBRATIONAL FREQUENCIES") >= 0) { + if (line.indexOf("VIBRATIONAL FREQUENCIES") >= 0) { readFrequencies(); return true; } Modified: trunk/Jmol/src/org/jmol/adapter/readers/simple/HyperChemReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/simple/HyperChemReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/simple/HyperChemReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -51,11 +51,10 @@ // we have reached the start of a molecule if (!doGetModel(++modelNumber)) return checkLastModel(); - iHaveAtoms = true; processMol(); return true; } - if (!iHaveAtoms) + if (!doProcessLines) return true; if (line.startsWith("atom ")) { Modified: trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -109,20 +109,15 @@ /////////////// file reader option ////////////// - public void readAtomSetCollection(BufferedReader reader) { - this.reader = reader; + public void initializeReader() throws Exception { XMLReader xmlReader = getXMLReader(); if (xmlReader == null) { atomSetCollection = new AtomSetCollection("xml", this); atomSetCollection.errorMessage = "No XML reader found"; return; } - try { - processXml(xmlReader); - } catch (Exception e) { - e.printStackTrace(); - atomSetCollection.errorMessage = "XML reader error: " + e.getMessage(); - } + processXml(xmlReader); + continuing = false; } private XMLReader getXMLReader() { Modified: trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlVaspReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlVaspReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlVaspReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -91,20 +91,19 @@ if (Logger.debugging) Logger.debug("xmlvasp: start " + localName); + if (!parent.continuing) + return; if ("structure".equals(localName)) { - if (modelRead && parent.isLastModel(modelNumber)) + if (!parent.doGetModel(++modelNumber)) { + parent.checkLastModel(); return; - readThisModel = parent.doGetModel(++modelNumber); - if (readThisModel) { - modelRead = true; - parent.setFractionalCoordinates(true); - atomSetCollection.setDoFixPeriodic(); - atomSetCollection.newAtomSet(); } + parent.setFractionalCoordinates(true); + atomSetCollection.setDoFixPeriodic(); + atomSetCollection.newAtomSet(); return; } - - if (!readThisModel) + if (!parent.doProcessLines) return; if ("v".equals(localName)) { Modified: trunk/Jmol/src/org/jmol/adapter/readers/xtal/CrystalReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/xtal/CrystalReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/xtal/CrystalReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -31,6 +31,7 @@ import org.jmol.util.Logger; import org.jmol.util.TextFormat; +import java.util.BitSet; import java.util.Vector; import javax.vecmath.Point3f; @@ -43,8 +44,9 @@ * Ingram Building, University of Kent, Canterbury, Kent, CT2 7NH United * Kingdom, pc...@ke... * - * @version 1.3 + * @version 1.4 * + * * for a specific model in the set, use * * load "xxx.out" n @@ -65,7 +67,16 @@ * * load "xxx.out" FILTER "novibrations" * - * TODO: fix atom counter when frequency are for fragment + * now allows reading of frequencies and atomic values with conventional + * as long as this is not an optimization. + * + * Piero-- + * + * Q: Is there a way to determine the conventional cell from the primitive + * cell if the original primitive cell parameters are known and the cell + * changes? Can we just scale it up? Can the symmetry change during a + * calculation? -- Bob + * * */ @@ -75,66 +86,73 @@ private boolean isPolymer = false; private boolean isSlab = false; private boolean isMolecular = false; - private boolean doReadAtoms = false; private boolean haveCharges = false; private boolean addVibrations = false; private int atomCount; private int[] atomFrag; + private BitSet bsPrimitiveAtomsIgnore; + private boolean isFreqCalc = false; protected void initializeReader() throws Exception { - isPrimitive = (filter == null || filter.indexOf("conv") < 0); + doProcessLines = false; + if (filter != null) + filter = filter.toLowerCase(); addVibrations = (filter == null || filter.indexOf("novib") < 0); - atomSetCollection.setAtomSetCollectionAuxiliaryInfo("unitCellType", - (isPrimitive ? "primitive" : "conventional")); setFractionalCoordinates(readHeader()); } - boolean iHaveDesiredModel; protected boolean checkLine() throws Exception { - // starting point for any calculation is the definition of the lattice - // parameters similar to the "data" statement of a CIF file - - //SHIFT OF THE ORIGIN : 3/4 1/4 0 - if (line.startsWith(" SHIFT OF THE ORIGIN")) { - readShift(); + if (line.contains("FRQFRQ")) { + isFreqCalc = true; return true; } - - if (line.startsWith(" LATTICE PARAMETER") - && (isPrimitive - && (line.contains("- PRIMITIVE") || line.contains("- BOHR")) || !isPrimitive - && line.contains("- CONVENTIONAL"))) { - if (!isPrimitive || doGetModel(++modelNumber)) { + if (!isPrimitive) { + if (line.startsWith(" SHIFT OF THE ORIGIN")) { + readShift(); + return true; + } + if (line.startsWith(" INPUT COORDINATES")) { + readInputCoords(); + return true; + } + } + + if (line.startsWith(" LATTICE PARAMETER")) { + boolean isConvLattice = line.contains("- CONVENTIONAL"); + if (isConvLattice) { + // skip if we want primitive and this is the conventional lattice + if (isPrimitive) + return true; + readCellParams(); + } else if (!isPrimitive && !havePrimitiveMapping) { + readPrimitiveMapping(); // just for properties + return true; + } + if (!doGetModel(++modelNumber)) + return checkLastModel(); + if (isPrimitive) { readCellParams(); - iHaveDesiredModel = checkLastModel(); - doReadAtoms = true; + } else if (modelNumber == 1) { + // done here } else { - if (iHaveDesiredModel) { + if (!isFreqCalc) { + // conventional cell and now the lattice has changed. + // ignore? Can we convert a new primitive cell to conventional cell? continuing = false; - return false; + Logger.error("Ignoring structure " + modelNumber + " due to FILTER \"conventional\""); } - doReadAtoms = false; } return true; } - if (!doReadAtoms) + if (!doProcessLines) return true; - if (!isPrimitive) { - if (line.startsWith(" INPUT COORDINATES")) { - readInputCoords(); - continuing = false; - // because if we are reading the conventional cell, - // there won't be anything else we can do here. - } - return true; - } - // from here on -- must be primitive - if (line.startsWith(" ATOMS IN THE ASYMMETRIC UNIT")) { - readFractionalCoords(); + if (isPrimitive) + readFractionalCoords(); return true; } + if (line.startsWith(" TOTAL ENERGY")) { readEnergy(); readLine(); @@ -150,16 +168,21 @@ return true; } - if (line.contains("VOLUME=") && line.contains("- DENSITY")) { + if (isPrimitive && line.contains("VOLUME=") && line.contains("- DENSITY")) { readVolumePrimCell(); return true; } - + if (line.startsWith(" MULLIKEN POPULATION ANALYSIS")) { readPartialCharges(); return true; } + if (line.startsWith(" TOTAL ATOMIC CHARGES")) { + readTotalAtomicCharges(); + return true; + } + if (line.startsWith(" FREQUENCIES COMPUTED ON A FRAGMENT")) { readFragments(); return true; @@ -168,6 +191,8 @@ if (addVibrations && line .contains("* CALCULATION OF PHONON FREQUENCIES AT THE GAMMA POINT.")) { + if (vInputCoords != null) + processInputCoords(); readFrequencies(); return true; } @@ -181,7 +206,6 @@ readMagneticMoments(); return true; } - return true; } @@ -226,27 +250,35 @@ */ private void readSpins() throws Exception { - String[] spins = new String[atomCount]; String data = ""; while (readLine() != null && line.indexOf("ALPHA") < 0) data += line; data = TextFormat.simpleReplace(data, "-", " -"); - String[] tokens = getTokens(data); - for (int i = 0, pt = 2; i < atomCount; i++, pt += 3) - spins[i] = tokens[pt]; - data = TextFormat.join(spins, '\n', 0); - atomSetCollection.setAtomSetAuxiliaryProperty("spin", data); + setData("spin", data, 2, 3); } private void readMagneticMoments() throws Exception { String data = ""; while (readLine() != null && line.indexOf("TTTTTT") < 0) data += line; - data = TextFormat.join(getTokens(data), '\n', 0); - atomSetCollection.setAtomSetAuxiliaryProperty("magneticMoment", data); + setData("magneticMoment", data, 0, 1); } + private void setData(String name, String data, int pt, int dp) { + String[] s = new String[atomCount]; + String[] tokens = getTokens(data); + for (int i = 0, j = 0; i < atomCount; i++, pt += dp) { + int iConv = getAtomIndexFromPrimitiveIndex(i); + if (iConv >= 0) + s[j++] = tokens[pt]; + } + data = TextFormat.join(s, '\n', 0); + atomSetCollection.setAtomSetAuxiliaryProperty(name, data); + } + protected void finalizeReader() throws Exception { + if (vInputCoords != null) + processInputCoords(); if (energy != null) setEnergy(); super.finalizeReader(); @@ -272,9 +304,17 @@ isSlab = (type.equals("SLAB CALCULATION")); } atomSetCollection.setAtomSetCollectionAuxiliaryInfo("symmetryType", type); + isPrimitive = (filter == null || filter.indexOf("conv") < 0); + if ((isPolymer || isSlab) && !isPrimitive) { + Logger.error("Cannot use FILTER \"conventional\" with POLYMER or SLAB"); + isPrimitive = true; + } + atomSetCollection.setAtomSetCollectionAuxiliaryInfo("unitCellType", + (isPrimitive ? "primitive" : "conventional")); + if (type.indexOf("MOLECULAR") >= 0) { - isMolecular = doReadAtoms = true; + isMolecular = doProcessLines = true; readLine(); atomSetCollection.setAtomSetCollectionAuxiliaryInfo( "molecularCalculationPointGroup", line.substring( @@ -293,27 +333,104 @@ if (isPolymer && !isPrimitive) { float a = parseFloat(line.substring(line.indexOf("CELL") + 4)); setUnitCell(a, -1, -1, 90, 90, 90); - return; - } - discardLinesUntilContains("GAMMA"); - String[] tokens = getTokens(readLine()); - if (isSlab) { - if (isPrimitive) - setUnitCell(parseFloat(tokens[0]), parseFloat(tokens[1]), -1, - parseFloat(tokens[3]), parseFloat(tokens[4]), parseFloat(tokens[5])); - else - setUnitCell(parseFloat(tokens[0]), parseFloat(tokens[1]), -1, 90, 90, - parseFloat(tokens[2])); - } else if (isPolymer) { - setUnitCell(parseFloat(tokens[0]), -1, -1, parseFloat(tokens[3]), - parseFloat(tokens[4]), parseFloat(tokens[5])); } else { - setUnitCell(parseFloat(tokens[0]), parseFloat(tokens[1]), - parseFloat(tokens[2]), parseFloat(tokens[3]), parseFloat(tokens[4]), - parseFloat(tokens[5])); + discardLinesUntilContains("GAMMA"); + String[] tokens = getTokens(readLine()); + if (isSlab) { + if (isPrimitive) + setUnitCell(parseFloat(tokens[0]), parseFloat(tokens[1]), -1, + parseFloat(tokens[3]), parseFloat(tokens[4]), + parseFloat(tokens[5])); + else + setUnitCell(parseFloat(tokens[0]), parseFloat(tokens[1]), -1, 90, 90, + parseFloat(tokens[2])); + } else if (isPolymer) { + setUnitCell(parseFloat(tokens[0]), -1, -1, parseFloat(tokens[3]), + parseFloat(tokens[4]), parseFloat(tokens[5])); + } else { + setUnitCell(parseFloat(tokens[0]), parseFloat(tokens[1]), + parseFloat(tokens[2]), parseFloat(tokens[3]), + parseFloat(tokens[4]), parseFloat(tokens[5])); + } } } + + private boolean havePrimitiveMapping; + private int[] primitiveToIndex; + + /** + * create arrays that map primitive atoms to conventional atoms + * in a 1:1 fashion. Creates: + * + * BitSet bsPrimitiveAtomsIgnore -- atoms that are not in base symmetry set + * int[] primitiveToIndex -- points to model-based atomIndex + * + * @throws Exception + */ + private void readPrimitiveMapping() throws Exception { + havePrimitiveMapping = true; + BitSet bsInputAtomsIgnore = new BitSet(); + int n = vInputCoords.size(); + int[] indexToPrimitive = new int[n]; + primitiveToIndex = new int[n]; + for (int i = 0; i < n; i++) + indexToPrimitive[i] = -1; + + discardLines(3); + while (readLine() != null && line.contains(" NOT IRREDUCIBLE")) { + // example HA_BULK_PBE_FREQ.OUT + // we remove unnecessary atoms. This is important, because + // these won't get properties, and we don't know exactly which + // other atom to associate with them. + + bsInputAtomsIgnore.set(parseInt(line.substring(21, 25)) - 1); + readLine(); + } + + // COORDINATES OF THE EQUIVALENT ATOMS + discardLines(3); + int iPrim = 0; + int nPrim = 0; + while (readLine() != null && line.indexOf("NUMBER") < 0) { + if (line.length() == 0) + continue; + nPrim++; + int iAtom = parseInt(line.substring(4, 8)) - 1; + if (indexToPrimitive[iAtom] >= 0) { + // more than one primitive atom is mapped to a given conventional atom. + // so we ignore all except the first in terms of getting frequency or + // other data. + if (bsPrimitiveAtomsIgnore == null) + bsPrimitiveAtomsIgnore = new BitSet(); + bsPrimitiveAtomsIgnore.set(iPrim); + } else { + indexToPrimitive[iAtom] = iPrim++; + } + } + + if (bsInputAtomsIgnore.nextSetBit(0) >= 0) + for (int i = n; --i >= 0;) { + if (bsInputAtomsIgnore.get(i)) + vInputCoords.remove(i); + } + atomCount = vInputCoords.size(); + // now reset primitiveToIndex + primitiveToIndex = new int[nPrim]; + for (int i = 0; i < nPrim; i++) + primitiveToIndex[i] = -1; + + for (int i = vInputCoords.size(); --i >= 0;) { + line = (String) vInputCoords.get(i); + int iConv = parseInt(line.substring(0, 4)) - 1; + iPrim = indexToPrimitive[iConv]; + if (iPrim >= 0) + primitiveToIndex[iPrim] = i; + } + + System.out.println(nPrim + " primitive atoms " + vInputCoords.size() + " conventionalAtoms"); + } + int atomIndexLast; /* @@ -377,19 +494,30 @@ return atomicNumber; } + private Vector vInputCoords; + /* * INPUT COORDINATES * - * ATOM AT. N. COORDINATES 1 12 0.000000000000E+00 0.000000000000E+00 - * 0.000000000000E+00 2 8 5.000000000000E-01 5.000000000000E-01 - * 5.000000000000E-01 + * ATOM AT. N. COORDINATES + * 1 12 0.000000000000E+00 0.000000000000E+00 0.000000000000E+00 + * 2 8 5.000000000000E-01 5.000000000000E-01 5.000000000000E-01 */ private void readInputCoords() throws Exception { + // we only store them, because we may want to delete some readLine(); readLine(); - while (readLine() != null && line.length() > 0) { + vInputCoords = new Vector(); + while (readLine() != null && line.length() > 0) + vInputCoords.add(line); + } + + private void processInputCoords() throws Exception { + // here we may have deleted unnecessary input coordinates + int atomCount = vInputCoords.size(); + for (int i = 0; i < atomCount; i++) { Atom atom = atomSetCollection.addNewAtom(); - String[] tokens = getTokens(); + String[] tokens = getTokens((String) vInputCoords.get(i)); int atomicNumber = getAtomicNumber(tokens[1]); float x = parseFloat(tokens[2]) + ptOriginShift.x; float y = parseFloat(tokens[3]) + ptOriginShift.y; @@ -405,6 +533,7 @@ setAtomCoord(atom, x, y, z); atom.elementSymbol = getElementSymbol(atomicNumber); } + vInputCoords = null; } private void newAtomSet() throws Exception { @@ -442,14 +571,42 @@ haveCharges = true; discardLines(3); Atom[] atoms = atomSetCollection.getAtoms(); - int i = atomSetCollection.getLastAtomSetAtomIndex(); + int i0 = atomSetCollection.getLastAtomSetAtomIndex(); + int iPrim = 0; while (readLine() != null && line.length() > 3) - if (line.charAt(3) != ' ') - atoms[i++].partialCharge = parseFloat(line.substring(9, 11)) - - parseFloat(line.substring(12, 18)); + if (line.charAt(3) != ' ') { + int iConv = getAtomIndexFromPrimitiveIndex(iPrim); + if (iConv >= 0) + atoms[i0 + iConv].partialCharge = parseFloat(line.substring(9, 11)) + - parseFloat(line.substring(12, 18)); + iPrim++; + } } + private float[] nuclearCharges; + private void readTotalAtomicCharges() throws Exception { + StringBuffer data = new StringBuffer(); + while (readLine() != null && !line.contains("T")) // TTTTT or SUMMED SPIN DENSITY + data.append(line); + String[] tokens = getTokens(data.toString()); + float[] charges = new float[tokens.length]; + if (nuclearCharges == null) + nuclearCharges = charges; + Atom[] atoms = atomSetCollection.getAtoms(); + int i0 = atomSetCollection.getLastAtomSetAtomIndex(); + for (int i = 0; i < charges.length; i++) { + int iConv = getAtomIndexFromPrimitiveIndex(i); + if (iConv >= 0) { + charges[i] = parseFloat(tokens[i]); + atoms[i0 + iConv].partialCharge = nuclearCharges[i] - charges[i]; + } + } + } + private int getAtomIndexFromPrimitiveIndex(int iPrim) { + return (primitiveToIndex == null ? iPrim : primitiveToIndex[iPrim]); + } + private void readFragments() throws Exception{ /* * 2 ( 8 O ) 3 ( 8 O ) 4 ( 8 O ) 85 ( 8 O ) 86 ( 8 O ) @@ -473,9 +630,12 @@ Sfrag = TextFormat.simpleReplace(Sfrag, "(", " ("); String[] tokens = getTokens(Sfrag); for (int i = 0, pos = 0; i < numAtomsFrag; i++, pos += 5) - atomFrag[i] = parseInt(tokens[pos]) - 1; + atomFrag[i] = getAtomIndexFromPrimitiveIndex(parseInt(tokens[pos]) - 1); + + // note: atomFrag[i] will be -1 if this atom is being ignored due to FILTER "conventional" + } - + private float[] frequencies; private String[] data; Modified: trunk/Jmol/src/org/jmol/adapter/readers/xtal/ShelxReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/xtal/ShelxReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/readers/xtal/ShelxReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -79,11 +79,10 @@ setFractionalCoordinates(true); atomSetCollection.newAtomSet(); atomSetCollection.setAtomSetName(line.substring(4).trim()); - iHaveAtoms = true; return true; } - if (!iHaveAtoms || lineLength < 3) + if (!doProcessLines || lineLength < 3) return true; if (unsupportedRecordTypes.indexOf(";" + command + ";") >= 0) Modified: trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/adapter/smarter/AtomSetCollectionReader.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -141,7 +141,7 @@ // protected/public state variables public int[] latticeCells; - protected boolean iHaveAtoms; + public boolean doProcessLines; public boolean iHaveUnitCell; public boolean iHaveSymmetryOperators; protected boolean doApplySymmetry; @@ -167,14 +167,14 @@ private boolean doConvertToFractional; private boolean fileCoordinatesAreFractional; protected boolean ignoreFileUnitCell; - private boolean ignoreFileSpaceGroupName; + protected boolean ignoreFileSpaceGroupName; private float symmetryRange; - private float[] notionalUnitCell; //0-5 a b c alpha beta gamma; 6-21 matrix c->f + protected float[] notionalUnitCell; //0-5 a b c alpha beta gamma; 6-21 matrix c->f private int[] firstLastStep; protected int desiredModelNumber = Integer.MIN_VALUE; private int lastModelNumber = Integer.MAX_VALUE; private int desiredSpaceGroupIndex = -1; - private SymmetryInterface symmetry; + protected SymmetryInterface symmetry; protected OutputStream os; /* @@ -200,12 +200,10 @@ public void readAtomSetCollectionFromDOM(Object DOMNode) { // XML readers only } - - ////////////// These next are optional ways of reading the file. - ////////////// Probably move toward this for future readers. - protected boolean continuing = true; - public void readAtomSetCollection(BufferedReader reader) { + public boolean continuing = true; + + final public void readAtomSetCollection(BufferedReader reader) { this.reader = reader; atomSetCollection = new AtomSetCollection(readerName, this); try { @@ -235,6 +233,30 @@ return true; } + public boolean checkLastModel() { + if (isLastModel(modelNumber) && doProcessLines) { + continuing = false; + return false; + } + doProcessLines = false; + return true; + } + + /** + * after reading a model, Q: Is this the last model? + * + * @param modelNumber + * @return Yes/No + */ + public boolean isLastModel(int modelNumber) { + return (desiredModelNumber > 0 || modelNumber >= lastModelNumber); + } + + public boolean doGetVibration(int vibrationNumber) { + // vibrationNumber is 1-based + return (desiredVibrationNumber <= 0 || vibrationNumber == desiredVibrationNumber); + } + protected void finalizeReader() throws Exception { applySymmetryAndSetTrajectory(); } @@ -402,7 +424,7 @@ } } - private boolean haveModel = false; + public boolean haveModel; public boolean doGetModel(int modelNumber) { // modelNumber is 1-based, but firstLastStep is 0-based boolean isOK = (bsModels == null ? desiredModelNumber < 1 || modelNumber == desiredModelNumber @@ -413,37 +435,15 @@ if (isOK && desiredModelNumber == 0) atomSetCollection.discardPreviousAtoms(); haveModel |= isOK; + if (isOK) + doProcessLines = true; return isOK; } - protected boolean checkLastModel() { - if (isLastModel(modelNumber) && iHaveAtoms) { - continuing = false; - return false; - } - iHaveAtoms = false; - return true; - } - - /** - * after reading a model, Q: Is this the last model? - * - * @param modelNumber - * @return Yes/No - */ - public boolean isLastModel(int modelNumber) { - return (desiredModelNumber > 0 || modelNumber >= lastModelNumber); - } - - public boolean doGetVibration(int vibrationNumber) { - // vibrationNumber is 1-based - return (desiredVibrationNumber <= 0 || vibrationNumber == desiredVibrationNumber); - } - private String previousSpaceGroup; private float[] previousUnitCell; - private void initializeSymmetry() { + protected void initializeSymmetry() { previousSpaceGroup = spaceGroup; previousUnitCell = notionalUnitCell; iHaveUnitCell = ignoreFileUnitCell; @@ -459,7 +459,7 @@ needToApplySymmetry = false; } - + protected void newAtomSet(String name) { if (atomSetCollection.getCurrentAtomSetIndex() >= 0) { atomSetCollection.newAtomSet(); @@ -477,7 +477,8 @@ int lastAtomCount = atomSetCollection.getLastAtomSetAtomCount(); atomSetCollection.cloneLastAtomSet(atomCount); if (atomSetCollection.haveUnitCell) { - iHaveUnitCell = needToApplySymmetry = true; + iHaveUnitCell = true; + needToApplySymmetry = true; spaceGroup = previousSpaceGroup; notionalUnitCell = previousUnitCell; } @@ -488,6 +489,7 @@ if (ignoreFileSpaceGroupName) return; spaceGroup = name.trim(); + Logger.info("Setting space group name to " + spaceGroup); } public void setSymmetryOperator(String xyz) { @@ -565,14 +567,14 @@ for (int i = 0; i < n; i++) if (Float.isNaN(notionalUnitCell[i])) return false; - newSymmetry().setUnitCell(notionalUnitCell); + getSymmetry().setUnitCell(notionalUnitCell); if (doApplySymmetry) doConvertToFractional = !fileCoordinatesAreFractional; //if (but not only if) applying symmetry do we force conversion return true; } - private SymmetryInterface newSymmetry() { + protected SymmetryInterface getSymmetry() { symmetry = (SymmetryInterface) Interface.getOptionInterface("symmetry.Symmetry"); return symmetry; } @@ -681,11 +683,7 @@ atomSetCollection.setLatticeCells(latticeCells, applySymmetryToBonds, doPackUnitCell); if (ignoreFileSpaceGroupName || !iHaveSymmetryOperators) { - SymmetryInterface symmetry = (SymmetryInterface) Interface - .getOptionInterface("symmetry.Symmetry"); - if (symmetry.createSpaceGroup(desiredSpaceGroupIndex, (spaceGroup - .indexOf("*") >= 0 ? "P1" : spaceGroup), notionalUnitCell, - atomSetCollection.doNormalize)) { + if (createSpaceGroup()) { atomSetCollection.setAtomSetSpaceGroupName(symmetry .getSpaceGroupName()); atomSetCollection.applySymmetry(symmetry); @@ -700,6 +698,12 @@ initializeSymmetry(); } + protected boolean createSpaceGroup() { + return getSymmetry().createSpaceGroup(desiredSpaceGroupIndex, (spaceGroup + .indexOf("*") >= 0 ? "P1" : spaceGroup), notionalUnitCell, + atomSetCollection.doNormalize); + } + public void setMOData(Hashtable moData) { atomSetCollection.setAtomSetAuxiliaryInfo("moData", moData); Vector orbitals = (Vector) moData.get("mos"); @@ -775,36 +779,38 @@ } /** - * Extracts a block of frequency data from a file. This block may be of two types -- - * either X Y Z across a row or each of X Y Z on a separate line. Data is presumed - * to be in fixed FORTRAN-like column format, not space-separated columns. + * Extracts a block of frequency data from a file. This block may be of two + * types -- either X Y Z across a row or each of X Y Z on a separate line. + * Data is presumed to be in fixed FORTRAN-like column format, not + * space-separated columns. * * @param iAtom0 - * the first atom to be assigned a frequency + * the first atom to be assigned a frequency * @param atomCount - * the number of atoms to be assigned + * the number of atoms to be assigned * @param modelAtomCount - * the number of atoms in each model + * the number of atoms in each model * @param ignore - * the frequencies to ignore because the user has selected - * only certain vibrations to be read or for whatever reason; - * length serves to set the number of frequencies to be read + * the frequencies to ignore because the user has selected only + * certain vibrations to be read or for whatever reason; length + * serves to set the number of frequencies to be read * @param isWide - * when TRUE, this is a table that has X Y Z for each mode within the same row; - * when FALSE, this is a table that has X Y Z for each mode on a separate line. + * when TRUE, this is a table that has X Y Z for each mode within the + * same row; when FALSE, this is a table that has X Y Z for each mode + * on a separate line. * @param col0 - * the column in which data starts + * the column in which data starts * @param colWidth - * the width of the data columns + * the width of the data columns * @param atomIndexes - * an array either null or indicating exactly which atoms get the frequencies - * (used by CrystalReader) + * an array either null or indicating exactly which atoms get the + * frequencies (used by CrystalReader) * @throws Exception */ - protected void fillFrequencyData(int iAtom0, int atomCount, int modelAtomCount, - boolean[] ignore, boolean isWide, - int col0, int colWidth, int[] atomIndexes) - throws Exception { + protected void fillFrequencyData(int iAtom0, int atomCount, + int modelAtomCount, boolean[] ignore, + boolean isWide, int col0, int colWidth, + int[] atomIndexes) throws Exception { boolean withSymmetry = (modelAtomCount != atomCount); if (atomIndexes != null) atomCount = atomIndexes.length; @@ -819,7 +825,7 @@ int dataPt = values.length - (isWide ? nFreq * 3 : nFreq) - 1; for (int j = 0; j < nFreq; j++) { ++dataPt; - String x = values[dataPt]; + String x = values[dataPt]; if (x.charAt(0) == ')') // AMPAC reader! x = x.substring(1); float vx = parseFloat(x); @@ -827,10 +833,14 @@ float vz = parseFloat(isWide ? values[++dataPt] : valuesZ[dataPt]); if (ignore[j]) continue; - int iAtom = iAtom0 + modelAtomCount * j + (atomIndexes == null ? atomPt : atomIndexes[atomPt]); + int iAtom = (atomIndexes == null ? atomPt : atomIndexes[atomPt]); + if (iAtom < 0) + continue; if (Logger.debugging) - Logger.debug("vib " + iAtom + "/" + j + ": " + vx + " " + vy + " " + vz); - atomSetCollection.addVibrationVector(iAtom, vx, vy, vz, withSymmetry); + Logger.debug("vib " + iAtom + "/" + j + ": " + vx + " " + vy + " " + + vz); + atomSetCollection.addVibrationVector(iAtom0 + modelAtomCount * j + + iAtom, vx, vy, vz, withSymmetry); } } } Modified: trunk/Jmol/src/org/jmol/symmetry/SpaceGroup.java =================================================================== --- trunk/Jmol/src/org/jmol/symmetry/SpaceGroup.java 2010-03-06 22:19:42 UTC (rev 12574) +++ trunk/Jmol/src/org/jmol/symmetry/SpaceGroup.java 2010-03-08 04:12:22 UTC (rev 12575) @@ -510,7 +510,7 @@ // Hall symbol - if (!haveExtension) // no extensions for Hall symbols + if (!haveExtension) for (i = lastIndex; --i >= 0;) { s = spaceGroupDefinitions[i]; if (s.hallSymbol.equals(name)) @@ -1214,7 +1214,7 @@ , new SpaceGroup("171;c6^4;p 62;p 62") , new SpaceGroup("172;c6^5;p 64;p 64") , new SpaceGroup("173;c6^6;p 63;p 6c") - , new SpaceGroup("173*;c6^6;p 63*;p 63") //nonstandard + , new SpaceGroup("173*;c6^6;p 63*;p 63 ") //nonstandard; space added so not identical to H-M P 63 , new SpaceGroup("174;c3h^1;p -6;p -6") , new SpaceGroup("175;c6h^1;p 6/m;-p 6") , new SpaceGroup("176;c6h^2;p 63/m;-p 6c") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |