Ecological niche modelling or ENM (often wrongly called “species distribution modelling” or SDM) is now a very widely used tool in ecology. A major factor in its widespread use is the MaxEnt program written by Steven Phillips and colleagues.
MaxEnt, like all ENM methods, tries to figure out the relationship between a organism and the environment in which it is known to occur, and use this relationship to predict other times or places which may be suitable for the organism. The environment is typically represented by a selection of environmental variables in the form of GIS grids, rasters or layers. MaxEnt can read and write environmental data in four different formats one of which is it’s own “mxe” format.
An mxe file is actually a gzip archive file. Unpacking an mxe file however doesn’t directly recover the raw data in a grid file. Instead, it unpacks into another binary file type. After some comparative work (ie comparing an ASCII character form of a GIS grid file with gzip, zip and mxe versions of the same file) I concluded that the binary file was a Java structure saved to disk.
# A file to play with
fn <- "~/Climate_data/Current/WorldClim/EastOZ_30s/scratch/bio01.mxe"
# Establish a file connection object pointing to the mxe file:
mxe.gz <- gzfile(fn,"rb")
# Now read stuff...
junk <- readBin(mxe.gz,"raw",9,endian="big")
xll <- readBin(mxe.gz,"double",1,endian="big")
yll <- readBin(mxe.gz,"double",1,endian="big")
cellsize <- readBin(mxe.gz,"double",1,endian="big")
nrow <- readBin(mxe.gz,"integer",1,endian="big")
ncol <- readBin(mxe.gz,"integer",1,endian="big")
nodata <- readBin(mxe.gz,"integer",1,endian="big")
junk <- readBin(mxe.gz,"raw",5,endian="big")
data <- readBin(mxe.gz,"numeric",size=4,n=nrow*ncol,endian="big")
# Tidy-up
close(mxe.gz)
A few things to note:
Working on a Linux-powered machine with an Intel CPU, mxe files were found to have big-endian byte ordering. On other platforms it may be little-endian byte ordering - users will have to check.
The numeric type differs amongst the fields. R’s type “double” corresponds to 8-byte floating point format; “integer” is a 4-byte signed integer; and “raw” is untyped array of byte-values of the length indicated.
The data type for the “data” object may vary from that shown in this example code. If you have used MaxEnt to convert a group of files you be familiar with the different data types MaxEnt reports during the conversion. In the example, I needed to read a numeric filed called FLOAT4 by MaxEnt. This can be achieved by setting the “what” parameter to the generic “numeric” type and forcing the readBin function to read a 4-byte value from the binary stream with size=4 parameter setting.
Two regions in the mxe file structure are yet be deciphered and are stored I the “junk1” and “junk2” objects.
So, there it is. I hope this will prove to be useful to someone, somewhere, at some time.