1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.xray.parsers;
39
40 import ffx.crystal.Crystal;
41
42 import java.io.DataOutputStream;
43 import java.io.File;
44 import java.io.FileOutputStream;
45 import java.nio.ByteBuffer;
46 import java.nio.ByteOrder;
47 import java.util.logging.Level;
48 import java.util.logging.Logger;
49
50 import static ffx.utilities.TinkerUtils.version;
51 import static java.lang.String.format;
52 import static org.apache.commons.math3.util.FastMath.pow;
53 import static org.apache.commons.math3.util.FastMath.sqrt;
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 public class CCP4MapWriter {
70
71 private static final Logger logger = Logger.getLogger(CCP4MapWriter.class.getName());
72 private final String filename;
73 private final Crystal crystal;
74 private final int extx, exty, extz;
75 private final int orix, oriy, oriz, nx, ny, nz;
76 private int stride;
77
78
79
80
81
82
83
84
85
86
87 public CCP4MapWriter(int extx, int exty, int extz, Crystal crystal, String filename) {
88 this.orix = 0;
89 this.oriy = 0;
90 this.oriz = 0;
91 this.extx = extx;
92 this.exty = exty;
93 this.extz = extz;
94 this.nx = extx;
95 this.ny = exty;
96 this.nz = extz;
97 this.crystal = crystal;
98 this.filename = filename;
99 this.stride = 2;
100 }
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 public CCP4MapWriter(
118 int orix, int oriy, int oriz,
119 int extx, int exty, int extz,
120 int nx, int ny, int nz,
121 Crystal crystal, String filename) {
122 this.orix = orix;
123 this.oriy = oriy;
124 this.oriz = oriz;
125 this.extx = extx;
126 this.exty = exty;
127 this.extz = extz;
128 this.nx = nx;
129 this.ny = ny;
130 this.nz = nz;
131 this.crystal = crystal;
132 this.filename = filename;
133 this.stride = 2;
134 }
135
136
137
138
139
140
141 public void setStride(int stride) {
142 this.stride = stride;
143 }
144
145
146
147
148
149
150 public void write(double[] data) {
151 write(data, false);
152 }
153
154
155
156
157
158
159
160 public void write(double[] data, boolean norm) {
161 double min = Double.POSITIVE_INFINITY;
162 double max = Double.NEGATIVE_INFINITY;
163 double mean = 0.0;
164 double sd = 0.0;
165
166 int n = 0;
167 for (int k = 0; k < extz; k++) {
168 for (int j = 0; j < exty; j++) {
169 for (int i = 0; i < extx; i++) {
170 int index = stride * (i + extx * (j + exty * k));
171 n++;
172 if (data[index] < min) {
173 min = data[index];
174 }
175 if (data[index] > max) {
176 max = data[index];
177 }
178 mean += (data[index] - mean) / n;
179 }
180 }
181 }
182
183 n = 0;
184 for (int k = 0; k < extz; k++) {
185 for (int j = 0; j < exty; j++) {
186 for (int i = 0; i < extx; i++) {
187 int index = stride * (i + extx * (j + exty * k));
188 sd += pow(data[index] - mean, 2.0);
189 n++;
190 }
191 }
192 }
193 sd = sqrt(sd / n);
194
195 if (norm) {
196 if (logger.isLoggable(Level.INFO)) {
197 StringBuilder sb = new StringBuilder();
198 sb.append("\n Normalizing CCP4 Map");
199 sb.append(format("\n Min: %8.4f", min));
200 sb.append(format("\n Max: %8.4f", max));
201 sb.append(format("\n Mean: %8.4f", mean));
202 sb.append(format("\n Standard Dev.: %8.4f", sd));
203 logger.info(sb.toString());
204 }
205
206 for (int k = 0; k < extz; k++) {
207 for (int j = 0; j < exty; j++) {
208 for (int i = 0; i < extx; i++) {
209 int index = stride * (i + extx * (j + exty * k));
210 data[index] = (data[index] - mean) / sd;
211 }
212 }
213 }
214
215 write(data, false);
216 return;
217 }
218
219 File file = version(new File(filename));
220 String name = file.getName();
221
222 try {
223 if (logger.isLoggable(Level.INFO)) {
224 StringBuilder sb = new StringBuilder();
225 sb.append(format("\n Writing CCP4 map file: \"%s\"", name));
226 sb.append(format("\n Min: %8.4f", min));
227 sb.append(format("\n Max: %8.4f", max));
228 sb.append(format("\n Mean: %8.4f", mean));
229 sb.append(format("\n Standard Dev.: %8.4f", sd));
230 logger.info(sb.toString());
231 }
232
233 FileOutputStream fos = new FileOutputStream(file);
234 DataOutputStream dos = new DataOutputStream(fos);
235
236 byte[] bytes = new byte[2048];
237 ByteBuffer bb = ByteBuffer.wrap(bytes);
238
239 bb.order(ByteOrder.nativeOrder());
240
241
242 bb.putInt(extx).putInt(exty).putInt(extz);
243
244 bb.putInt(2);
245 bb.putInt(orix).putInt(oriy).putInt(oriz);
246 bb.putInt(nx).putInt(ny).putInt(nz);
247
248 bb.putFloat((float) crystal.a);
249 bb.putFloat((float) crystal.b);
250 bb.putFloat((float) crystal.c);
251 bb.putFloat((float) crystal.alpha);
252 bb.putFloat((float) crystal.beta);
253 bb.putFloat((float) crystal.gamma);
254
255 bb.putInt(1).putInt(2).putInt(3);
256 bb.putFloat((float) min);
257 bb.putFloat((float) max);
258 bb.putFloat((float) mean);
259
260 bb.putInt(crystal.spaceGroup.number);
261
262
263
264
265 bb.putInt(80);
266 bb.putInt(0);
267
268 for (int i = 0; i < 12; i++) {
269 bb.putFloat(0.0f);
270 }
271
272 for (int i = 0; i < 15; i++) {
273 bb.putInt(0);
274 }
275
276 int offset = 0;
277 dos.write(bytes, offset, 208);
278 bb.rewind();
279
280 String mapstr = "MAP ";
281 dos.writeBytes(mapstr);
282
283
284
285 int imapdata;
286 if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
287 imapdata = 0x4441;
288 } else {
289 imapdata = 0x1111;
290 }
291 bb.putInt(imapdata);
292 bb.putFloat((float) sd);
293 bb.putInt(1);
294 dos.write(bytes, offset, 12);
295
296 StringBuilder sb = new StringBuilder();
297 sb.append("map data from ffx");
298 while (sb.length() < 80) {
299 sb.append(" ");
300 }
301 dos.writeBytes(sb.toString());
302
303 sb = new StringBuilder();
304 while (sb.length() < 80) {
305 sb.append(" ");
306 }
307 for (int i = 0; i < 9; i++) {
308 dos.writeBytes(sb.toString());
309 }
310
311 sb = new StringBuilder();
312 sb.append("x,y,z");
313 while (sb.length() < 80) {
314 sb.append(" ");
315 }
316 dos.writeBytes(sb.toString());
317
318 bb.rewind();
319 for (int k = 0; k < extz; k++) {
320 for (int j = 0; j < exty; j++) {
321 for (int i = 0; i < extx; i++) {
322 int index = stride * (i + extx * (j + exty * k));
323 float fmapdata = (float) data[index];
324 bb.putFloat(fmapdata);
325 if (!bb.hasRemaining()) {
326 dos.write(bytes);
327 bb.rewind();
328 }
329 }
330 }
331 }
332 if (bb.position() > 0) {
333 dos.write(bytes);
334 bb.rewind();
335 }
336 dos.close();
337 } catch (Exception e) {
338 String message = "Fatal exception evaluating structure factors.\n";
339 logger.log(Level.SEVERE, message, e);
340 }
341 }
342 }