Java tutorial
/** * Title: Force Field X. * * Description: Force Field X - Software for Molecular Biophysics. * * Copyright: Copyright (c) Michael J. Schnieders 2001-2015. * * This file is part of Force Field X. * * Force Field X is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 as published by * the Free Software Foundation. * * Force Field X 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 General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * Linking this library statically or dynamically with other modules is making a * combined work based on this library. Thus, the terms and conditions of the * GNU General Public License cover the whole combination. * * As a special exception, the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent modules, and * to copy and distribute the resulting executable under terms of your choice, * provided that you also meet, for each linked independent module, the terms * and conditions of the license of that module. An independent module is a * module which is not derived from or based on this library. If you modify this * library, you may extend this exception to your version of the library, but * you are not obligated to do so. If you do not wish to do so, delete this * exception statement from your version. */ package ffx.xray; import java.io.DataInputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.lang3.StringUtils; import static org.apache.commons.math3.util.FastMath.cos; import static org.apache.commons.math3.util.FastMath.sin; import static org.apache.commons.math3.util.FastMath.toRadians; import ffx.crystal.Crystal; import ffx.crystal.HKL; import ffx.crystal.ReflectionList; import ffx.crystal.Resolution; import ffx.crystal.SpaceGroup; import ffx.numerics.ComplexNumber; import ffx.xray.MTZWriter.MTZType; /** * This class parses CCP4 MTZ files.<br> * * @author Timothy D. Fenn<br> * @see <a href="http://www.ccp4.ac.uk/html/maplib.html" target="_blank">CCP4 * map format</a> * * @see <a href="http://www.ccp4.ac.uk/dist/html/library.html" * target="_blank">CCP4 library documentation</a> * @see <a href="http://www.ccp4.ac.uk/html/maplib.html" target="_blank">CCP4 * map format</a> * * @see <a href="http://www.ccp4.ac.uk/dist/html/library.html" * target="_blank">CCP4 library documentation</a> * */ public class MTZFilter implements DiffractionFileFilter { private static final Logger logger = Logger.getLogger(MTZFilter.class.getName()); private class Column { public String label; public char type; public int id; public double min, max; } private class Dataset { public String project; public String dataset; public double lambda; public double[] cell = new double[6]; } private static enum Header { VERS, TITLE, NCOL, SORT, SYMINF, SYMM, RESO, VALM, COL, COLUMN, NDIF, PROJECT, CRYSTAL, DATASET, DCELL, DWAVEL, BATCH, END, NOVALUE; public static Header toHeader(String str) { try { return valueOf(str); } catch (Exception ex) { return NOVALUE; } } } final private ArrayList<Column> columns = new ArrayList<>(); final private ArrayList<Dataset> datasets = new ArrayList<>(); private boolean headerParsed = false; private String title; private String foString, sigfoString, rfreeString; private int h, k, l, fo, sigfo, rfree; private int fplus, sigfplus, fminus, sigfminus, rfreeplus, rfreeminus; private int fc, phic, fs, phis; private int dsetoffset = 1; public int nColumns; public int nReflections; public int nBatches; public int sgnum; public String spaceGroupName; public double resLow; public double resHigh; /** * <p> * Constructor for MTZFilter.</p> */ public MTZFilter() { } /** * {@inheritDoc} */ @Override public ReflectionList getReflectionList(File mtzFile) { return getReflectionList(mtzFile, null); } /** * {@inheritDoc} */ @Override public ReflectionList getReflectionList(File mtzFile, CompositeConfiguration properties) { ByteOrder b = ByteOrder.nativeOrder(); FileInputStream fis; DataInputStream dis; try { fis = new FileInputStream(mtzFile); dis = new DataInputStream(fis); byte headeroffset[] = new byte[4]; byte bytes[] = new byte[80]; int offset = 0; // eat "MTZ" title dis.read(bytes, offset, 4); String mtzstr = new String(bytes); // header offset dis.read(headeroffset, offset, 4); // machine stamp dis.read(bytes, offset, 4); ByteBuffer bb = ByteBuffer.wrap(bytes); int stamp = bb.order(ByteOrder.BIG_ENDIAN).getInt(); String stampstr = Integer.toHexString(stamp); switch (stampstr.charAt(0)) { case '1': case '3': if (b.equals(ByteOrder.LITTLE_ENDIAN)) { b = ByteOrder.BIG_ENDIAN; } break; case '4': if (b.equals(ByteOrder.BIG_ENDIAN)) { b = ByteOrder.LITTLE_ENDIAN; } break; } bb = ByteBuffer.wrap(headeroffset); int headeroffseti = bb.order(b).getInt(); // skip to header and parse dis.skipBytes((headeroffseti - 4) * 4); for (Boolean parsing = true; parsing; dis.read(bytes, offset, 80)) { mtzstr = new String(bytes); parsing = parseHeader(mtzstr); } } catch (EOFException eof) { System.out.println("EOF reached "); } catch (IOException ioe) { System.out.println("IO Exception: " + ioe.getMessage()); return null; } // column identifiers foString = sigfoString = rfreeString = null; if (properties != null) { foString = properties.getString("fostring", null); sigfoString = properties.getString("sigfostring", null); rfreeString = properties.getString("rfreestring", null); } h = k = l = fo = sigfo = rfree = -1; fplus = sigfplus = fminus = sigfminus = rfreeplus = rfreeminus = -1; fc = phic = -1; boolean print = false; parseColumns(print); parseFcColumns(print); if (fo < 0 && fplus < 0 && sigfo < 0 && sigfplus < 0 && fc < 0 && phic < 0) { logger.info( " The MTZ header contains insufficient information to generate the reflection list.\n For non-default column labels set fostring/sigfostring in the properties file."); return null; } Column c; if (fo > 0) { c = (Column) columns.get(fo); } else if (fplus > 0) { c = (Column) columns.get(fplus); } else { c = (Column) columns.get(fc); } Dataset d = (Dataset) datasets.get(c.id - dsetoffset); if (logger.isLoggable(Level.INFO)) { StringBuilder sb = new StringBuilder(); sb.append(String.format("\n Reading %s\n\n", mtzFile.getName())); sb.append(String.format(" Setting up reflection list based on MTZ file.\n")); sb.append(String.format(" Space group number: %d (name: %s)\n", sgnum, SpaceGroup.spaceGroupNames[sgnum - 1])); sb.append(String.format(" Resolution: %8.3f\n", 0.999999 * resHigh)); sb.append(String.format(" Cell: %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n", d.cell[0], d.cell[1], d.cell[2], d.cell[3], d.cell[4], d.cell[5])); logger.info(sb.toString()); } Crystal crystal = new Crystal(d.cell[0], d.cell[1], d.cell[2], d.cell[3], d.cell[4], d.cell[5], SpaceGroup.spaceGroupNames[sgnum - 1]); double sampling = 0.6; if (properties != null) { sampling = properties.getDouble("sampling", 0.6); } Resolution resolution = new Resolution(0.999999 * resHigh, sampling); return new ReflectionList(crystal, resolution, properties); } /** * {@inheritDoc} */ @Override public double getResolution(File mtzFile, Crystal crystal) { ReflectionList reflectionlist = getReflectionList(mtzFile, null); return reflectionlist.maxres; } /** * {@inheritDoc} */ @Override public boolean readFile(File mtzFile, ReflectionList reflectionlist, DiffractionRefinementData refinementdata, CompositeConfiguration properties) { int nread, nignore, nres, nfriedel, ncut; ByteOrder b = ByteOrder.nativeOrder(); FileInputStream fis; DataInputStream dis; boolean transpose = false; StringBuilder sb = new StringBuilder(); //sb.append(String.format("\n Opening %s\n", mtzFile.getName())); try { fis = new FileInputStream(mtzFile); dis = new DataInputStream(fis); byte headeroffset[] = new byte[4]; byte bytes[] = new byte[80]; int offset = 0; // eat "MTZ" title dis.read(bytes, offset, 4); String mtzstr = new String(bytes); // header offset dis.read(headeroffset, offset, 4); // machine stamp dis.read(bytes, offset, 4); ByteBuffer bb = ByteBuffer.wrap(bytes); int stamp = bb.order(ByteOrder.BIG_ENDIAN).getInt(); String stampstr = Integer.toHexString(stamp); switch (stampstr.charAt(0)) { case '1': case '3': if (b.equals(ByteOrder.LITTLE_ENDIAN)) { b = ByteOrder.BIG_ENDIAN; } break; case '4': if (b.equals(ByteOrder.BIG_ENDIAN)) { b = ByteOrder.LITTLE_ENDIAN; } break; } bb = ByteBuffer.wrap(headeroffset); int headeroffseti = bb.order(b).getInt(); // skip to header and parse dis.skipBytes((headeroffseti - 4) * 4); for (Boolean parsing = true; parsing; dis.read(bytes, offset, 80)) { mtzstr = new String(bytes); parsing = parseHeader(mtzstr); } // column identifiers foString = sigfoString = rfreeString = null; if (properties != null) { foString = properties.getString("fostring", null); sigfoString = properties.getString("sigfostring", null); rfreeString = properties.getString("rfreestring", null); } h = k = l = fo = sigfo = rfree = -1; fplus = sigfplus = fminus = sigfminus = rfreeplus = rfreeminus = -1; boolean print = true; parseColumns(print); if (h < 0 || k < 0 || l < 0) { String message = "Fatal error in MTZ file - no H K L indexes?\n"; logger.log(Level.SEVERE, message); return false; } // reopen to start at beginning fis = new FileInputStream(mtzFile); dis = new DataInputStream(fis); // skip initial header dis.skipBytes(80); // check if HKLs need to be transposed or not float data[] = new float[nColumns]; HKL mate = new HKL(); int nposignore = 0; int ntransignore = 0; int nzero = 0; int none = 0; for (int i = 0; i < nReflections; i++) { for (int j = 0; j < nColumns; j++) { dis.read(bytes, offset, 4); bb = ByteBuffer.wrap(bytes); data[j] = bb.order(b).getFloat(); } int ih = (int) data[h]; int ik = (int) data[k]; int il = (int) data[l]; boolean friedel = reflectionlist.findSymHKL(ih, ik, il, mate, false); HKL hklpos = reflectionlist.getHKL(mate); if (hklpos == null) { nposignore++; } friedel = reflectionlist.findSymHKL(ih, ik, il, mate, true); HKL hkltrans = reflectionlist.getHKL(mate); if (hkltrans == null) { ntransignore++; } if (rfree > 0) { if (((int) data[rfree]) == 0) { nzero++; } else if (((int) data[rfree]) == 1) { none++; } } if (rfreeplus > 0) { if (((int) data[rfreeplus]) == 0) { nzero++; } else if (((int) data[rfreeplus]) == 1) { none++; } } if (rfreeminus > 0) { if (((int) data[rfreeminus]) == 0) { nzero++; } else if (((int) data[rfreeminus]) == 1) { none++; } } } if (nposignore > ntransignore) { transpose = true; } if (none > (nzero * 2) && refinementdata.rfreeflag < 0) { refinementdata.setFreeRFlag(0); sb.append(String.format(" Setting R free flag to %d based on MTZ file data.\n", refinementdata.rfreeflag)); } else if (nzero > (none * 2) && refinementdata.rfreeflag < 0) { refinementdata.setFreeRFlag(1); sb.append(String.format(" Setting R free flag to %d based on MTZ file data.\n", refinementdata.rfreeflag)); } else if (refinementdata.rfreeflag < 0) { refinementdata.setFreeRFlag(0); sb.append(String.format(" Setting R free flag to MTZ default: %d\n", refinementdata.rfreeflag)); } // reopen to start at beginning fis = new FileInputStream(mtzFile); dis = new DataInputStream(fis); // skip initial header dis.skipBytes(80); // read in data double anofsigf[][] = new double[refinementdata.n][4]; for (int i = 0; i < refinementdata.n; i++) { anofsigf[i][0] = anofsigf[i][1] = anofsigf[i][2] = anofsigf[i][3] = Double.NaN; } nread = nignore = nres = nfriedel = ncut = 0; for (int i = 0; i < nReflections; i++) { for (int j = 0; j < nColumns; j++) { dis.read(bytes, offset, 4); bb = ByteBuffer.wrap(bytes); data[j] = bb.order(b).getFloat(); } int ih = (int) data[h]; int ik = (int) data[k]; int il = (int) data[l]; boolean friedel = reflectionlist.findSymHKL(ih, ik, il, mate, transpose); HKL hkl = reflectionlist.getHKL(mate); if (hkl != null) { if (fo > 0 && sigfo > 0) { if (refinementdata.fsigfcutoff > 0.0) { if ((data[fo] / data[sigfo]) < refinementdata.fsigfcutoff) { ncut++; continue; } } if (friedel) { anofsigf[hkl.index()][2] = data[fo]; anofsigf[hkl.index()][3] = data[sigfo]; nfriedel++; } else { anofsigf[hkl.index()][0] = data[fo]; anofsigf[hkl.index()][1] = data[sigfo]; } } else { if (fplus > 0 && sigfplus > 0) { if (refinementdata.fsigfcutoff > 0.0) { if ((data[fplus] / data[sigfplus]) < refinementdata.fsigfcutoff) { ncut++; continue; } } anofsigf[hkl.index()][0] = data[fplus]; anofsigf[hkl.index()][1] = data[sigfplus]; } if (fminus > 0 && sigfminus > 0) { if (refinementdata.fsigfcutoff > 0.0) { if ((data[fminus] / data[sigfminus]) < refinementdata.fsigfcutoff) { ncut++; continue; } } anofsigf[hkl.index()][2] = data[fminus]; anofsigf[hkl.index()][3] = data[sigfminus]; } } if (rfree > 0) { refinementdata.setFreeR(hkl.index(), (int) data[rfree]); } else { if (rfreeplus > 0 && rfreeminus > 0) { // not sure what the correct thing to do here is? refinementdata.setFreeR(hkl.index(), (int) data[rfreeplus]); } else if (rfreeplus > 0) { refinementdata.setFreeR(hkl.index(), (int) data[rfreeplus]); } else if (rfreeminus > 0) { refinementdata.setFreeR(hkl.index(), (int) data[rfreeminus]); } } nread++; } else { HKL tmp = new HKL(ih, ik, il); if (!reflectionlist.resolution .inInverseResSqRange(Crystal.invressq(reflectionlist.crystal, tmp))) { nres++; } else { nignore++; } } } // set up fsigf from F+ and F- refinementdata.generate_fsigf_from_anofsigf(anofsigf); sb.append(String.format(" MTZ file type (machine stamp): %s\n", stampstr)); sb.append(String.format(" HKL data is %s\n", transpose ? "transposed" : "not transposed")); sb.append(String.format(" HKL read in: %d\n", nread)); sb.append(String.format(" HKL read as friedel mates: %d\n", nfriedel)); sb.append(String.format(" HKL NOT read in (too high resolution): %d\n", nres)); sb.append(String.format(" HKL NOT read in (not in internal list?): %d\n", nignore)); sb.append(String.format(" HKL NOT read in (F/sigF cutoff): %d\n", ncut)); sb.append( String.format(" HKL in internal list: %d\n", reflectionlist.hkllist.size())); if (logger.isLoggable(Level.INFO)) { logger.info(sb.toString()); } if (rfree < 0 && rfreeplus < 0 && rfreeminus < 0) { refinementdata.generateRFree(); } } catch (EOFException eof) { System.out.println("EOF reached "); return false; } catch (IOException ioe) { System.out.println("IO Exception: " + ioe.getMessage()); return false; } return true; } /** * Average the computed structure factors for two systems. * * @param mtzFile1 file 1 (which will be overwritten and become the new * average) * @param mtzFile2 second MTZ file * @param reflectionlist list of HKLs * @param iter the iteration in the running average * @param properties the CompositeConfiguration defines the properties of * each system. */ public void averageFcs(File mtzFile1, File mtzFile2, ReflectionList reflectionlist, int iter, CompositeConfiguration properties) { DiffractionRefinementData fcdata1 = new DiffractionRefinementData(properties, reflectionlist); DiffractionRefinementData fcdata2 = new DiffractionRefinementData(properties, reflectionlist); readFcs(mtzFile1, reflectionlist, fcdata1, properties); readFcs(mtzFile2, reflectionlist, fcdata2, properties); // compute running average using mtzFile1 as current average System.out.println("iteration for averaging: " + iter); for (int i = 0; i < reflectionlist.hkllist.size(); i++) { fcdata1.fc[i][0] += (fcdata2.fc[i][0] - fcdata1.fc[i][0]) / iter; fcdata1.fc[i][1] += (fcdata2.fc[i][1] - fcdata1.fc[i][1]) / iter; fcdata1.fs[i][0] += (fcdata2.fs[i][0] - fcdata1.fs[i][0]) / iter; fcdata1.fs[i][1] += (fcdata2.fs[i][1] - fcdata1.fs[i][1]) / iter; } // overwrite original MTZ MTZWriter mtzout = new MTZWriter(reflectionlist, fcdata1, mtzFile1.getName(), MTZType.FCONLY); mtzout.write(); } public boolean readFcs(File mtzFile, ReflectionList reflectionlist, DiffractionRefinementData fcdata, CompositeConfiguration properties) { int nread, nignore, nres, nfriedel, ncut; ByteOrder b = ByteOrder.nativeOrder(); FileInputStream fis; DataInputStream dis; StringBuilder sb = new StringBuilder(); try { fis = new FileInputStream(mtzFile); dis = new DataInputStream(fis); byte headeroffset[] = new byte[4]; byte bytes[] = new byte[80]; int offset = 0; // eat "MTZ" title dis.read(bytes, offset, 4); String mtzstr = new String(bytes); // header offset dis.read(headeroffset, offset, 4); // machine stamp dis.read(bytes, offset, 4); ByteBuffer bb = ByteBuffer.wrap(bytes); int stamp = bb.order(ByteOrder.BIG_ENDIAN).getInt(); String stampstr = Integer.toHexString(stamp); switch (stampstr.charAt(0)) { case '1': case '3': if (b.equals(ByteOrder.LITTLE_ENDIAN)) { b = ByteOrder.BIG_ENDIAN; } break; case '4': if (b.equals(ByteOrder.BIG_ENDIAN)) { b = ByteOrder.LITTLE_ENDIAN; } break; } bb = ByteBuffer.wrap(headeroffset); int headeroffseti = bb.order(b).getInt(); // skip to header and parse dis.skipBytes((headeroffseti - 4) * 4); for (Boolean parsing = true; parsing; dis.read(bytes, offset, 80)) { mtzstr = new String(bytes); parsing = parseHeader(mtzstr); } // column identifiers fc = phic = fs = phis = -1; boolean print = true; parseFcColumns(print); if (h < 0 || k < 0 || l < 0) { String message = "Fatal error in MTZ file - no H K L indexes?\n"; logger.log(Level.SEVERE, message); return false; } // reopen to start at beginning fis = new FileInputStream(mtzFile); dis = new DataInputStream(fis); // skip initial header dis.skipBytes(80); float data[] = new float[nColumns]; HKL mate = new HKL(); // read in data ComplexNumber c = new ComplexNumber(); nread = nignore = nres = nfriedel = ncut = 0; for (int i = 0; i < nReflections; i++) { for (int j = 0; j < nColumns; j++) { dis.read(bytes, offset, 4); bb = ByteBuffer.wrap(bytes); data[j] = bb.order(b).getFloat(); } int ih = (int) data[h]; int ik = (int) data[k]; int il = (int) data[l]; boolean friedel = reflectionlist.findSymHKL(ih, ik, il, mate, false); HKL hkl = reflectionlist.getHKL(mate); if (hkl != null) { if (fc > 0 && phic > 0) { c.re(data[fc] * cos(toRadians(data[phic]))); c.im(data[fc] * sin(toRadians(data[phic]))); fcdata.setFc(hkl.index(), c); } if (fs > 0 && phis > 0) { c.re(data[fs] * cos(toRadians(data[phis]))); c.im(data[fs] * sin(toRadians(data[phis]))); fcdata.setFs(hkl.index(), c); } nread++; } else { HKL tmp = new HKL(ih, ik, il); if (!reflectionlist.resolution .inInverseResSqRange(Crystal.invressq(reflectionlist.crystal, tmp))) { nres++; } else { nignore++; } } } sb.append(String.format(" MTZ file type (machine stamp): %s\n", stampstr)); sb.append(String.format(" Fc HKL read in: %d\n", nread)); sb.append(String.format(" Fc HKL read as friedel mates: %d\n", nfriedel)); sb.append(String.format(" Fc HKL NOT read in (too high resolution): %d\n", nres)); sb.append(String.format(" Fc HKL NOT read in (not in internal list?): %d\n", nignore)); sb.append(String.format(" Fc HKL NOT read in (F/sigF cutoff): %d\n", ncut)); sb.append(String.format(" HKL in internal list: %d\n", reflectionlist.hkllist.size())); if (logger.isLoggable(Level.INFO)) { logger.info(sb.toString()); } } catch (EOFException eof) { System.out.println("EOF reached "); return false; } catch (IOException ioe) { System.out.println("IO Exception: " + ioe.getMessage()); return false; } return true; } private Boolean parseHeader(String str) { Boolean parsing = true; Column col; Dataset dset; int ndset; String[] strarray = str.split("\\s+"); if (headerParsed) { return Header.toHeader(strarray[0]) != Header.END; } switch (Header.toHeader(strarray[0])) { case TITLE: title = str.substring(5); break; case NCOL: nColumns = Integer.parseInt(strarray[1]); nReflections = Integer.parseInt(strarray[2]); nBatches = Integer.parseInt(strarray[3]); break; case SORT: break; case SYMINF: String[] tmp = str.split("\'+"); sgnum = Integer.parseInt(strarray[4]); if (tmp.length > 1) { spaceGroupName = tmp[1]; } break; case SYMM: break; case RESO: double r1 = Math.sqrt(1.0 / Float.parseFloat(strarray[1])); double r2 = Math.sqrt(1.0 / Float.parseFloat(strarray[2])); resLow = Math.max(r1, r2); resHigh = Math.min(r1, r2); break; case VALM: break; case NDIF: int ndif = Integer.parseInt(strarray[1]); break; case COL: case COLUMN: ndset = Integer.parseInt(strarray[5]); if (ndset == 0) { dsetoffset = 0; } col = new Column(); columns.add(col); col.label = strarray[1]; col.type = strarray[2].charAt(0); col.id = ndset; col.min = Double.parseDouble(strarray[3]); col.max = Double.parseDouble(strarray[4]); break; case PROJECT: ndset = Integer.parseInt(strarray[1]); if (ndset == 0) { dsetoffset = 0; } try { dset = (Dataset) datasets.get(ndset - dsetoffset); } catch (IndexOutOfBoundsException e) { dset = new Dataset(); datasets.add(dset); } dset.project = strarray[2]; break; case CRYSTAL: break; case DATASET: ndset = Integer.parseInt(strarray[1]); if (ndset == 0) { dsetoffset = 0; } try { dset = (Dataset) datasets.get(ndset - dsetoffset); } catch (IndexOutOfBoundsException e) { dset = new Dataset(); datasets.add(dset); } dset.dataset = strarray[2]; break; case DCELL: ndset = Integer.parseInt(strarray[1]); if (ndset == 0) { dsetoffset = 0; } try { dset = (Dataset) datasets.get(ndset - dsetoffset); } catch (IndexOutOfBoundsException e) { dset = new Dataset(); datasets.add(dset); } dset.cell[0] = Double.parseDouble(strarray[2]); dset.cell[1] = Double.parseDouble(strarray[3]); dset.cell[2] = Double.parseDouble(strarray[4]); dset.cell[3] = Double.parseDouble(strarray[5]); dset.cell[4] = Double.parseDouble(strarray[6]); dset.cell[5] = Double.parseDouble(strarray[7]); break; case DWAVEL: ndset = Integer.parseInt(strarray[1]); if (ndset == 0) { dsetoffset = 0; } try { dset = (Dataset) datasets.get(ndset - dsetoffset); } catch (IndexOutOfBoundsException e) { dset = new Dataset(); datasets.add(dset); } dset.lambda = Double.parseDouble(strarray[2]); break; case BATCH: break; case END: headerParsed = true; parsing = false; break; default: break; } return parsing; } private void parseColumns(boolean print) { int nc = 0; StringBuilder sb = new StringBuilder(); for (Iterator i = columns.iterator(); i.hasNext(); nc++) { Column c = (Column) i.next(); String label = c.label.trim(); if (label.equalsIgnoreCase("H") && c.type == 'H') { h = nc; } else if (label.equalsIgnoreCase("K") && c.type == 'H') { k = nc; } else if (label.equalsIgnoreCase("L") && c.type == 'H') { l = nc; } else if ((label.equalsIgnoreCase("free") || label.equalsIgnoreCase("freer") || label.equalsIgnoreCase("freerflag") || label.equalsIgnoreCase("freer_flag") || label.equalsIgnoreCase("rfree") || label.equalsIgnoreCase("rfreeflag") || label.equalsIgnoreCase("r-free-flags") || label.equalsIgnoreCase("test") || StringUtils.equalsIgnoreCase(label, rfreeString)) && c.type == 'I') { sb.append(String.format(" Reading R Free column: \"%s\"\n", c.label)); rfree = nc; } else if ((label.equalsIgnoreCase("free(+)") || label.equalsIgnoreCase("freer(+)") || label.equalsIgnoreCase("freerflag(+)") || label.equalsIgnoreCase("freer_flag(+)") || label.equalsIgnoreCase("rfree(+)") || label.equalsIgnoreCase("rfreeflag(+)") || label.equalsIgnoreCase("r-free-flags(+)") || label.equalsIgnoreCase("test(+)") || StringUtils.equalsIgnoreCase(label + "(+)", rfreeString)) && c.type == 'I') { rfreeplus = nc; } else if ((label.equalsIgnoreCase("free(-)") || label.equalsIgnoreCase("freer(-)") || label.equalsIgnoreCase("freerflag(-)") || label.equalsIgnoreCase("freer_flag(-)") || label.equalsIgnoreCase("rfree(-)") || label.equalsIgnoreCase("rfreeflag(-)") || label.equalsIgnoreCase("r-free-flags(-)") || label.equalsIgnoreCase("test(-)") || StringUtils.equalsIgnoreCase(label + "(-)", rfreeString)) && c.type == 'I') { rfreeminus = nc; } else if ((label.equalsIgnoreCase("f") || label.equalsIgnoreCase("fp") || label.equalsIgnoreCase("fo") || label.equalsIgnoreCase("fobs") || label.equalsIgnoreCase("f-obs") || StringUtils.equalsIgnoreCase(label, foString)) && c.type == 'F') { sb.append(String.format(" Reading Fo column: \"%s\"\n", c.label)); fo = nc; } else if ((label.equalsIgnoreCase("f(+)") || label.equalsIgnoreCase("fp(+)") || label.equalsIgnoreCase("fo(+)") || label.equalsIgnoreCase("fobs(+)") || label.equalsIgnoreCase("f-obs(+)") || StringUtils.equalsIgnoreCase(label + "(+)", foString)) && c.type == 'G') { fplus = nc; } else if ((label.equalsIgnoreCase("f(-)") || label.equalsIgnoreCase("fp(-)") || label.equalsIgnoreCase("fo(-)") || label.equalsIgnoreCase("fobs(-)") || label.equalsIgnoreCase("f-obs(-)") || StringUtils.equalsIgnoreCase(label + "(-)", foString)) && c.type == 'G') { fminus = nc; } else if ((label.equalsIgnoreCase("sigf") || label.equalsIgnoreCase("sigfp") || label.equalsIgnoreCase("sigfo") || label.equalsIgnoreCase("sigfobs") || label.equalsIgnoreCase("sigf-obs") || StringUtils.equalsIgnoreCase(label, sigfoString)) && c.type == 'Q') { sb.append(String.format(" Reading sigFo column: \"%s\"\n", c.label)); sigfo = nc; } else if ((label.equalsIgnoreCase("sigf(+)") || label.equalsIgnoreCase("sigfp(+)") || label.equalsIgnoreCase("sigfo(+)") || label.equalsIgnoreCase("sigfobs(+)") || label.equalsIgnoreCase("sigf-obs(+)") || StringUtils.equalsIgnoreCase(label + "(+)", sigfoString)) && c.type == 'L') { sigfplus = nc; } else if ((label.equalsIgnoreCase("sigf(-)") || label.equalsIgnoreCase("sigfp(-)") || label.equalsIgnoreCase("sigfo(-)") || label.equalsIgnoreCase("sigfobs(-)") || label.equalsIgnoreCase("sigf-obs(-)") || StringUtils.equalsIgnoreCase(label + "(-)", sigfoString)) && c.type == 'L') { sigfminus = nc; } } if (fo < 0 && sigfo < 0 && fplus > 0 && sigfplus > 0 && fminus > 0 && sigfminus > 0) { sb.append(String.format(" Reading Fplus/Fminus column to fill in Fo\n")); } if (logger.isLoggable(Level.INFO) && print) { logger.info(sb.toString()); } } private void parseFcColumns(boolean print) { int nc = 0; StringBuilder sb = new StringBuilder(); for (Iterator i = columns.iterator(); i.hasNext(); nc++) { Column c = (Column) i.next(); String label = c.label.trim(); if (label.equalsIgnoreCase("H") && c.type == 'H') { h = nc; } else if (label.equalsIgnoreCase("K") && c.type == 'H') { k = nc; } else if (label.equalsIgnoreCase("L") && c.type == 'H') { l = nc; } else if ((label.equalsIgnoreCase("fc") || label.equalsIgnoreCase("fcalc")) && c.type == 'F') { sb.append(String.format(" Reading Fc column: \"%s\"\n", c.label)); fc = nc; } else if ((label.equalsIgnoreCase("phic") || label.equalsIgnoreCase("phifc") || label.equalsIgnoreCase("phicalc") || label.equalsIgnoreCase("phifcalc")) && c.type == 'P') { sb.append(String.format(" Reading phiFc column: \"%s\"\n", c.label)); phic = nc; } else if ((label.equalsIgnoreCase("fs") || label.equalsIgnoreCase("fscalc")) && c.type == 'F') { sb.append(String.format(" Reading Fs column: \"%s\"\n", c.label)); fs = nc; } else if ((label.equalsIgnoreCase("phis") || label.equalsIgnoreCase("phifs") || label.equalsIgnoreCase("phiscalc") || label.equalsIgnoreCase("phifscalc")) && c.type == 'P') { sb.append(String.format(" Reading phiFs column: \"%s\"\n", c.label)); phis = nc; } } if (logger.isLoggable(Level.INFO) && print) { logger.info(sb.toString()); } } /** * <p> * printHeader</p> */ public void printHeader() { StringBuilder sb = new StringBuilder(); sb.append(" MTZ title: ").append(title).append("\n"); sb.append(" MTZ space group: ").append(spaceGroupName).append(" space group number: ").append(sgnum) .append(" (").append(SpaceGroup.spaceGroupNames[sgnum - 1]).append(")\n"); sb.append(" MTZ resolution: ").append(resLow).append(" - ").append(resHigh).append("\n"); sb.append(" Number of reflections: ").append(nReflections).append("\n"); int ndset = 1; for (Iterator i = datasets.iterator(); i.hasNext(); ndset++) { Dataset d = (Dataset) i.next(); sb.append(" dataset ").append(ndset).append(": ").append(d.dataset).append("\n"); sb.append(" project ").append(ndset).append(": ").append(d.project).append("\n"); sb.append(" wavelength ").append(ndset).append(": ").append(d.lambda).append("\n"); sb.append(" cell ").append(ndset).append(": ").append(d.cell[0]).append(" ").append(d.cell[1]) .append(" ").append(d.cell[2]).append(" ").append(d.cell[3]).append(" ").append(d.cell[4]) .append(" ").append(d.cell[5]).append("\n"); sb.append("\n"); } sb.append(" Number of columns: ").append(nColumns).append("\n"); int nc = 0; for (Iterator i = columns.iterator(); i.hasNext(); nc++) { Column c = (Column) i.next(); sb.append(String.format(" column %d: dataset id: %d min: %9.2f max: %9.2f label: %s type: %c\n", nc, c.id, c.min, c.max, c.label, c.type)); } if (logger.isLoggable(Level.INFO)) { logger.info(sb.toString()); } } }