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.realspace.parsers;
39
40 import ffx.crystal.Crystal;
41 import ffx.crystal.SpaceGroupInfo;
42 import ffx.realspace.RealSpaceRefinementData;
43 import org.apache.commons.configuration2.CompositeConfiguration;
44
45 import java.io.DataInputStream;
46 import java.io.FileInputStream;
47 import java.nio.ByteBuffer;
48 import java.nio.ByteOrder;
49 import java.util.logging.Level;
50 import java.util.logging.Logger;
51
52 import static java.lang.String.format;
53
54
55
56
57
58
59
60
61
62
63 public class CCP4MapFilter implements RealSpaceFileFilter {
64
65 private static final Logger logger = Logger.getLogger(CCP4MapFilter.class.getName());
66
67
68 @Override
69 public Crystal getCrystal(String fileName, CompositeConfiguration properties) {
70 int imapData;
71 int spaceGroup = -1;
72 double cellA = -1.0;
73 double cellB = -1.0;
74 double cellC = -1.0;
75 double cellAlpha = -1.0;
76 double cellBeta = -1.0;
77 double cellGamma = -1.0;
78
79 ByteOrder byteOrder = ByteOrder.nativeOrder();
80 FileInputStream fileInputStream;
81 DataInputStream dataInputStream;
82
83
84 try {
85 fileInputStream = new FileInputStream(fileName);
86 dataInputStream = new DataInputStream(fileInputStream);
87
88 dataInputStream.skipBytes(212);
89 byte[] bytes = new byte[4];
90 dataInputStream.read(bytes, 0, 4);
91 ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
92
93 imapData = byteBuffer.order(ByteOrder.BIG_ENDIAN).getInt();
94 String stampString = Integer.toHexString(imapData);
95
96 switch (stampString.charAt(0)) {
97 case '1':
98 case '3':
99 if (byteOrder.equals(ByteOrder.LITTLE_ENDIAN)) {
100 byteOrder = ByteOrder.BIG_ENDIAN;
101 }
102 break;
103 case '4':
104 if (byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
105 byteOrder = ByteOrder.LITTLE_ENDIAN;
106 }
107 break;
108 }
109 fileInputStream.close();
110 } catch (Exception e) {
111 String message = " Fatal exception reading CCP4 map.\n";
112 logger.log(Level.SEVERE, message, e);
113 }
114
115 try {
116 fileInputStream = new FileInputStream(fileName);
117 dataInputStream = new DataInputStream(fileInputStream);
118
119 dataInputStream.skipBytes(40);
120 byte[] bytes = new byte[80];
121 dataInputStream.read(bytes, 0, 80);
122 ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
123
124 cellA = byteBuffer.order(byteOrder).getFloat();
125 cellB = byteBuffer.order(byteOrder).getFloat();
126 cellC = byteBuffer.order(byteOrder).getFloat();
127 cellAlpha = byteBuffer.order(byteOrder).getFloat();
128 cellBeta = byteBuffer.order(byteOrder).getFloat();
129 cellGamma = byteBuffer.order(byteOrder).getFloat();
130
131 for (int i = 0; i < 3; i++) {
132 byteBuffer.order(byteOrder).getInt();
133 }
134 for (int i = 0; i < 3; i++) {
135 byteBuffer.order(byteOrder).getFloat();
136 }
137
138 spaceGroup = byteBuffer.order(byteOrder).getInt();
139 fileInputStream.close();
140 } catch (Exception e) {
141 String message = " Fatal exception reading CCP4 map.\n";
142 logger.log(Level.SEVERE, message, e);
143 }
144
145 return new Crystal(
146 cellA,
147 cellB,
148 cellC,
149 cellAlpha,
150 cellBeta,
151 cellGamma,
152 SpaceGroupInfo.spaceGroupNames[spaceGroup - 1]);
153 }
154
155
156 @Override
157 public boolean readFile(
158 String filename, RealSpaceRefinementData refinementdata, CompositeConfiguration properties) {
159
160 int imapData;
161 double cellA, cellB, cellC, cellAlpha, cellBeta, cellGamma;
162 String stampString;
163
164 ByteOrder byteOrder = ByteOrder.nativeOrder();
165 FileInputStream fileInputStream;
166 DataInputStream dataInputStream;
167
168 double min = Double.POSITIVE_INFINITY;
169 double max = Double.NEGATIVE_INFINITY;
170 double mean = 0.0;
171 double sd = 0.0;
172 double rmsd = 0.0;
173
174
175 try {
176 fileInputStream = new FileInputStream(filename);
177 dataInputStream = new DataInputStream(fileInputStream);
178
179 dataInputStream.skipBytes(212);
180 byte[] bytes = new byte[4];
181 dataInputStream.read(bytes, 0, 4);
182 ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
183
184 imapData = byteBuffer.order(ByteOrder.BIG_ENDIAN).getInt();
185 stampString = Integer.toHexString(imapData);
186 switch (stampString.charAt(0)) {
187 case '1':
188 case '3':
189 if (byteOrder.equals(ByteOrder.LITTLE_ENDIAN)) {
190 byteOrder = ByteOrder.BIG_ENDIAN;
191 }
192 break;
193 case '4':
194 if (byteOrder.equals(ByteOrder.BIG_ENDIAN)) {
195 byteOrder = ByteOrder.LITTLE_ENDIAN;
196 }
197 break;
198 }
199 if (logger.isLoggable(Level.INFO)) {
200 StringBuilder sb = new StringBuilder();
201 sb.append(format(" Opening CCP4 map: %s\n", filename));
202 logger.info(sb.toString());
203 }
204
205 fileInputStream.close();
206 } catch (Exception e) {
207 String message = " Fatal exception reading CCP4 map.\n";
208 logger.log(Level.SEVERE, message, e);
209 }
210
211 try {
212 fileInputStream = new FileInputStream(filename);
213 dataInputStream = new DataInputStream(fileInputStream);
214
215 byte[] bytes = new byte[2048];
216
217 dataInputStream.read(bytes, 0, 1024);
218 ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
219
220 int[] ext = new int[3];
221 ext[0] = byteBuffer.order(byteOrder).getInt();
222 ext[1] = byteBuffer.order(byteOrder).getInt();
223 ext[2] = byteBuffer.order(byteOrder).getInt();
224
225
226 int mode = byteBuffer.order(byteOrder).getInt();
227
228 int[] ori = new int[3];
229 ori[0] = byteBuffer.order(byteOrder).getInt();
230 ori[1] = byteBuffer.order(byteOrder).getInt();
231 ori[2] = byteBuffer.order(byteOrder).getInt();
232
233 int[] ni = new int[3];
234 ni[0] = byteBuffer.order(byteOrder).getInt();
235 ni[1] = byteBuffer.order(byteOrder).getInt();
236 ni[2] = byteBuffer.order(byteOrder).getInt();
237
238 cellA = byteBuffer.order(byteOrder).getFloat();
239 cellB = byteBuffer.order(byteOrder).getFloat();
240 cellC = byteBuffer.order(byteOrder).getFloat();
241 cellAlpha = byteBuffer.order(byteOrder).getFloat();
242 cellBeta = byteBuffer.order(byteOrder).getFloat();
243 cellGamma = byteBuffer.order(byteOrder).getFloat();
244
245 int[] axisi = new int[3];
246 for (int i = 0; i < 3; i++) {
247 int axis = byteBuffer.order(byteOrder).getInt();
248 switch (axis) {
249 case 1:
250 axisi[0] = i;
251 break;
252 case 2:
253 axisi[1] = i;
254 break;
255 case 3:
256 axisi[2] = i;
257 break;
258 }
259 }
260
261 min = byteBuffer.order(byteOrder).getFloat();
262 max = byteBuffer.order(byteOrder).getFloat();
263 mean = byteBuffer.order(byteOrder).getFloat();
264 int sg = byteBuffer.order(byteOrder).getInt();
265 int nsymb = byteBuffer.order(byteOrder).getInt();
266 int skew = byteBuffer.order(byteOrder).getInt();
267
268 for (int i = 0; i < 12; i++) {
269 byteBuffer.order(byteOrder).getFloat();
270 }
271
272 for (int i = 0; i < 15; i++) {
273 byteBuffer.order(byteOrder).getInt();
274 }
275
276 byte[] word = new byte[2048];
277 byteBuffer.order(byteOrder).get(word, 0, 4);
278 String mapString = new String(word);
279 sd = byteBuffer.order(byteOrder).getFloat();
280 rmsd = byteBuffer.order(byteOrder).getFloat();
281
282 if (logger.isLoggable(Level.INFO)) {
283 StringBuilder sb = new StringBuilder();
284 sb.append(format(" Column origin: %d\t Extent: %d\n", ori[0], ext[0]));
285 sb.append(format(" Row origin: %d\t Extent: %d\n", ori[1], ext[1]));
286 sb.append(format(" Section origin: %d\t Extent: %d\n", ori[2], ext[2]));
287 sb.append(format(" Axis order: %d %d %d\n", axisi[0], axisi[1], axisi[2]));
288 sb.append(format(" Number of X, Y, Z columns: %d %d %d\n", ni[0], ni[1], ni[2]));
289 sb.append(format(" Spacegroup: %d (%s)\n", sg, SpaceGroupInfo.spaceGroupNames[sg - 1]));
290 sb.append(
291 format(
292 " Cell: %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n",
293 cellA, cellB, cellC, cellAlpha, cellBeta, cellGamma));
294 logger.info(sb.toString());
295 }
296
297 int nlabel = byteBuffer.order(byteOrder).getInt();
298 for (int i = 0; i < 10; i++) {
299 byteBuffer.order(byteOrder).get(word, 0, 80);
300 mapString = new String(word);
301 }
302
303 if (nsymb > 0) {
304 byteBuffer.rewind();
305 dataInputStream.read(bytes, 0, nsymb);
306 for (int i = 0; i < nsymb / 80; i += 80) {
307 byteBuffer.order(byteOrder).get(word, 0, 80);
308 mapString = new String(word);
309 }
310 }
311
312 byteBuffer.rewind();
313 dataInputStream.read(bytes, 0, 2048);
314 refinementdata.setData(new double[ext[0] * ext[1] * ext[2]]);
315 int[] ijk = new int[3];
316 int index, x, y, z;
317 refinementdata.setOrigin(ori[axisi[0]], ori[axisi[1]], ori[axisi[2]]);
318 int nx = ext[axisi[0]];
319 int ny = ext[axisi[1]];
320 int nz = ext[axisi[2]];
321 refinementdata.setExtent(nx, ny, nz);
322 refinementdata.setNI(ni[0], ni[1], ni[2]);
323 for (ijk[2] = 0; ijk[2] < ext[2]; ijk[2]++) {
324 for (ijk[1] = 0; ijk[1] < ext[1]; ijk[1]++) {
325 for (ijk[0] = 0; ijk[0] < ext[0]; ijk[0]++) {
326 x = ijk[axisi[0]];
327 y = ijk[axisi[1]];
328 z = ijk[axisi[2]];
329 index = x + nx * (y + ny * z);
330 refinementdata.getData()[index] = byteBuffer.order(byteOrder).getFloat();
331 if (!byteBuffer.hasRemaining()) {
332 byteBuffer.rewind();
333 dataInputStream.read(bytes, 0, 2048);
334 }
335 }
336 }
337 }
338 fileInputStream.close();
339 } catch (Exception e) {
340 String message = " Fatal exception reading CCP4 map.\n";
341 logger.log(Level.SEVERE, message, e);
342 }
343
344 return true;
345 }
346 }