View Javadoc
1   // ******************************************************************************
2   //
3   // Title:       Force Field X.
4   // Description: Force Field X - Software for Molecular Biophysics.
5   // Copyright:   Copyright (c) Michael J. Schnieders 2001-2024.
6   //
7   // This file is part of Force Field X.
8   //
9   // Force Field X is free software; you can redistribute it and/or modify it
10  // under the terms of the GNU General Public License version 3 as published by
11  // the Free Software Foundation.
12  //
13  // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16  // details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA 02111-1307 USA
21  //
22  // Linking this library statically or dynamically with other modules is making a
23  // combined work based on this library. Thus, the terms and conditions of the
24  // GNU General Public License cover the whole combination.
25  //
26  // As a special exception, the copyright holders of this library give you
27  // permission to link this library with independent modules to produce an
28  // executable, regardless of the license terms of these independent modules, and
29  // to copy and distribute the resulting executable under terms of your choice,
30  // provided that you also meet, for each linked independent module, the terms
31  // and conditions of the license of that module. An independent module is a
32  // module which is not derived from or based on this library. If you modify this
33  // library, you may extend this exception to your version of the library, but
34  // you are not obligated to do so. If you do not wish to do so, delete this
35  // exception statement from your version.
36  //
37  // ******************************************************************************
38  package ffx.xray.parsers;
39  
40  import ffx.crystal.Crystal;
41  
42  import static org.apache.commons.math3.util.FastMath.pow;
43  import static org.apache.commons.math3.util.FastMath.sqrt;
44  
45  import java.io.BufferedWriter;
46  import java.io.FileWriter;
47  import java.io.PrintWriter;
48  import java.util.logging.Level;
49  import java.util.logging.Logger;
50  
51  /**
52   * The CNSMapWriter class writes an output map that covers the unit cell (not the asymmetric unit).
53   * The map is set up for passage into FFTs (the x-axis has +2 offset).
54   *
55   * @author Timothy D. Fenn
56   * @see CCP4MapWriter
57   * @since 1.0
58   */
59  public class CNSMapWriter {
60  
61    private static final Logger logger = Logger.getLogger(CNSMapWriter.class.getName());
62    private final String filename;
63    private final Crystal crystal;
64    private final int nx, ny, nz;
65  
66    /**
67     * Constructor for CNSMapWriter.
68     *
69     * @param nx an int.
70     * @param ny an int.
71     * @param nz an int.
72     * @param crystal a {@link ffx.crystal.Crystal} object.
73     * @param filename a {@link java.lang.String} object.
74     */
75    public CNSMapWriter(int nx, int ny, int nz, Crystal crystal, String filename) {
76      this.nx = nx;
77      this.ny = ny;
78      this.nz = nz;
79      this.crystal = crystal;
80      this.filename = filename;
81    }
82  
83    /**
84     * write
85     *
86     * @param data an array of double.
87     */
88    public void write(double[] data) {
89      try {
90        StringBuilder sb = new StringBuilder();
91        sb.append(String.format("\nwriting CNS map file: \"%s\"\n", filename));
92  
93        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
94        double mean = 0.0;
95        double sd = 0.0;
96        out.println();
97        out.println("       1");
98        out.println("map from ffx");
99        out.printf("%8d%8d%8d%8d%8d%8d%8d%8d%8d\n", nx, 0, nx - 1, ny, 0, ny - 1, nz, 0, nz - 1);
100       out.printf(
101           "%12.5E%12.5E%12.5E%12.5E%12.5E%12.5E\n",
102           crystal.a, crystal.b, crystal.c, crystal.alpha, crystal.beta, crystal.gamma);
103       out.println("ZYX");
104       int n = 0;
105       for (int k = 0; k < nz; k++) {
106         out.printf("%8d\n", k);
107         for (int j = 0; j < ny; j++) {
108           for (int i = 0; i < nx; i++) {
109             int index = 2 * (i + nx * (j + ny * k));
110             out.printf("%12.5E", data[index]);
111             n++;
112             mean += (data[index] - mean) / n;
113             if ((n % 6) == 0) {
114               out.println();
115             }
116           }
117         }
118       }
119 
120       n = 0;
121       for (int k = 0; k < nz; k++) {
122         for (int j = 0; j < ny; j++) {
123           for (int i = 0; i < nx; i++) {
124             int index = 2 * (i + nx * (j + ny * k));
125             sd += pow(data[index] - mean, 2.0);
126             n++;
127           }
128         }
129       }
130       sd = sqrt(sd / n);
131 
132       out.println("   -9999");
133       out.printf("%12.4E%12.4E\n", mean, sd);
134       sb.append(String.format("map mean: %g standard dev.: %g", mean, sd));
135       out.close();
136       if (logger.isLoggable(Level.INFO)) {
137         logger.info(sb.toString());
138       }
139     } catch (Exception e) {
140       String message = "Fatal exception evaluating structure factors.\n";
141       logger.log(Level.SEVERE, message, e);
142       System.exit(-1);
143     }
144   }
145 }