add loadmat function

This commit is contained in:
wyq 2023-12-23 00:37:25 +08:00
parent 087a811810
commit 25f01acc1c
13 changed files with 134 additions and 79 deletions

View File

@ -67,7 +67,7 @@ import java.util.zip.ZipInputStream;
public static String getVersion(){
String version = GlobalUtil.class.getPackage().getImplementationVersion();
if (version == null || version.equals("")) {
version = "3.7.5";
version = "3.7.6";
}
return version;
}

View File

@ -476,14 +476,14 @@ public class MeteoDataInfo {
RandomAccessFile raf = new RandomAccessFile(fileName, "r");
if (GrADSDataInfo.class.getDeclaredConstructor().newInstance().isValidFile(raf)) {
di = new GrADSDataInfo();
} else if (MatLabDataInfo.class.getDeclaredConstructor().newInstance().isValidFile(raf)) {
di = new MatLabDataInfo();
} else if (NetcdfFiles.canOpen(fileName)) {
di = new NetCDFDataInfo();
} else if (ARLDataInfo.class.getDeclaredConstructor().newInstance().isValidFile(raf)) {
di = new ARLDataInfo();
} else if (CMARadarBaseDataInfo.canOpen(fileName)) {
di = new CMARadarBaseDataInfo();
} else if (MatLabDataInfo.class.getDeclaredConstructor().newInstance().isValidFile(raf)) {
di = new MatLabDataInfo();
} else {
di = MICAPSDataInfo.getDataInfo(raf);
}
@ -885,17 +885,6 @@ public class MeteoDataInfo {
_infoText = dataInfo.generateInfoText();
}
/**
* Open numpy data file
*
* @param fileName File path
*/
public void openNumpyData(String fileName) {
dataInfo = new NumpyDataInfo();
dataInfo.readDataInfo(fileName);
_infoText = dataInfo.generateInfoText();
}
/**
* Open MICAPS data
*

View File

@ -1,8 +1,6 @@
package org.meteoinfo.data.meteodata.matlab;
import com.google.common.base.Charsets;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.meteoinfo.common.DataConvert;
import org.meteoinfo.data.GridArray;
import org.meteoinfo.data.GridData;
import org.meteoinfo.data.dimarray.Dimension;
@ -12,17 +10,13 @@ import org.meteoinfo.data.meteodata.IGridDataInfo;
import org.meteoinfo.data.meteodata.Variable;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.InvalidRangeException;
import us.hebi.matlab.mat.format.CharEncoding;
import org.meteoinfo.ndarray.io.matlab.MatLabUtil;
import us.hebi.matlab.mat.format.Mat5;
import us.hebi.matlab.mat.format.Mat5File;
import us.hebi.matlab.mat.types.*;
import us.hebi.matlab.mat.util.Bytes;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteOrder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@ -36,7 +30,7 @@ public class MatLabDataInfo extends DataInfo implements IGridDataInfo {
byte[] bytes = new byte[116];
raf.seek(0);
raf.read(bytes);
String magic = MatLabDataInfo.parseAsciiString(bytes);
String magic = MatLabUtil.parseAsciiString(bytes);
if (magic.startsWith(MAT5_IDENTIFIER)) {
return true;
} else {
@ -59,7 +53,7 @@ public class MatLabDataInfo extends DataInfo implements IGridDataInfo {
raf.seek(0);
raf.read(bytes);
raf.close();
String magic = MatLabDataInfo.parseAsciiString(bytes);
String magic = MatLabUtil.parseAsciiString(bytes);
if (magic.startsWith(MAT5_IDENTIFIER)) {
return true;
} else {
@ -70,23 +64,6 @@ public class MatLabDataInfo extends DataInfo implements IGridDataInfo {
}
}
static String parseAsciiString(byte[] buffer) {
return parseAsciiString(buffer, 0, buffer.length);
}
static String parseAsciiString(byte[] buffer, int offset, int maxLength) {
// Stop at String end character
int length = Bytes.findFirst(buffer, offset, maxLength, (byte) '\0', maxLength);
// Remove right-side trailing spaces
while (length > 0 && buffer[length - 1] == ' ') {
length--;
}
// Convert to String
return length == 0 ? "" : new String(buffer, offset, length, Charsets.US_ASCII);
}
@Override
public void readDataInfo(String fileName) {
// Iterate over all entries in the mat file

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\numpy">
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\matlab">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\city"/>
@ -13,24 +13,20 @@
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\text"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\array"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\matlab"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\numpy"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\matlab"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\plot\plot3_multi_color_chinese.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\numpy\test_npy_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_2.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_npz_2.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\numpy\savez_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\matlab\loadmat_1.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\plot\plot3_multi_color_chinese.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\io\numpy\test_npy_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_2.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_npz_2.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\io\numpy\savez_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\io\numpy\load_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\io\matlab\loadmat_1.py"/>
</RecentFiles>
</File>
<Font>
@ -38,5 +34,5 @@
</Font>
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
<Figure DoubleBuffering="true"/>
<Startup MainFormLocation="-7,0" MainFormSize="1420,834"/>
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685"/>
</MeteoInfo>

View File

@ -32,7 +32,7 @@ import mipylib.migl as migl
__all__ = [
'addfile','addfiles','addfile_arl','addfile_ascii_grid','addfile_awx','addfile_geotiff',
'addfile_grads','addfile_hyconc','addfile_hytraj','addfile_hypart','addfile_lonlat',
'addfile_matlab','addfile_micaps','addfile_mm5','addfile_nc','addfile_numpy','addfile_grib','addfile_surfer',
'addfile_matlab','addfile_micaps','addfile_mm5','addfile_nc','addfile_grib','addfile_surfer',
'add_bufr_lookup', 'addtimedim','joinncfile','asciiread','asciiwrite','bincreate','binread',
'binwrite', 'numasciicol','numasciirow','readtable','convert2nc','grads2nc','ncwrite'
]
@ -286,22 +286,6 @@ def addfile_matlab(fname, getfn=True):
datafile = DimDataFile(meteodata)
return datafile
def addfile_numpy(fname, getfn=True):
"""
Add a numpy data file.
:param fname: (*string*) The numpy file name.
:param getfn: (*string*) If run ``__getfilename`` function or not. Default is ``True``.
:returns: (*DimDataFile*) Opened file object.
"""
if getfn:
fname, isweb = __getfilename(fname)
meteodata = MeteoDataInfo()
meteodata.openNumpyData(fname)
datafile = DimDataFile(meteodata)
return datafile
def addfile_lonlat(fname, getfn=True, missingv=-9999.0):
"""
Add a Lon/Lat ASCII data file.

View File

@ -9,7 +9,8 @@ from .index_tricks import *
from .stride_tricks import *
from .type_check import *
from .arraysetops import *
from npyio import *
from .npyio import *
from .matio import *
__all__ = []
__all__ += shape_base.__all__
@ -18,4 +19,5 @@ __all__ += index_tricks.__all__
__all__ += stride_tricks.__all__
__all__ += type_check.__all__
__all__ += arraysetops.__all__
__all__ += npyio.__all__
__all__ += npyio.__all__
__all__ += matio.__all__

View File

@ -0,0 +1,17 @@
from org.meteoinfo.ndarray.io.matlab import Mat
from ..core._ndarray import NDArray
__all__ = ['loadmat']
def loadmat(file):
"""
Load MATLAB file.
:param file: (*str*) Data file path.
:return: Diction of arrays.
"""
data_map = Mat.load(file)
data = {k: NDArray(data_map[k]) for k in data_map}
return data

View File

@ -96,6 +96,11 @@
<version>5.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>us.hebi.matlab.mat</groupId>
<artifactId>mfl-core</artifactId>
<version>0.5.15</version>
</dependency>
<!--<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>

View File

@ -0,0 +1,36 @@
package org.meteoinfo.ndarray.io.matlab;
import org.meteoinfo.ndarray.Array;
import us.hebi.matlab.mat.format.Mat5;
import us.hebi.matlab.mat.types.MatFile;
import us.hebi.matlab.mat.types.Matrix;
import us.hebi.matlab.mat.types.Source;
import us.hebi.matlab.mat.types.Sources;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class Mat {
/**
* Load data from MatLab data file
*
* @param fileName MatLab file name
* @return Data map
*/
public static Map<String, Array> load(String fileName) {
try (Source source = Sources.openFile(fileName)) {
MatFile mat = Mat5.newReader(source).readMat();
Map<String, Array> map = new HashMap<>();
for (MatFile.Entry entry : mat.getEntries()) {
Array array = MatLabUtil.fromMatLabArray((Matrix) entry.getValue());
map.put(entry.getName(), array);
}
return map;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,10 +1,12 @@
package org.meteoinfo.data.meteodata.matlab;
package org.meteoinfo.ndarray.io.matlab;
import com.google.common.base.Charsets;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import org.meteoinfo.ndarray.Index;
import us.hebi.matlab.mat.types.MatlabType;
import us.hebi.matlab.mat.types.Matrix;
import us.hebi.matlab.mat.util.Bytes;
public class MatLabUtil {
@ -67,22 +69,69 @@ public class MatLabUtil {
break;
case LONG:
case ULONG:
for (int i = 0; i < matArray.getNumElements(); i++) {
array.setLong(i, matArray.getLong(i));
for (int i = 0; i < array.getSize(); i++) {
current = index.getCurrentCounter();
for (int j = 0; j < ndim; j++) {
if (current[j] < shape[j] - 1) {
current[j] = current[j] + 1;
break;
} else {
current[j] = 0;
}
}
index.set(current);
array.setLong(index, matArray.getLong(i));
}
break;
case FLOAT:
for (int i = 0; i < matArray.getNumElements(); i++) {
array.setFloat(i, matArray.getFloat(i));
for (int i = 0; i < array.getSize(); i++) {
current = index.getCurrentCounter();
for (int j = 0; j < ndim; j++) {
if (current[j] < shape[j] - 1) {
current[j] = current[j] + 1;
break;
} else {
current[j] = 0;
}
}
index.set(current);
array.setFloat(index, matArray.getFloat(i));
}
break;
case DOUBLE:
for (int i = 0; i < matArray.getNumElements(); i++) {
array.setDouble(i, matArray.getDouble(i));
for (int i = 0; i < array.getSize(); i++) {
current = index.getCurrentCounter();
for (int j = 0; j < ndim; j++) {
if (current[j] < shape[j] - 1) {
current[j] = current[j] + 1;
break;
} else {
current[j] = 0;
}
}
index.set(current);
array.setDouble(index, matArray.getDouble(i));
}
break;
}
return array;
}
public static String parseAsciiString(byte[] buffer) {
return parseAsciiString(buffer, 0, buffer.length);
}
public static String parseAsciiString(byte[] buffer, int offset, int maxLength) {
// Stop at String end character
int length = Bytes.findFirst(buffer, offset, maxLength, (byte) '\0', maxLength);
// Remove right-side trailing spaces
while (length > 0 && buffer[length - 1] == ' ') {
length--;
}
// Convert to String
return length == 0 ? "" : new String(buffer, offset, length, Charsets.US_ASCII);
}
}

View File

@ -34,7 +34,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<revision>3.7.5</revision>
<revision>3.7.6</revision>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.release>8</maven.compiler.release>