1 /* $RCSfile$
2  * $Author: hansonr $
3  * $Date: 2007-03-30 11:40:16 -0500 (Fri, 30 Mar 2007) $
4  * $Revision: 7273 $
5  *
6  * Copyright (C) 2007 Miguel, Bob, Jmol Development
7  *
8  * Contact: hansonr@stolaf.edu
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Lesser General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2.1 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Lesser General License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 package org.jmol.jvxl.readers;
25 
26 import java.io.BufferedReader;
27 
28 
29 import org.jmol.util.Logger;
30 import javajs.util.P3;
31 import org.jmol.util.SimpleUnitCell;
32 
33 // DSN6, MRC, and XPLOR readers
34 
35 abstract class MapFileReader extends VolumeFileReader {
36 
37   protected float dmin = Float.MAX_VALUE;
38   protected float dmax, dmean, drange;
39 
MapFileReader()40   MapFileReader(){}
41 
42   @Override
init2(SurfaceGenerator sg, BufferedReader br)43   void init2(SurfaceGenerator sg, BufferedReader br) {
44     init2MFR(sg, br);
45   }
46 
init2MFR(SurfaceGenerator sg, BufferedReader br)47   protected void init2MFR(SurfaceGenerator sg, BufferedReader br) {
48     init2VFR(sg, br);
49     isAngstroms = true;
50 // undocumented; for debugging, I think
51 //    adjustment = center;
52 //    if (adjustment == null || Float.isNaN(adjustment.x))
53 //      adjustment = new P3();
54   }
55 
56     /*
57      * inputs:
58      *
59      a b c    cell dimensions in angstroms
60      alpha beta gamma  cell angles in degrees
61      nx       number of columns (fastest changing in map)
62      ny       number of rows
63      yz       number of sections (slowest changing in map)
64      a0       offset of uc origin along a axis
65      b0       offset of uc origin along b axis
66      c0       offset of uc origin along c axis
67      na       number of intervals along uc X -- a/na is unit vector
68      nb       number of intervals along uc Y -- b/nb is unit vector
69      nc       number of intervals along uc Z -- c/nc is unit vector
70      mapc     axis corresp to cols (1,2,3 for X,Y,Z)
71      mapr     axis corresp to rows (1,2,3 for X,Y,Z)
72      maps     axis corresp to sections (1,2,3 for X,Y,Z)
73      originX, originY, originZ   origin in X,Y,Z of unitCell (0,0,0)
74     */
75 
76   protected int mapc, mapr, maps;
77   protected int n0, n1, n2, mode;
78   protected float[] xyzStart = new float[3];
79   protected int na, nb, nc;
80   protected float a, b, c, alpha, beta, gamma;
81   protected P3 origin = new P3();
82   //protected P3 adjustment = new P3();
83   protected P3[] vectors = new P3[3];
84   protected int xIndex = -1, yIndex, zIndex;
85 
86   protected P3 p3 = new P3();
87 
checkInsideOut(int mapc, int mapr, int maps)88   protected void checkInsideOut(int mapc, int mapr, int maps) {
89     if (params.thePlane == null)
90       params.insideOut = (";123;231;312;".indexOf(";" + mapc + mapr + maps) >= 0);
91   }
92 
getVectorsAndOrigin()93   protected void getVectorsAndOrigin() {
94 
95     checkInsideOut(mapc, mapr, maps);
96 
97     Logger.info("grid parameters: nx,ny,nz: " + n0 + "," + n1 + "," + n2);
98     Logger.info("grid parameters: nxStart,nyStart,nzStart: " + xyzStart[0]
99         + "," + xyzStart[1] + "," + xyzStart[2]);
100 
101     Logger.info("grid parameters: mx,my,mz: " + na + "," + nb + "," + nc);
102     Logger.info("grid parameters: a,b,c,alpha,beta,gamma: " + a + "," + b + ","
103         + c + "," + alpha + "," + beta + "," + gamma);
104     Logger.info("grid parameters: mapc,mapr,maps: " + mapc + "," + mapr + ","
105         + maps);
106     Logger.info("grid parameters: originX,Y,Z: " + origin);
107 
108     SimpleUnitCell unitCell = SimpleUnitCell.newA(new float[] { a / na, b / nb,
109         c / nc, alpha, beta, gamma });
110 
111     /*
112 
113      Many thanks to Eric Martz for helping get this right.
114      Basically we have:
115 
116      Three principal crystallographic axes: a, b, and c...
117      ...also referred to as x, y, and z
118      ...also referred to as directions 1, 2, and 3
119      ...a mapping of "sheets" "rows" and "columns" of data
120         set in the file as
121 
122                          s1r1c1...s1r1c9.....
123                          s1r2c1...s1r2c9.....
124 
125                          s2r1c1...s2r1c9.....
126                          s2r2c1...s2r2c9.....
127      etc.
128 
129      In Jmol, we always have x (our [0]) running slowest, so we
130      ultimately must make the following assignment:
131 
132        MRC "maps" maps to .x or [0]
133        MRC "mapr" maps to .y or [1]
134        MRC "mapc" maps to .z or [2]
135 
136      We really don't care if this is actually physical "x" "y" or "z".
137      In fact, for a hexagonal cell these will be combinations of xyz.
138 
139      So it goes something like this:
140 
141      scale the (a) vector by 1/mx and call that vector[0]
142      scale the (b) vector by 1/my and call that vector[1]
143      scale the (c) vector by 1/mz and call that vector[2]
144 
145      Now map these vectors to Jmol volumetricVectors using
146 
147      our x: volVector[0] = vector[maps - 1]  (slow)
148      our y: volVector[1] = vector[mapr - 1]
149      our z: volVector[2] = vector[mapc - 1]  (fast)
150 
151      This is because our x is the slowest running variable.
152     */
153 
154     vectors[0] = P3.new3(1, 0, 0);
155     vectors[1] = P3.new3(0, 1, 0);
156     vectors[2] = P3.new3(0, 0, 1);
157     unitCell.toCartesian(vectors[0], false);
158     unitCell.toCartesian(vectors[1], false);
159     unitCell.toCartesian(vectors[2], false);
160 
161     Logger.info("Jmol unit cell vectors:");
162     Logger.info("    a: " + vectors[0]);
163     Logger.info("    b: " + vectors[1]);
164     Logger.info("    c: " + vectors[2]);
165 
166     // we must pass through the data as it is present
167 
168     voxelCounts[0] = n2; // slowest
169     voxelCounts[1] = n1;
170     voxelCounts[2] = n0; // fastest
171 
172     volumetricVectors[0].setT(vectors[maps - 1]);
173     volumetricVectors[1].setT(vectors[mapr - 1]);
174     volumetricVectors[2].setT(vectors[mapc - 1]);
175 
176     // only use nxyzStart if the origin is {0, 0, 0}
177 
178     if (origin.x == 0 && origin.y == 0 && origin.z == 0) {
179 
180       // older method -- wow! Beats me.....
181 
182       if (xIndex == -1) {
183         int[] xyz2crs = new int[3];
184         xyz2crs[mapc - 1] = 0; // mapc = 2 ==> [1] = 0
185         xyz2crs[mapr - 1] = 1; // mapr = 1 ==> [0] = 1
186         xyz2crs[maps - 1] = 2; // maps = 3 ==> [2] = 2
187         xIndex = xyz2crs[0]; // xIndex = 1
188         yIndex = xyz2crs[1]; // yIndex = 0
189         zIndex = xyz2crs[2]; // zIndex = 2
190       }
191 
192       origin.scaleAdd2(xyzStart[xIndex]/* + adjustment.x */, vectors[0],
193           origin);
194       origin.scaleAdd2(xyzStart[yIndex]/* + adjustment.y */, vectors[1],
195           origin);
196       origin.scaleAdd2(xyzStart[zIndex]/* + adjustment.z */, vectors[2],
197           origin);
198 
199     }
200 
201     volumetricOrigin.setT(origin);
202 
203     Logger.info("Jmol grid origin in Cartesian coordinates: " + origin);
204     Logger.info("Use  isosurface OFFSET {x y z}  if you want to shift it.\n");
205 
206     p3.set(na, nb, nc);
207     unitCell.toCartesian(p3, true);
208     p3.add(origin);
209     Logger.info("boundbox corners " +  origin + " " + p3 + ";draw bbox boundbox mesh nofill");
210 
211     /* example:
212 
213     isosurface within 5 {_Fe} "1blu.ccp4";
214     reading isosurface data from C:/jmol-dev/workspace/Jmol/bobtest/1blu.ccp4
215     FileManager opening C:\jmol-dev\workspace\Jmol\bobtest\1blu.ccp4
216     data file type was determined to be MRC-
217     FileManager opening C:\jmol-dev\workspace\Jmol\bobtest\1blu.ccp4
218     MRC header: mode: 2
219     MRC header: dmin,dmax,dmean: -2.0043933,4.9972544,-0.0151823275
220     MRC header: ispg,nsymbt: 152,0
221     MRC header: rms: 0.46335652
222     MRC header: labels: 1
223     Created by MAPMAN V. 080625/7.8.5 at Tue Jan 19 08:04:40 2010 for A. Nonymous
224     MRC header: bytes read: 1024
225 
226     cutoff set to (dmean + 2*rms) = 0.91153073
227     grid parameters: nx,ny,nz: 73,60,66
228     grid parameters: nxStart,nyStart,nzStart: -12,23,-32
229     grid parameters: mx,my,mz: 78,78,114
230     grid parameters: a,b,c,alpha,beta,gamma: 52.0,52.0,77.1875,90.0,90.0,120.0
231     grid parameters: mapc,mapr,maps: 2,1,3
232     grid parameters: originX,Y,Z: 0.0,0.0,0.0
233     Jmol unit cell vectors:
234     a: (0.6666667, 0.0, 0.0)
235     b: (-0.33333337, 0.57735026, 0.0)
236     c: (-2.9596254E-8, -5.1262216E-8, 0.6770833)
237     Jmol grid origin in Cartesian coordinates: (19.333334, -6.9282017, -21.666666)
238     Jmol origin in slow-to-fast system: (19.333334, -6.9282017, -21.666666)
239 
240     */
241 
242   }
243 
setCutoffAutomatic()244   protected void setCutoffAutomatic() {
245     if (params.thePlane == null && params.cutoffAutomatic) {
246       params.cutoff = -1f;
247       Logger.info("MapReader: setting cutoff to default value of "
248           + params.cutoff
249           + (boundingBox == null ? " (no BOUNDBOX parameter)\n" : "\n"));
250     }
251   }
252 
253 
254 }
255