1 // ******************************************************************************
2 //
3 // Title: Force Field X.
4 // Description: Force Field X - Software for Molecular Biophysics.
5 // Copyright: Copyright (c) Michael J. Schnieders 2001-2023.
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.crystal;
39
40 import static org.apache.commons.math3.util.FastMath.pow;
41 import static org.apache.commons.math3.util.FastMath.sqrt;
42
43 import java.io.BufferedWriter;
44 import java.io.FileWriter;
45 import java.io.PrintWriter;
46 import java.util.logging.Level;
47 import java.util.logging.Logger;
48
49 /**
50 * The CNSMapWriter class writes an output map that covers the unit cell (not the asymmetric unit).
51 * The map is set up for passage into FFTs (the x-axis has +2 offset).
52 *
53 * @author Timothy D. Fenn
54 * @see CCP4MapWriter
55 * @since 1.0
56 */
57 public class CNSMapWriter {
58
59 private static final Logger logger = Logger.getLogger(CNSMapWriter.class.getName());
60 private final String filename;
61 private final Crystal crystal;
62 private final int nx, ny, nz;
63
64 /**
65 * Constructor for CNSMapWriter.
66 *
67 * @param nx an int.
68 * @param ny an int.
69 * @param nz an int.
70 * @param crystal a {@link ffx.crystal.Crystal} object.
71 * @param filename a {@link java.lang.String} object.
72 */
73 public CNSMapWriter(int nx, int ny, int nz, Crystal crystal, String filename) {
74 this.nx = nx;
75 this.ny = ny;
76 this.nz = nz;
77 this.crystal = crystal;
78 this.filename = filename;
79 }
80
81 /**
82 * write
83 *
84 * @param data an array of double.
85 */
86 public void write(double[] data) {
87 try {
88 StringBuilder sb = new StringBuilder();
89 sb.append(String.format("\nwriting CNS map file: \"%s\"\n", filename));
90
91 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
92 double mean = 0.0;
93 double sd = 0.0;
94 out.println();
95 out.println(" 1");
96 out.println("map from ffx");
97 out.printf("%8d%8d%8d%8d%8d%8d%8d%8d%8d\n", nx, 0, nx - 1, ny, 0, ny - 1, nz, 0, nz - 1);
98 out.printf(
99 "%12.5E%12.5E%12.5E%12.5E%12.5E%12.5E\n",
100 crystal.a, crystal.b, crystal.c, crystal.alpha, crystal.beta, crystal.gamma);
101 out.println("ZYX");
102 int n = 0;
103 for (int k = 0; k < nz; k++) {
104 out.printf("%8d\n", k);
105 for (int j = 0; j < ny; j++) {
106 for (int i = 0; i < nx; i++) {
107 int index = 2 * (i + nx * (j + ny * k));
108 out.printf("%12.5E", data[index]);
109 n++;
110 mean += (data[index] - mean) / n;
111 if ((n % 6) == 0) {
112 out.println();
113 }
114 }
115 }
116 }
117
118 n = 0;
119 for (int k = 0; k < nz; k++) {
120 for (int j = 0; j < ny; j++) {
121 for (int i = 0; i < nx; i++) {
122 int index = 2 * (i + nx * (j + ny * k));
123 sd += pow(data[index] - mean, 2.0);
124 n++;
125 }
126 }
127 }
128 sd = sqrt(sd / n);
129
130 out.println(" -9999");
131 out.printf("%12.4E%12.4E\n", mean, sd);
132 sb.append(String.format("map mean: %g standard dev.: %g", mean, sd));
133 out.close();
134 if (logger.isLoggable(Level.INFO)) {
135 logger.info(sb.toString());
136 }
137 } catch (Exception e) {
138 String message = "Fatal exception evaluating structure factors.\n";
139 logger.log(Level.SEVERE, message, e);
140 System.exit(-1);
141 }
142 }
143 }