
org.jmol.adapter.readers.cif.CifReader Maven / Gradle / Ivy
Show all versions of jmol Show documentation
/* $RCSfile$
* $Author: hansonr $
* $Date: 2006-10-20 07:48:25 -0500 (Fri, 20 Oct 2006) $
* $Revision: 5991 $
*
* Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org
*
* Contact: [email protected]
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jmol.adapter.readers.cif;
import org.jmol.adapter.smarter.AtomSetCollection;
import org.jmol.adapter.smarter.Atom;
import org.jmol.adapter.smarter.AtomSetCollectionReader;
import org.jmol.api.JmolAdapter;
import org.jmol.api.SymmetryInterface;
import org.jmol.java.BS;
import org.jmol.script.T;
import javajs.api.GenericCifDataParser;
import javajs.util.Lst;
import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;
import org.jmol.util.Logger;
import org.jmol.util.Vibration;
import javajs.util.Rdr;
import javajs.util.CifDataParser;
import javajs.util.P3;
import javajs.util.PT;
import javajs.util.V3;
/**
* A true line-free CIF file reader for CIF files.
*
* Subclasses of CIF -- mmCIF/PDBx (pre-initialized) and msCIF (initialized
* here)
*
* Note that a file can be a PDB file without being
*
* Added nonstandard mCIF (magnetic_ tags) 5/2/2014 note that PRELIM keys can be
* removed at some later time
*
*
*
* http://www.iucr.org/iucr-top/cif/
*
*
* http://www.iucr.org/iucr-top/cif/standard/cifstd5.html
*
* @author Miguel, Egon, and Bob ([email protected])
*
* symmetry added by Bob Hanson:
*
* setSpaceGroupName() setSymmetryOperator() setUnitCellItem()
* setFractionalCoordinates() setAtomCoord()
* applySymmetryAndSetTrajectory()
*
*/
public class CifReader extends AtomSetCollectionReader {
private static final String titleRecords = "__citation_title__publ_section_title__active_magnetic_irreps_details__";
private MSCifRdr mr;
// no need for reflection here -- the CIF reader is already
// protected by reflection
GenericCifDataParser parser;
private boolean filterAssembly;
private boolean allowRotations = true;
private boolean readIdeal = true;
private int configurationPtr = Integer.MIN_VALUE;
protected boolean useAuthorChainID = true;
protected String thisDataSetName = "", lastDataSetName;
private String chemicalName = "";
private String thisStructuralFormula = "";
private String thisFormula = "";
protected boolean iHaveDesiredModel;
protected boolean isMMCIF;
protected boolean isLigand;
boolean isMagCIF;
boolean haveHAtoms;
private String molecularType = "GEOM_BOND default";
private char lastAltLoc = '\0';
private boolean haveAromatic;
private int conformationIndex;
private int nMolecular = 0;
private String appendedData;
protected boolean skipping;
protected int nAtoms;
protected int ac;
private String auditBlockCode;
private String lastSpaceGroupName;
private boolean modulated;
protected boolean isCourseGrained;
boolean haveCellWaveVector;
private String latticeType = null;
private int modDim;
protected Map htGroup1;
protected int nAtoms0;
private int titleAtomSet = 1;
@Override
public void initializeReader() throws Exception {
initSubclass();
allowPDBFilter = true;
appendedData = (String) htParams.get("appendedData");
String conf = getFilter("CONF ");
if (conf != null)
configurationPtr = parseIntStr(conf);
isMolecular = checkFilterKey("MOLECUL") && !checkFilterKey("BIOMOLECULE"); // molecular; molecule
readIdeal = !checkFilterKey("NOIDEAL");
filterAssembly = checkFilterKey("$");
useAuthorChainID = !checkFilterKey("NOAUTHORCHAINS");
if (isMolecular) {
forceSymmetry(false);
molecularType = "filter \"MOLECULAR\"";
}
asc.checkSpecial = !checkFilterKey("NOSPECIAL");
allowRotations = !checkFilterKey("NOSYM");
if (strSupercell != null && strSupercell.indexOf(",") >= 0)
addCellType("conventional", strSupercell, true);
if (binaryDoc != null)
return; // mmtf
readCifData();
continuing = false;
}
protected void initSubclass() {
// for MMCifReader
}
private void readCifData() throws Exception {
/*
* Modified for 10.9.64 9/23/06 by Bob Hanson to remove as much as possible
* of line dependence. a loop could now go:
*
* blah blah blah loop_ _a _b _c 0 1 2 0 3 4 0 5 6 loop_......
*
* we don't actually check that any skipped loop has the proper number of
* data points --- some multiple of the number of data keys -- but other
* than that, we are checking here for proper CIF syntax, and Jmol will
* report if it finds data where a key is supposed to be.
*/
parser = new CifDataParser().set(this, null);
line = "";
while ((key = parser.peekToken()) != null)
if (!readAllData())
break;
if (appendedData != null) {
parser = ((GenericCifDataParser) getInterface("javajs.util.CifDataParser"))
.set(null, Rdr.getBR(appendedData));
while ((key = parser.peekToken()) != null)
if (!readAllData())
break;
}
}
private boolean readAllData() throws Exception {
if (key.startsWith("data_")) {
isLigand = false;
if (asc.atomSetCount == 0)
iHaveDesiredModel = false;
if (iHaveDesiredModel)
return false;
if (desiredModelNumber != Integer.MIN_VALUE)
appendLoadNote(null);
newModel(++modelNumber);
haveCellWaveVector = false;
if (auditBlockCode == null)
modulated = false;
if (!skipping) {
nAtoms0 = asc.ac;
processDataParameter();
nAtoms = asc.ac;
}
return true;
}
if (skipping && key.equals("_audit_block_code")) {
iHaveDesiredModel = false;
skipping = false;
}
isLoop = key.startsWith("loop_");
if (isLoop) {
if (skipping && !isMMCIF) {
parser.getTokenPeeked();
parser.skipLoop(false);
} else {
processLoopBlock();
}
return true;
}
// global_ and stop_ are reserved STAR keywords
// see http://www.iucr.org/iucr-top/lists/comcifs-l/msg00252.html
// http://www.iucr.org/iucr-top/cif/spec/version1.1/cifsyntax.html#syntax
// stop_ is not allowed, because nested loop_ is not allowed
// global_ is a reserved STAR word; not allowed in CIF
// ah, heck, let's just flag them as CIF ERRORS
/*
* if (key.startsWith("global_") || key.startsWith("stop_")) {
* tokenizer.getTokenPeeked(); continue; }
*/
if (key.indexOf("_") != 0) {
Logger.warn("CIF ERROR ? should be an underscore: " + key);
parser.getTokenPeeked();
} else if (!getData()) {
return true;
}
if (!skipping) {
key = parser.fixKey(key0 = key);
if (key.startsWith("_chemical_name") || key.equals("_chem_comp_name")) {
processChemicalInfo("name");
} else if (key.startsWith("_chemical_formula_structural")) {
processChemicalInfo("structuralFormula");
} else if (key.startsWith("_chemical_formula_sum")
|| key.equals("_chem_comp_formula")) {
processChemicalInfo("formula");
} else if (key.equals("_cell_modulation_dimension")) {
modDim = parseIntStr(data);
} else if (key.startsWith("_cell_") && key.indexOf("_commen_") < 0) {
processCellParameter();
} else if (key.startsWith("_atom_sites_fract_tran")) {
processUnitCellTransformMatrix();
} else if (key.startsWith("_audit")) {
if (key.equals("_audit_block_code")) {
auditBlockCode = parser.fullTrim(data).toUpperCase();
appendLoadNote(auditBlockCode);
if (htAudit != null && auditBlockCode.contains("_MOD_")) {
String key = PT.rep(auditBlockCode, "_MOD_", "_REFRNCE_");
if (asc.setSymmetry((SymmetryInterface) htAudit.get(key)) != null) {
unitCellParams = asc.getSymmetry().getUnitCellParams();
iHaveUnitCell = true;
}
} else if (htAudit != null) {
if (symops != null)
for (int i = 0; i < symops.size(); i++)
setSymmetryOperator(symops.get(i));
}
if (lastSpaceGroupName != null)
setSpaceGroupName(lastSpaceGroupName);
} else if (key.equals("_audit_creation_date")) {
symmetry = null;
}
} else if (key.equals(singleAtomID)) {
readSingleAtom();
} else if (key.startsWith("_symmetry_space_group_name_h-m")
|| key.startsWith("_symmetry_space_group_name_hall")
|| key.startsWith("_space_group_name") || key.contains("_ssg_name")
|| key.contains("_magn_name") || key.contains("_bns_name") // PRELIM
) {
processSymmetrySpaceGroupName();
} else if (key.startsWith("_space_group_transform")) {
processUnitCellTransform();
} else if (key.contains("_database_code")) {
addModelTitle("ID");
} else if (titleRecords.contains("_" + key + "__")) {
addModelTitle("TITLE");
} else {
processSubclassEntry();
}
}
return true;
}
private void addModelTitle(String key) {
if (asc.atomSetCount > titleAtomSet)
appendLoadNote("\nMODEL: " + (titleAtomSet = asc.atomSetCount));
appendLoadNote(key + ": " + parser.fullTrim(data));
}
protected void processSubclassEntry() throws Exception {
if (modDim > 0)
getModulationReader().processEntry();
}
private void processUnitCellTransform() {
data = PT.replaceAllCharacters(data, " ", "");
if (key.contains("_from_parent"))
addCellType("parent", data, true);
else if (key.contains("_to_standard"))
addCellType("standard", data, false);
appendLoadNote(key + ": " + data);
}
private Map htCellTypes;
private void addCellType(String type, String data, boolean isFrom) {
if (htCellTypes == null)
htCellTypes = new Hashtable();
if (data.startsWith("!")) {
data = data.substring(1);
isFrom = !isFrom;
}
String cell = (isFrom ? "!" : "") + data;
htCellTypes.put(type, cell);
if (type.equalsIgnoreCase(strSupercell)) {
strSupercell = cell;
htCellTypes.put("conventional", (isFrom ? "" : "!") + data);
}
}
/**
* No need for anything other than the atom name and symbol; coordinates will
* be (0 0 0), and no other information is needed.
*/
private void readSingleAtom() {
Atom atom = new Atom();
atom.set(0, 0, 0);
atom.atomName = parser.fullTrim(data);
atom.getElementSymbol();
asc.addAtom(atom);
}
private MSCifRdr getModulationReader() throws Exception {
return (mr == null ? initializeMSCIF() : mr);
}
private MSCifRdr initializeMSCIF() throws Exception {
if (mr == null)
ms = mr = (MSCifRdr) getInterface("org.jmol.adapter.readers.cif.MSCifRdr");
modulated = (mr.initialize(this, modDim) > 0);
return mr;
}
public Map modelMap;
protected void newModel(int modelNo) throws Exception {
skipping = !doGetModel(modelNumber = modelNo, null);
if (skipping) {
if (!isMMCIF)
parser.getTokenPeeked();
return;
}
chemicalName = "";
thisStructuralFormula = "";
thisFormula = "";
iHaveDesiredModel = isLastModel(modelNumber);
if (isCourseGrained)
asc.setCurrentModelInfo("courseGrained", Boolean.TRUE);
if (nAtoms0 == asc.ac) {
// we found no atoms -- must revert
modelNumber--;
haveModel = false;
asc.removeCurrentAtomSet();
} else {
applySymmetryAndSetTrajectory();
}
}
@Override
protected void finalizeSubclassReader() throws Exception {
// added check for final data_global
if (asc.iSet > 0 && asc.getAtomSetAtomCount(asc.iSet) == 0)
asc.atomSetCount--;
else if (!isMMCIF || !finalizeSubclass())
applySymmetryAndSetTrajectory();
int n = asc.atomSetCount;
if (n > 1)
asc.setCollectionName("");
finalizeReaderASCR();
addHeader();
if (haveAromatic)
addJmolScript("calculate aromatic");
}
protected void addHeader() {
String header = parser.getFileHeader();
if (header.length() > 0) {
String s = setLoadNote();
appendLoadNote(null);
appendLoadNote(header);
appendLoadNote(s);
setLoadNote();
asc.setInfo("fileHeader", header);
}
}
protected boolean finalizeSubclass() throws Exception {
// MMCifReader only
return false;
}
@Override
public void doPreSymmetry() throws Exception {
if (magCenterings != null)
addLatticeVectors();
if (modDim > 0)
getModulationReader().setModulation(false, null);
if (isMagCIF) {
asc.getXSymmetry().scaleFractionalVibs();
vibsFractional = true;
//if (isMagCIF) {
// set fractional; note that this will be set to Cartesians later
}
}
@Override
public void applySymmetryAndSetTrajectory() throws Exception {
// This speeds up calculation, because no crosschecking
// No special-position atoms in mmCIF files, because there will
// be no center of symmetry, no rotation-inversions,
// no atom-centered rotation axes, and no mirror or glide planes.
if (isMMCIF)
asc.checkSpecial = false;
boolean doCheckBonding = doCheckUnitCell && !isMMCIF;
if (isMMCIF) {
int modelIndex = asc.iSet;
asc.setCurrentModelInfo(
"PDB_CONECT_firstAtom_count_max",
new int[] { asc.getAtomSetAtomIndex(modelIndex),
asc.getAtomSetAtomCount(modelIndex), maxSerial });
}
if (htCellTypes != null) {
for (Entry e : htCellTypes.entrySet())
asc.setCurrentModelInfo("unitcell_" + e.getKey(), e.getValue());
htCellTypes = null;
}
if (!haveCellWaveVector)
modDim = 0;
if (doApplySymmetry && !iHaveFractionalCoordinates)
fractionalizeCoordinates(true);
applySymTrajASCR();
if (doCheckBonding && (bondTypes.size() > 0 || isMolecular))
setBondingAndMolecules();
asc.setCurrentModelInfo("fileHasUnitCell", Boolean.TRUE);
asc.xtalSymmetry = null;
}
@Override
protected void finalizeSubclassSymmetry(boolean haveSymmetry)
throws Exception {
// called by applySymTrajASCR
// just for modulated, audit block, and magnetic structures
SymmetryInterface sym = (haveSymmetry ? asc.getXSymmetry()
.getBaseSymmetry() : null);
if (modDim > 0 && sym != null) {
addLatticeVectors();
asc.setTensors();
getModulationReader().setModulation(true, sym);
mr.finalizeModulation();
}
if (isMagCIF) {
asc.setNoAutoBond();
if (sym != null) {
addJmolScript("vectors on;vectors 0.15;");
int n = asc.getXSymmetry().setSpinVectors();
appendLoadNote(n
+ " magnetic moments - use VECTORS ON/OFF or VECTOR MAX x.x or SELECT VXYZ>0");
}
}
if (sym != null && auditBlockCode != null
&& auditBlockCode.contains("REFRNCE")) {
if (htAudit == null)
htAudit = new Hashtable();
htAudit.put(auditBlockCode, sym);
}
}
////////////////////////////////////////////////////////////////
// processing methods
////////////////////////////////////////////////////////////////
private Hashtable htAudit;
private Lst symops;
/**
* initialize a new atom set
*
*/
private void processDataParameter() {
bondTypes.clear();
parser.getTokenPeeked();
thisDataSetName = (key.length() < 6 ? "" : key.substring(5));
if (thisDataSetName.length() > 0)
nextAtomSet();
if (debugging)
Logger.debug(key);
}
protected void nextAtomSet() {
asc.setCurrentModelInfo("isCIF", Boolean.TRUE);
if (asc.iSet >= 0) {
// note that there can be problems with multi-data mmCIF sets each with
// multiple models; and we could be loading multiple files!
if (isMMCIF)
setModelPDB(true); // first model can be missed
asc.newAtomSet();
if (isMMCIF)
setModelPDB(true);
} else {
asc.setCollectionName(thisDataSetName);
}
}
/**
* reads some of the more interesting info into specific atomSetAuxiliaryInfo
* elements
*
* @param type
* "name" "formula" etc.
* @return data
* @throws Exception
*/
private String processChemicalInfo(String type) throws Exception {
if (type.equals("name")) {
chemicalName = data = parser.fullTrim(data);
appendLoadNote(chemicalName);
if (!data.equals("?"))
asc.setInfo("modelLoadNote", data);
} else if (type.equals("structuralFormula")) {
thisStructuralFormula = data = parser.fullTrim(data);
} else if (type.equals("formula")) {
thisFormula = data = parser.fullTrim(data);
if (thisFormula.length() > 1)
appendLoadNote(thisFormula);
}
if (debugging) {
Logger.debug(type + " = " + data);
}
return data;
}
// _space_group.magn_ssg_name_BNS "P2_1cn1'(0,0,g)000s"
// _space_group.magn_ssg_number_BNS 33.1.9.5.m145.?
// _space_group.magn_point_group "mm21'"
/**
* done by AtomSetCollectionReader
*
* @throws Exception
*/
private void processSymmetrySpaceGroupName() throws Exception {
if (key.indexOf("_ssg_name") >= 0) {
modulated = true;
latticeType = data.substring(0, 1);
} else if (modulated) {
return;
}
data = parser.toUnicode(data);
setSpaceGroupName(lastSpaceGroupName = (key.indexOf("h-m") > 0 ? "HM:"
: modulated ? "SSG:" : key.indexOf("bns") >= 0 ? "BNS:" : key
.indexOf("hall") >= 0 ? "Hall:" : "")
+ data);
}
private void addLatticeVectors() {
lattvecs = null;
if (magCenterings != null) {
// could be x+1/2,y+1/2,z,+1
// or x+0.5,y+0.5,z,+1
// or 0.5+x,0.5+y,z,+1
//
latticeType = "Magnetic";
lattvecs = new Lst();
for (int i = 0; i < magCenterings.size(); i++) {
String s = magCenterings.get(i);
float[] f = new float[modDim + 4];
if (s.indexOf("x1") >= 0)
for (int j = 1; j <= modDim + 3; j++)
s = PT.rep(s, "x" + j, "");
String[] tokens = PT.split(PT.replaceAllCharacters(s, "xyz+", ""), ",");
int n = 0;
for (int j = 0; j < tokens.length; j++) {
s = tokens[j].trim();
if (s.length() == 0)
continue;
if ((f[j] = PT.parseFloatFraction(s)) != 0)
n++;
}
if (n >= 2) // needs to have an x y or z as well as a +/-1;
lattvecs.addLast(f);
}
magCenterings = null;
} else if (latticeType != null && "ABCFI".indexOf(latticeType) >= 0) {
lattvecs = new Lst();
try {
ms.addLatticeVector(lattvecs, latticeType);
} catch (Exception e) {
// n/a
}
}
if (lattvecs != null && lattvecs.size() > 0
&& asc.getSymmetry().addLatticeVectors(lattvecs))
appendLoadNote("Note! " + lattvecs.size()
+ " symmetry operators added for lattice centering " + latticeType);
latticeType = null;
}
/**
* unit cell parameters -- two options, so we use MOD 6
*
* @throws Exception
*/
private void processCellParameter() throws Exception {
for (int i = JmolAdapter.cellParamNames.length; --i >= 0;)
if (key.equals(JmolAdapter.cellParamNames[i])) {
setUnitCellItem(i, parseFloatStr(data));
return;
}
}
final private static String[] TransformFields = { "x[1][1]", "x[1][2]",
"x[1][3]", "r[1]", "x[2][1]", "x[2][2]", "x[2][3]", "r[2]", "x[3][1]",
"x[3][2]", "x[3][3]", "r[3]", };
/**
*
* the PDB transformation matrix cartesian --> fractional
*
* @throws Exception
*/
private void processUnitCellTransformMatrix() throws Exception {
/*
* PDB:
SCALE1 .024414 0.000000 -.000328 0.00000
SCALE2 0.000000 .053619 0.000000 0.00000
SCALE3 0.000000 0.000000 .044409 0.00000
* CIF:
_atom_sites.fract_transf_matrix[1][1] .024414
_atom_sites.fract_transf_matrix[1][2] 0.000000
_atom_sites.fract_transf_matrix[1][3] -.000328
_atom_sites.fract_transf_matrix[2][1] 0.000000
_atom_sites.fract_transf_matrix[2][2] .053619
_atom_sites.fract_transf_matrix[2][3] 0.000000
_atom_sites.fract_transf_matrix[3][1] 0.000000
_atom_sites.fract_transf_matrix[3][2] 0.000000
_atom_sites.fract_transf_matrix[3][3] .044409
_atom_sites.fract_transf_vector[1] 0.00000
_atom_sites.fract_transf_vector[2] 0.00000
_atom_sites.fract_transf_vector[3] 0.00000
*/
float v = parseFloatStr(data);
if (Float.isNaN(v))
return;
//could enable EM box: unitCellParams[0] = 1;
for (int i = 0; i < TransformFields.length; i++) {
if (key.indexOf(TransformFields[i]) >= 0) {
setUnitCellItem(6 + i, v);
return;
}
}
}
////////////////////////////////////////////////////////////////
// non-loop_ processing
////////////////////////////////////////////////////////////////
String key, key0;
String data;
private boolean isLoop;
/**
*
* @return TRUE if data, even if ''; FALSE if '.' or '?' or eof.
*
* @throws Exception
*/
private boolean getData() throws Exception {
key = parser.getTokenPeeked();
data = parser.getNextToken();
//if (debugging && data != null && data.charAt(0) != '\0')
//Logger.debug(key + " " + data);
if (data == null) {
Logger.warn("CIF ERROR ? end of file; data missing: " + key);
return false;
}
return (data.length() == 0 || data.charAt(0) != '\0');
}
////////////////////////////////////////////////////////////////
// loop_ processing
////////////////////////////////////////////////////////////////
/**
* processes loop_ blocks of interest or skips the data
*
* @throws Exception
*/
protected void processLoopBlock() throws Exception {
parser.getTokenPeeked(); //loop_
key = parser.peekToken();
if (key == null)
return;
key = parser.fixKey(key0 = key);
if (modDim > 0)
switch (getModulationReader().processLoopBlock()) {
case 0:
break;
case -1:
parser.skipLoop(false);
//$FALL-THROUGH$
case 1:
return;
}
boolean isLigand = false;
if (key.startsWith(FAMILY_ATOM)
|| (isLigand = key.equals("_chem_comp_atom_comp_id"))) {
if (!processAtomSiteLoopBlock(isLigand))
return;
if (thisDataSetName.equals("global"))
asc.setCollectionName(thisDataSetName = chemicalName);
if (!thisDataSetName.equals(lastDataSetName)) {
asc.setAtomSetName(thisDataSetName);
lastDataSetName = thisDataSetName;
}
asc.setCurrentModelInfo("chemicalName", chemicalName);
asc.setCurrentModelInfo("structuralFormula", thisStructuralFormula);
asc.setCurrentModelInfo("formula", thisFormula);
return;
}
if (key.startsWith(FAMILY_SGOP) || key.startsWith("_symmetry_equiv_pos")
|| key.startsWith("_symmetry_ssg_equiv")) {
if (ignoreFileSymmetryOperators) {
Logger.warn("ignoring file-based symmetry operators");
parser.skipLoop(false);
} else {
processSymmetryOperationsLoopBlock();
}
return;
}
if (key.startsWith("_citation")) {
processCitationListBlock();
return;
}
if (key.startsWith("_atom_type")) {
processAtomTypeLoopBlock();
return;
}
if ((isMolecular || !doApplySymmetry) && key.startsWith("_geom_bond")) {
processGeomBondLoopBlock();
return;
}
if (processSubclassLoopBlock())
return;
if (key.equals("_propagation_vector_seq_id")) {// Bilbao mCIF
addMore();
return;
}
parser.skipLoop(false);
}
protected boolean processSubclassLoopBlock() throws Exception {
return false;
}
private void addMore() {
String str;
int n = 0;
try {
while ((str = parser.peekToken()) != null && str.charAt(0) == '_') {
parser.getTokenPeeked();
n++;
}
int m = 0;
String s = "";
while ((str = parser.getNextDataToken()) != null) {
s += str + (m % n == 0 ? "=" : " ");
if (++m % n == 0) {
appendUunitCellInfo(s.trim());
s = "";
}
}
} catch (Exception e) {
}
}
protected int fieldProperty(int i) {
return (i >= 0 && (field = parser.getColumnData(i)).length() > 0
&& (firstChar = field.charAt(0)) != '\0' ? col2key[i] : NONE);
}
int[] col2key = new int[CifDataParser.KEY_MAX]; // 100
int[] key2col = new int[CifDataParser.KEY_MAX];
String field;
protected char firstChar = '\0';
/**
* sets up arrays and variables for tokenizer.getData()
*
* @param fields
* @throws Exception
*/
void parseLoopParameters(String[] fields) throws Exception {
parser.parseDataBlockParameters(fields, isLoop ? null : key0, data,
key2col, col2key);
}
void parseLoopParametersFor(String key, String[] fields) throws Exception {
// just once for static fields
// first field must start with * if any do
if (fields[0].charAt(0) == '*')
for (int i = fields.length; --i >= 0;)
if (fields[i].charAt(0) == '*')
fields[i] = key + fields[i].substring(1);
parseLoopParameters(fields);
}
/**
*
* used for turning off fractional or nonfractional coord.
*
* @param fieldIndex
*/
private void disableField(int fieldIndex) {
int i = key2col[fieldIndex];
if (i != NONE)
col2key[i] = NONE;
}
////////////////////////////////////////////////////////////////
// atom type data
////////////////////////////////////////////////////////////////
private Map htOxStates;
private Lst