/*
* This file is part of MoleculeViewer.
*
* MoleculeViewer is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MoleculeViewer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with MoleculeViewer. If not, see <http://www.gnu.org/licenses/>.
*/
package astex;
/* Copyright Astex Technology Ltd. 1999 */
/* Copyright David Hall, Boston University, 2011 */
/*
* 09-08-02 mjh
* add functionality for managing InsightII grid map files
* in the Map object.
* 20-12-99 mjh
* not correctly handling big and little endian file types.
* 11-11-99 mjh
* created
*/
import java.io.*;
/**
* A class for storing an electron density map.
*/
public class Map extends Symmetry {
/** Volume render. */
public boolean volumeRender = false;
/** Volume color. */
public int volumeColor = Color32.red;
/** Volume min. */
public double volumeMin = 0.0;
/** Volume max. */
public double volumeMax = 1.0;
/** Maximum number of contour levels. */
public static final int MaximumContourLevels = 3;
/** The actual contour levels. */
private double contourLevels[] = new double[MaximumContourLevels];
/** The color for the contour levels. */
private int contourColors[] = new int[MaximumContourLevels];
/** The color for the contour levels. */
private int contourStyle[] = new int[MaximumContourLevels];
/** Types for the display style. */
public static final int Lines = 1;
public static final int Surface = 2;
/** Whether each level is displayed. */
private boolean contourDisplayed[] = new boolean[MaximumContourLevels];
/** Is the map file big endian or little endian. */
private boolean littleEndian = true;
/** Size of map grid. */
public int grid[] = new int[3];
/** Format that map data is stored in. */
private int mode;
/** Map center. */
private Point3d center = new Point3d();
/** Map radius. */
private double radius;
/** The file name or url that the map comes from. */
private String filename;
/** The name of the map. */
private String name;
/** The FILE object that we will read the data from. */
private FILE file;
/** Do we need to reread the file contents. */
private boolean needsReadingFlag = true;
/** Is header initialised. */
public boolean headerInitialised = false;
public enum MapType {
CCP4_BINARY,SYBYL_ASCII,INSIGHT_ASCII,ASTEX_ASCII,O_BINARY
}
/** What type is the map? */
private MapType mapType = MapType.CCP4_BINARY;
/** The center grid point for the current stored map data. */
public int centerGrid[] = new int[3];
/** The minimum grid point for the current stored map data. */
public int minimumGrid[] = new int[3];
/** The maximum grid point for the current stored map data. */
public int maximumGrid[] = new int[3];
/* various bogus stuff in the map header (some useful). */
public int nu[] = new int[3];
public int nv[] = new int[3];
public int axis[] = new int[3];
private int ihdr3[] = new int[3];
private int ihdr4[] = new int[17];
private int ihdr5[] = new int[1];
private char ihdr6[] = new char[800];
private double cell[] = new double[6];
private double rhdr2[] = new double[3];
private double rhdr3[] = new double[12];
public double rms;
public float data[] = null;
/* Regular format grids. */
/** The position of the first grid point. */
public Point3d origin = new Point3d();
/** The spacing along each axis. */
public Point3d spacing = new Point3d();
/** The number of grid points along each axis. */
public int ngrid[] = new int[3];
public boolean initialiseContours = true;
/** Private default constructor. */
private Map(){
}
/** Public interface to map creation. */
public static Map create(){
return new Map();
}
/** Create a simple map for internal use. */
public static Map createSimpleMap(){
Map map = create();
map.axis[0] = 0;
map.axis[1] = 1;
map.axis[2] = 2;
map.nv[0] = map.nv[1] = map.nv[2] = 1;
map.headerInitialised = true;
map.setMapType(MapType.INSIGHT_ASCII);
map.setSigma(1.0);
map.initialiseContours = false;
return map;
}
/** Return the sigma value for the map. */
public double getSigma(){
return rms;
}
/** Set the sigma level. */
public void setSigma(double s){
rms = s;
}
/** Does the map need reading. */
public boolean needsReading(){
return needsReadingFlag;
}
/** Set whether the map needs reading. */
public void setNeedsReading(boolean flag){
needsReadingFlag = flag;
}
/**
* Get the value of mapType.
* @return value of mapType.
*/
public MapType getMapType() {
return mapType;
}
/**
* Set the value of mapType.
* @param v Value to assign to mapType.
*/
public void setMapType(MapType v) {
this.mapType = v;
}
/** Read a map from the specified file object. */
public void read(){
if(file != null){
file.close();
file = null;
}
if(!headerInitialised){
file = FILE.open(filename);
readHeader();
}
}
/** Convert from big to little endian byte ordering. */
public static int convertBigToLittle(int i){
return (i >>> 24) | (i << 24) |
((i << 8) & 0x00ff0000) | ((i >> 8) & 0x0000ff00);
}
/** Read a map from the specified file object. */
public void readHeader(){
if(headerInitialised){
return;
}
if(mapType == MapType.CCP4_BINARY){
readCCP4Header();
}else if(mapType == MapType.O_BINARY){
readOHeader();
}else if(mapType == MapType.INSIGHT_ASCII){
readInsightHeader();
}else if(mapType == MapType.ASTEX_ASCII){
readAstexHeader();
}
}
/**
* Read an astex ascii file .sag (Simple Ascii Grid).
*
* Example file is
* <pre>
* # Simple ascii grid file
* # Header comments begin with '#' and
* # are optional
* # next come number of grid points (nx, ny, nz)
* # then come position of first grid point in x, y, z
* # then comes spacing of each cell.
* # Grid must be rectilinear
* # Finally come nx * ny * nz grid points
* # x varying fastest.
* 10 10 10
* 0.0 0.0 0.0
* 0.7 0.7 0.7
* 0.0
* ...
* 998 more data points
* ...
* 12.3
*/
private void readAstexHeader(){
while(file.nextLine()){
if(file.getChar(0) != '#'){
break;
}else{
String header = file.getCurrentLineAsString();
System.out.println(header);
}
}
ngrid[0] = file.readIntegerFromField(0);
ngrid[1] = file.readIntegerFromField(1);
ngrid[2] = file.readIntegerFromField(2);
file.nextLine();
origin.set(file.readDoubleFromField(0),
file.readDoubleFromField(1),
file.readDoubleFromField(2));
file.nextLine();
spacing.set(file.readDoubleFromField(0),
file.readDoubleFromField(1),
file.readDoubleFromField(2));
int dataPoints = ngrid[0] * ngrid[1] * ngrid[2];
ensureMapCapacity(dataPoints);
for(int i = 0; i < dataPoints; i++){
file.nextLine();
data[i] = (float)file.readDoubleFromField(0);
}
// dummy rms to give direct contour levels
rms = 1.0;
file.close();
}
/**
* Read the insight header.
* This seemingly straight forward ascii grid file
* format has possibly the most confusing set of
* interdependent parameters that describe the
* layout of the grid.
*/
private void readInsightHeader(){
// make the rms 1.0 so that we contour
// directly at the level specified.
rms = 1.0;
file.nextLine();
System.out.println(file.getCurrentLineAsString());
file.nextLine();
System.out.println(file.getCurrentLineAsString());
file.nextLine();
String fields[] = FILE.split(file.getCurrentLineAsString());
double lx = FILE.readDouble(fields[0]);
double ly = FILE.readDouble(fields[1]);
double lz = FILE.readDouble(fields[2]);
file.nextLine();
fields = FILE.split(file.getCurrentLineAsString());
ngrid[0] = FILE.readInteger(fields[0]) + 1;
ngrid[1] = FILE.readInteger(fields[1]) + 1;
ngrid[2] = FILE.readInteger(fields[2]) + 1;
for(int i = 0; i < 3; i++){
minimumGrid[i] = 0;
maximumGrid[i] = ngrid[i];
nu[i] = 0;
}
file.nextLine();
fields = FILE.split(file.getCurrentLineAsString());
double dx = lx/(double)(ngrid[0] - 1);
double dy = ly/(double)(ngrid[1] - 1);
double dz = lz/(double)(ngrid[2] - 1);
spacing.set(dx, dy, dz);
double ox = FILE.readInteger(fields[1]) * dx;
double oy = FILE.readInteger(fields[3]) * dy;
double oz = FILE.readInteger(fields[5]) * dz;
origin.set(ox, oy, oz);
System.out.println("Origin ... " + origin);
System.out.println("Spacing .." + spacing);
int dataPoints = ngrid[0] * ngrid[1] * ngrid[2];
ensureMapCapacity(dataPoints);
for(int i = 0; i < dataPoints; i++){
file.nextLine();
data[i] = (float)file.readDouble(0, 10);
}
file.close();
}
int oheader[] = new int[23];
byte odata[][][] = null;
int extent[] = new int[3];
double prod = 0.0;
double plus = 0.0;
/** Read an O header. */
private void readOHeader(){
readShortArray(file, oheader);
for(int i = 0; i < 512-(23*2); i++){
int c = file.read();
if(c == FILE.EOF){
System.out.println("eof reading o header");
return;
}
}
int iprod = oheader[15];
int iplus = oheader[16];
int iscale1 = oheader[17];
int iscale2 = oheader[18];
int isigma = oheader[21];
extent[0] = oheader[3];
extent[1] = oheader[4];
extent[2] = oheader[5];
// and set up ccp4 map equivalents
nu[0] = oheader[0];
nu[1] = oheader[1];
nu[2] = oheader[2];
nv[0] = oheader[6];
nv[1] = oheader[7];
nv[2] = oheader[8];
grid[0] = extent[0];
grid[1] = extent[1];
grid[2] = extent[2];
// dummy axis reordering
axis[0] = 0;
axis[1] = 1;
axis[2] = 2;
if(iscale1 == 0) iscale1 = 100;
if(iscale2 == 0) iscale2 = 100;
prod = (double)iprod/(double)iscale2;
plus = iplus;
double sigma = ((double)isigma-plus)/prod;
rms = sigma;
// scale the cell parameters
for(int i = 0; i < 6; i++){
cell[i] = (double)oheader[i+9]/(double)iscale1;
}
// now get the data...
// taken mostly verbatim from Mark Harris'
// reader for the EDS java viewer.
int inx = extent[0]/8; // How many cubies in each direction
int iny = extent[1]/8;
int inz = extent[2]/8;
if ((extent[0]%8) > 0) inx++; // Including any partials
if ((extent[1]%8) > 0) iny++;
if ((extent[2]%8) > 0) inz++;
int xtraX = (extent[0]%8); // How much of last cubie to read ?
int xtraY = (extent[1]%8);
int xtraZ = (extent[2]%8);
byte data[] = new byte[512];
//odata = new byte[inx*8 * iny*8 * inz*8];
odata = new byte[inx*8][iny*8][inz*8];
for (int k=0; k < inz; k++) {
for (int j=0; j < iny; j++) {
for (int i=0; i < inx; i++) {
for(int d = 0; d < 512; d++){
data[d] = (byte)file.read();
}
// Swap bytes on littleEndians !
boolean byteSwap = true;
if (byteSwap) {
for (int ii=0; ii < 511; ii+=2) {
byte dum = data[ii];
data[ii] = data[ii+1];
data[ii+1] = dum;
}
}
int cubieSizeX = 8;
int cubieSizeY = 8;
int cubieSizeZ = 8;
// For partial cubies
if (xtraX > 0 && i == inx-1) cubieSizeX = xtraX;
if (xtraY > 0 && j == iny-1) cubieSizeY = xtraY;
if (xtraZ > 0 && k == inz-1) cubieSizeZ = xtraZ;
for (int n = 0; n < cubieSizeZ; n++) {
for (int m = 0; m < cubieSizeY; m++) {
for (int l = 0; l < cubieSizeX; l++) {
byte sboxLMN = data[8*8*n+8*m+l];
// No unsigned types in Java !
int pt3 = (k)*8 + n;
int pt2 = (j)*8 + m;
int pt1 = (i)*8 + l;
odata[pt1][pt2][pt3] = sboxLMN;
} // l
} // m
} // n
} // i
} // j
} // k
// setup the different matrices.
setUnitCell(cell);
headerInitialised = true;
printHeader(System.out);
}
/** Read a CCP4 header. */
private void readCCP4Header(){
readIntegerArray(file, grid);
// check to see if little or big endian
int firstWord = grid[0];
if(firstWord > 65536 || firstWord < -65536){
littleEndian = false;
grid[0] = convertBigToLittle(grid[0]);
grid[1] = convertBigToLittle(grid[1]);
grid[2] = convertBigToLittle(grid[2]);
}
mode = readInteger(file);
// we only support modes 0 and 2.
if(mode != 0 && mode != 2){
file.close();
file = null;
return;
}
readIntegerArray(file, nu);
readIntegerArray(file, nv);
readDoubleArray(file, cell);
readIntegerArray(file, axis);
// make the axis 0-indexed
for(int i = 0; i < 3; i++){
axis[i] -= 1;
}
readDoubleArray(file, rhdr2);
readIntegerArray(file, ihdr3);
readDoubleArray(file, rhdr3);
readIntegerArray(file, ihdr4);
rms = (double)readFloat(file);
//System.out.println("rms " + rms);
readIntegerArray(file, ihdr5);
for(int i = 0; i < ihdr6.length; i++){
ihdr6[i] = (char)file.read();
}
// skip the symmetry operators
for(int i = 0; i < ihdr3[1]; i++){
file.read();
}
// store the space group number
setSpaceGroupNumber(ihdr3[0]);
System.out.println("ihdr3[0] " + ihdr3[0]);
System.out.println("gsgn " + getSpaceGroupNumber());
// setup the different matrices.
setUnitCell(cell);
printHeader(System.out);
}
/** Print the header for the map. */
public void printHeader(PrintStream printStream){
Format d5 = new Format("%5d");
Format f5 = new Format("%10.5f");
Format f3 = new Format("%8.3f");
printStream.println("Map " + getFile());
printStream.print("Grid in file ");
printStream.print(d5.format(grid[0]));
printStream.print(d5.format(grid[1]));
printStream.print(d5.format(grid[2]));
printStream.println("");
printStream.print("Grid origin ");
printStream.print(d5.format(nu[0]));
printStream.print(d5.format(nu[1]));
printStream.print(d5.format(nu[2]));
printStream.println("");
printStream.print("Grid size ");
printStream.print(d5.format(nv[0]));
printStream.print(d5.format(nv[1]));
printStream.print(d5.format(nv[2]));
printStream.println("");
printStream.print("RMS density " + f5.format(rms));
printStream.println("");
printStream.print("Map mode " + d5.format(mode));
if(mode == 2){
printStream.print(" (4-byte float)");
}
printStream.println("");
printStream.print("Axis order ");
for(int j = 0; j < 3; j++){
printStream.print(" ");
if(axis[j] == 0){
printStream.print("X");
}else if(axis[j] == 1){
printStream.print("Y");
}else if(axis[j] == 2){
printStream.print("Z");
}
}
printStream.println("");
printStream.print("Unit cell ");
printStream.print(f3.format(cell[0]));
printStream.print(f3.format(cell[1]));
printStream.print(f3.format(cell[2]));
printStream.print(f3.format(cell[3]));
printStream.print(f3.format(cell[4]));
printStream.print(f3.format(cell[5]));
printStream.println("");
}
/** Set the center point of the region we will contour. */
public void setCenter(double x, double y, double z){
center.set(x, y, z);
needsReadingFlag = true;
}
/** Set the center point of the region we will contour. */
public void setCenter(Point3d p){
center = p.clone();
needsReadingFlag = true;
}
/** Set the radius of the region we will contour. */
public void setRadius(double r){
radius = r;
}
/** Get the radius of the current map region. */
public double getRadius(){
return radius;
}
/** Set the map name. */
public void setName(String mapName){
name = mapName.replace('\\', '/');
}
/** Get the map name. */
public String getName(){
return name;
}
/**
* Set the filename. We need to know where it came from so we
* can reread the map when we recenter.
*/
public void setFile(String file){
System.out.println("file |"+file+"|");
filename = file;
if(file.indexOf(".grd") != -1){
mapType = MapType.INSIGHT_ASCII;
}else if(file.indexOf(".acnt") != -1){
mapType = MapType.SYBYL_ASCII;
}else if(file.indexOf(".map") != -1){
mapType = MapType.CCP4_BINARY;
}else if(file.indexOf(".omap") != -1){
mapType = MapType.O_BINARY;
}else if(file.indexOf(".sag") != -1){
mapType = MapType.ASTEX_ASCII;
}
}
/** Get the filename. */
public String getFile(){
return filename;
}
/** Ensure we have enough room to store the map. */
public void ensureMapCapacity(int dataPoints){
if(data == null || dataPoints > data.length){
data = new float[dataPoints];
}
}
/** Read the determined region from the map. */
public void readRegion(){
//System.out.println("readRegion");
if(mapType != MapType.CCP4_BINARY && mapType != MapType.O_BINARY){
return;
}
if((mapType == MapType.CCP4_BINARY && mode != 0 && mode != 2)){
return;
}
// does this need to be +1?
int dx = maximumGrid[0] - minimumGrid[0];
int dy = maximumGrid[1] - minimumGrid[1];
int dz = maximumGrid[2] - minimumGrid[2];
int dataPoints = dx * dy * dz;
ensureMapCapacity(dataPoints);
// a running total of how many relevant grid points we read
int point = 0;
// read the data slowest axis first
int grid0 = grid[0];
int grid1 = grid[1];
int grid2 = grid[2];
int max0 = maximumGrid[0];
int max1 = maximumGrid[1];
int max2 = maximumGrid[2];
int min0 = minimumGrid[0];
int min1 = minimumGrid[1];
int min2 = minimumGrid[2];
if(mapType == MapType.CCP4_BINARY){
for(int s = 0; s < grid2; s++){
if(s >= maximumGrid[2]){
// we got the region we were interested in
break;
}
for(int r = 0; r < grid1; r++){
for(int c = 0; c < grid0; c++){
if(s >= min2 && s < max2 &&
r >= min1 && r < max1 &&
c >= min0 && c < max0){
float f = readFloat(file);
data[point++] = f;
}else{
// just read as integer if we aren't
// using it as we avoid overhead of converting
// to float
int i = file.skip(4);
if(i == FILE.EOF){
System.out.println("unexpected EOF!");
}
}
}
}
}
}else if(mapType == MapType.O_BINARY){
for(int s = 0; s < grid2; s++){
for(int r = 0; r < grid1; r++){
for(int c = 0; c < grid0; c++){
if(s >= min2 && s < max2 &&
r >= min1 && r < max1 &&
c >= min0 && c < max0){
byte b = odata[c][r][s];
short sb = 0;
if(b < 0){
sb = (short)((int)b + 256);
}else{
sb = b;
}
float f = (float)(((float)sb - plus)/prod);
data[point++] = f;
}
}
}
}
}else{
System.out.println("trying to reread data for type " + mapType);
}
if(file != null){
file.close();
file = null;
}
}
/** Convert grid coordinates to cartesian. */
public void relativeGridToCartesian(double ix, double iy, double iz,
Point3d p){
absoluteGridToCartesian(ix + nu[0] + minimumGrid[0],
iy + nu[1] + minimumGrid[1],
iz + nu[2] + minimumGrid[2],
p);
}
private Point3d dummy = new Point3d();
/** Get the map value at relative grid point. */
public double getValueAtRelativeGrid(int gx, int gy, int gz){
int xsize = maximumGrid[0] - minimumGrid[0];
int ysize = maximumGrid[1] - minimumGrid[1];
int zsize = maximumGrid[2] - minimumGrid[2];
if(mapType == MapType.INSIGHT_ASCII){
xsize = ngrid[0];
ysize = ngrid[1];
zsize = ngrid[2];
}
if(gx >= 0 && gx < xsize &&
gy >= 0 && gy < ysize &&
gz >= 0 && gz < zsize){
int pos = gx;
pos += gy * xsize;
pos += gz * xsize * ysize;
return data[pos];
}
return 0.0;
}
/** Calculate the relative grid index. */
public int getRelativeGridIndex(int gx, int gy, int gz){
int xsize = maximumGrid[0] - minimumGrid[0];
int ysize = maximumGrid[1] - minimumGrid[1];
int zsize = maximumGrid[2] - minimumGrid[2];
if(mapType == MapType.INSIGHT_ASCII){
xsize = ngrid[0];
ysize = ngrid[1];
zsize = ngrid[2];
}
if(gx >= 0 && gx < xsize &&
gy >= 0 && gy < ysize &&
gz >= 0 && gz < zsize){
int pos = gx;
pos += gy * xsize;
pos += gz * xsize * ysize;
return pos;
}
return -1;
}
/** Return the size of map we have loaded. */
public void getMapBoxDimensions(int dims[]){
if(mapType == MapType.INSIGHT_ASCII){
System.arraycopy(ngrid, 0, dims, 0, 3);
}else{
dims[0] = maximumGrid[0] - minimumGrid[0];
dims[1] = maximumGrid[1] - minimumGrid[1];
dims[2] = maximumGrid[2] - minimumGrid[2];
}
}
/** Get the actual data array. */
public float[] getDataArray(){
return data;
}
/** Private variable for converting coordinates. */
private double xxx[] = new double[3];
/** Private variable for converting coordinates. */
private double swapped[] = new double[3];
/** Convert grid coordiantes to cartesian. */
public void absoluteGridToCartesian(double ix, double iy, double iz,
Point3d p){
xxx[0] = ix; xxx[1] = iy; xxx[2] = iz;
if(mapType == MapType.INSIGHT_ASCII){
p.x = origin.x + spacing.x * ix;
p.y = origin.y + spacing.y * iy;
p.z = origin.z + spacing.z * iz;
}else{
swapped[axis[0]] = xxx[0];
swapped[axis[1]] = xxx[1];
swapped[axis[2]] = xxx[2];
for(int j = 0; j < 3; j++){
//xxx[j] += nu[j];
swapped[j] /= nv[j];
}
//p.set(xxx[0], xxx[1], xxx[2]);
//p.set(xxx[axis[0]], xxx[axis[1]], xxx[axis[2]]);
p.set(swapped[0], swapped[1], swapped[2]);
p.transform(fractionalToCartesian);
}
}
/** Find nearest relative grid point to the specified point. */
public void nearestRelativeGrid(Point3d p, int g[]){
dummy.set(p);
dummy.transform(cartesianToFractional);
xxx[0] = dummy.x * nv[0];
xxx[1] = dummy.y * nv[1];
xxx[2] = dummy.z * nv[2];
swapped[0] = xxx[axis[0]];
swapped[1] = xxx[axis[1]];
swapped[2] = xxx[axis[2]];
swapped[0] -= nu[0] + minimumGrid[0];
swapped[1] -= nu[1] + minimumGrid[1];
swapped[2] -= nu[2] + minimumGrid[2];
g[0] = (int)(swapped[0] + 0.5);
g[1] = (int)(swapped[1] + 0.5);
g[2] = (int)(swapped[2] + 0.5);
}
/** Find nearest relative grid point to the specified point. */
public void lowerRelativeGrid(Point3d p, int g[]){
dummy.set(p);
dummy.transform(cartesianToFractional);
xxx[0] = dummy.x * nv[0];
xxx[1] = dummy.y * nv[1];
xxx[2] = dummy.z * nv[2];
swapped[0] = xxx[axis[0]];
swapped[1] = xxx[axis[1]];
swapped[2] = xxx[axis[2]];
swapped[0] -= nu[0] + minimumGrid[0];
swapped[1] -= nu[1] + minimumGrid[1];
swapped[2] -= nu[2] + minimumGrid[2];
g[0] = (int)(swapped[0]);
g[1] = (int)(swapped[1]);
g[2] = (int)(swapped[2]);
}
/** Print an array. */
public static void printArray(String name, int array[]){
System.out.print(name);
for(int i = 0; i < array.length; i++){
System.out.print(" " + array[i]);
}
System.out.println("");
}
/** Print an array. */
public static void printArray(String name, double array[]){
System.out.print(name);
for(int i = 0; i < array.length; i++){
System.out.print(" " + array[i]);
}
System.out.println("");
}
/** Read an array of ints from underlying file. */
private int readShortArray(FILE file, int array[]){
return readShortArray(file, array, array.length);
}
/** Read an array of ints from underlying file. */
private int readShortArray(FILE file, int array[], int count){
for(int i = 0; i < count; i++){
array[i] = readShort(file);
}
return 0;
}
/** Read an array of ints from underlying file. */
private int readIntegerArray(FILE file, int array[]){
return readIntegerArray(file, array, array.length);
}
/** Read an array of ints from underlying file. */
private int readIntegerArray(FILE file, int array[], int count){
for(int i = 0; i < count; i++){
array[i] = readInteger(file);
}
return 0;
}
/** Read an array of float from underlying file. */
private int readDoubleArray(FILE file, double array[]){
return readDoubleArray(file, array, array.length);
}
/** Read an array of float from underlying file. */
private int readDoubleArray(FILE file, double array[], int count){
for(int i = 0; i < count; i++){
array[i] = (double)readFloat(file);
}
return 0;
}
/**
* Read a 2 byte word from the file.
* This should really go in FILE but we'll keep it here for now.
*/
private int readShort(FILE file){
if(file == null){
System.out.println("Map.readShort: file is null");
}
int ch1 = file.read();
int ch2 = file.read();
if(ch1 == FILE.EOF|| ch2 == FILE.EOF){
System.out.println("eof in readShort");
return FILE.EOF;
}
// yes this does seem necessary to convert
// to signed properly...
if(littleEndian)
return (int)((short)(((ch1 << 8) + ((ch2)))));
return (int)((short)(((ch2 << 8) + ((ch1)))));
}
/**
* Read a 4 byte word from the file.
* This should really go in FILE but we'll keep it here for now.
*/
private int readInteger(FILE file){
int ch1 = file.read();
int ch2 = file.read();
int ch3 = file.read();
int ch4 = file.read();
if ((ch1 == FILE.EOF|| ch2 == FILE.EOF||
ch3 == FILE.EOF|| ch4 == FILE.EOF)){
System.out.println("eof");
}
if(littleEndian)
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
}
/**
* Read a float from the file.
* This relies on the Float.intBitsToFloat() method
* to correctly interpret the underlying data.
*/
private float readFloat(FILE file){
int data = readInteger(file);
return Float.intBitsToFloat(data);
}
/* Methods for setting the various attributes of the contour leves. */
/** Set the specified contour level. */
public void setContourLevel(int i, double level){
if(i >= 0 && i < MaximumContourLevels){
contourLevels[i] = level;
}
}
/** Set the specified contour color. */
public void setContourColor(int i, int color){
if(i >= 0 && i < MaximumContourLevels){
contourColors[i] = color;
}
}
/** Set the specified contour color. */
public void setContourStyle(int i, int style){
if(i >= 0 && i < MaximumContourLevels){
contourStyle[i] = style;
}
}
/** Set if the specified contour is displayed. */
public void setContourDisplayed(int i, boolean displayed){
if(i >= 0 && i < MaximumContourLevels){
contourDisplayed[i] = displayed;
}
}
/** Get the specified contour level. */
public double getContourLevel(int i){
if(i >= 0 && i < MaximumContourLevels){
return contourLevels[i];
}
return 0.0;
}
/** Get the specified contour color. */
public int getContourColor(int i){
if(i >= 0 && i < MaximumContourLevels){
return contourColors[i];
}
return 0;
}
/** Get the specified contour color. */
public int getContourStyle(int i){
if(i >= 0 && i < MaximumContourLevels){
return contourStyle[i];
}
return Lines;
}
/** Get if the specified contour is displayed. */
public boolean getContourDisplayed(int i){
if(i >= 0 && i < MaximumContourLevels){
return contourDisplayed[i];
}
return false;
}
public boolean hasContoursDisplayed(){
for(int i = 0; i < MaximumContourLevels; i++){
if(getContourDisplayed(i)){
return true;
}
}
return false;
}
}