Issue #2476 fixed crash, added short[] numpy support, removed gfe wx/discrete string keys hack, cleaned up jep numpy interfaces and code

Former-commit-id: a18df07586 [formerly 554a9cddf3] [formerly f3143ba7b4] [formerly a18df07586 [formerly 554a9cddf3] [formerly f3143ba7b4] [formerly 6880a18f1a [formerly f3143ba7b4 [formerly 0c24c900ce938982306bad9307f3b1ef27b362bb]]]]
Former-commit-id: 6880a18f1a
Former-commit-id: dced4c4d11 [formerly 19043faeaa] [formerly df19f622b8df95f3d1447cd1c6c599d088ba4b1c [formerly f2751f017e]]
Former-commit-id: 15fd50423e5c76bf2d7d7f54653759492ef97c8d [formerly e8c199f108]
Former-commit-id: f2184b9379
This commit is contained in:
Nate Jensen 2013-10-29 09:47:28 -05:00
parent fce988f3a4
commit 89b3b81ab3
30 changed files with 284 additions and 274 deletions

View file

@ -61,10 +61,10 @@ public class InterpolationContainer implements INumpyable {
/*
* (non-Javadoc)
*
* @see jep.INumpyable#getNumPy()
* @see jep.INumpyable#getNumpy()
*/
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
// todo
return new Object[] { xValues, yValues, zValues };
}

View file

@ -49,6 +49,7 @@ import com.raytheon.uf.viz.derivparam.tree.CubeLevel;
* Jul 8, 2008 njensen Initial creation
* Nov 20, 2009 #3387 jelkins Use derived script's variableId instead of filename
* Nov 21, 2009 #3576 rjpeter Refactored to populate DerivParamDesc.
* Oct 29, 2013 2476 njensen Renamed numeric methods to numpy
* </pre>
*
* @author njensen
@ -214,7 +215,7 @@ public class MasterDerivScript extends PythonInterpreter {
argKey += "_"
+ Integer.toHexString((val.hashCode()));
}
// setNumeric won't work with indexed objects
// setNumpy won't work with indexed objects
evaluateArgument(argKey, val);
jep.eval(argName + ".append(" + argKey + ")");
}
@ -231,7 +232,7 @@ public class MasterDerivScript extends PythonInterpreter {
for (int argIdx = 0; argIdx < valList.length; argIdx++) {
IDataRecord val = valList[argIdx];
jep.eval(argName + ".append(None)");
// setNumeric won't work with indexed objects
// setNumpy won't work with indexed objects
evaluateArgument("__tmp", val);
jep.eval(argName + "[" + argIdx + "] = __tmp");
}
@ -241,10 +242,10 @@ public class MasterDerivScript extends PythonInterpreter {
setDataRecordArg(argName, (IDataRecord) argValue);
} else if (argValue instanceof float[]) {
float[] val = (float[]) argValue;
jep.setNumeric(argName, val, val.length, 1);
jep.setNumpy(argName, val, val.length, 1);
} else if (argValue instanceof int[]) {
int[] val = (int[]) argValue;
jep.setNumeric(argName, val, val.length, 1);
jep.setNumpy(argName, val, val.length, 1);
} else if (argValue instanceof Float) {
jep.set(argName, (argValue));
} else if (argValue instanceof DerivedParameterRequest) {
@ -401,7 +402,7 @@ public class MasterDerivScript extends PythonInterpreter {
if (argValue instanceof FloatDataRecord) {
FloatDataRecord record = (FloatDataRecord) argValue;
if (sizes.length == 2) {
jep.setNumeric(argName, record.getFloatData(), (int) sizes[0],
jep.setNumpy(argName, record.getFloatData(), (int) sizes[0],
(int) sizes[1]);
reshape = false;
} else {
@ -415,7 +416,7 @@ public class MasterDerivScript extends PythonInterpreter {
} else if (argValue instanceof IntegerDataRecord) {
IntegerDataRecord record = (IntegerDataRecord) argValue;
if (sizes.length == 2) {
jep.setNumeric(argName, record.getIntData(), (int) sizes[0],
jep.setNumpy(argName, record.getIntData(), (int) sizes[0],
(int) sizes[1]);
reshape = false;
} else {
@ -424,7 +425,7 @@ public class MasterDerivScript extends PythonInterpreter {
} else if (argValue instanceof ByteDataRecord) {
ByteDataRecord record = (ByteDataRecord) argValue;
if (sizes.length == 2) {
jep.setNumeric(argName, record.getByteData(), (int) sizes[0],
jep.setNumpy(argName, record.getByteData(), (int) sizes[0],
(int) sizes[1]);
reshape = false;
} else {

View file

@ -59,7 +59,7 @@ public class CapeFuncPythonAdapter {
}
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { cape, cin };
}

View file

@ -50,6 +50,7 @@
# so mask can be used with advanced indexing
# (e.g. grid[mask] = value)
# Oct 07, 2013 2424 randerso remove use of pytz
# Oct 29, 2013 2476 njensen Improved getting wx/discrete keys in _getGridResults
#
########################################################################
import types, string, time, sys
@ -463,24 +464,31 @@ class SmartScript(BaseTool.BaseTool):
elif "List" == mode:
xlated = []
for rgrid in result:
xlgrid = rgrid.getGridSlice()
xlgrid = xlgrid.__numpy__
jxlgrid = rgrid.getGridSlice()
xlgrid = jxlgrid.__numpy__
if len(xlgrid) == 1:
xlgrid = xlgrid[0];
elif len(xlgrid) == 2 and isinstance(xlgrid[1], str):
xlgrid[1] = eval(xlgrid[1])
if xlgrid[0].dtype != numpy.int8:
# scalar
xlgrid = xlgrid[0]
else:
# discrete or weather
keys = JUtil.javaObjToPyVal(jxlgrid.getKeyList())
xlgrid.append(keys)
xlated.append(xlgrid)
retVal = xlated
else:
result = result[0];
result = result.getGridSlice()
result = result.__numpy__
slice = result.getGridSlice()
result = slice.__numpy__
if len(result) == 1:
retVal = result[0]
elif len(result) == 2 and isinstance(result[1], str):
retVal = (result[0], eval(result[1]))
if result[0].dtype != numpy.int8:
# scalar
result = result[0]
else:
retVal = (result[0], result[1])
# discrete or weather
keys = JUtil.javaObjToPyVal(slice.getKeyList())
result.append(keys)
retVal = result
if retVal is None or retVal == []:
if noDataError == 1:

View file

@ -17,12 +17,14 @@
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
# further licensing information.
##
import DatabaseID, AbsTime
import DatabaseID, AbsTime, JUtil
from com.raytheon.uf.common.dataplugin.gfe.db.objects import DatabaseID as JavaDatabaseID
from com.raytheon.uf.common.dataplugin.gfe.reference import ReferenceID
from com.raytheon.uf.common.dataplugin.gfe.db.objects import ParmID
from numpy import int8
class DBSSWE:
def __init__(self, parm):
self._parm = parm
@ -48,11 +50,16 @@ class DBSSWE:
if t == key:
#return g.pyData()
g.populate()
result = g.getGridSlice().__numpy__
slice = g.getGridSlice()
result = slice.__numpy__
if len(result) == 1:
if result[0].dtype != int8:
# scalar
result = result[0]
elif len(result) == 2 and isinstance(result[1], str):
result[1] = eval(result[1])
else:
# discrete or weather
dkeys = JUtil.javaObjToPyVal(slice.getKeyList())
result.append(dkeys)
return result
return None

View file

@ -840,7 +840,7 @@ public class DiscreteGridData extends AbstractGridData implements INumpyable {
}
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { this.getGrid().getBuffer().array() };
}

View file

@ -817,7 +817,7 @@ public class WeatherGridData extends AbstractGridData implements INumpyable {
}
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { this.getGrid().getBuffer().array() };
}

View file

@ -48,6 +48,7 @@ import com.raytheon.viz.gfe.core.griddata.WeatherGridData;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 12, 2012 dgilling Initial creation
* Oct 29, 2013 2476 njensen Renamed numeric methods to numpy
*
* </pre>
*
@ -117,7 +118,7 @@ public class CalcVcModGridArg implements IVcModuleArgument {
ScalarGridData grid = (ScalarGridData) gd;
Grid2DFloat f = (grid.getScalarSlice()).getScalarGrid();
String name = prefix + "grid";
jep.setNumeric(name, f.getFloats(), f.getXdim(), f.getYdim());
jep.setNumpy(name, f.getFloats(), f.getXdim(), f.getYdim());
jepString.append(name);
jepString.append(", ");
tempGridNames.add(name);
@ -127,9 +128,9 @@ public class CalcVcModGridArg implements IVcModuleArgument {
Grid2DFloat dir = (grid.getVectorSlice()).getDirGrid();
String magName = prefix + "Mag";
String dirName = prefix + "Dir";
jep.setNumeric(magName, mag.getFloats(), mag.getXdim(),
jep.setNumpy(magName, mag.getFloats(), mag.getXdim(),
mag.getYdim());
jep.setNumeric(dirName, dir.getFloats(), dir.getXdim(),
jep.setNumpy(dirName, dir.getFloats(), dir.getXdim(),
dir.getYdim());
jepString.append('(');
jepString.append(magName);
@ -142,7 +143,7 @@ public class CalcVcModGridArg implements IVcModuleArgument {
WeatherGridData grid = (WeatherGridData) gd;
Grid2DByte bytes = grid.getWeatherSlice().getWeatherGrid();
String name = prefix + "grid";
jep.setNumeric(name, bytes.getBytes(), bytes.getXdim(),
jep.setNumpy(name, bytes.getBytes(), bytes.getXdim(),
bytes.getYdim());
jepString.append('(');
jepString.append(name);
@ -159,7 +160,7 @@ public class CalcVcModGridArg implements IVcModuleArgument {
DiscreteGridData grid = (DiscreteGridData) gd;
Grid2DByte bytes = grid.getDiscreteSlice().getDiscreteGrid();
String name = prefix + "grid";
jep.setNumeric(name, bytes.getBytes(), bytes.getXdim(),
jep.setNumpy(name, bytes.getBytes(), bytes.getXdim(),
bytes.getYdim());
jepString.append('(');
jepString.append(name);
@ -175,7 +176,7 @@ public class CalcVcModGridArg implements IVcModuleArgument {
}
String maskName = prefix + "mask";
jep.setNumeric(maskName, mask.getBytes(), mask.getXdim(),
jep.setNumpy(maskName, mask.getBytes(), mask.getXdim(),
mask.getYdim());
jepString.append(maskName);
sb.append(jepString);

View file

@ -69,6 +69,7 @@ import com.raytheon.viz.gfe.core.wxvalue.WxValue;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 20, 2008 njensen Initial creation
* Oct 29, 2013 2476 njensen Renamed numeric methods to numpy
* </pre>
*
* @author njensen
@ -178,7 +179,7 @@ public class SmartToolController extends BaseGfePyController {
if (parmToEdit == null) {
return null;
} else {
return getNumericResult(parmToEdit.getGridInfo().getGridType());
return getNumpyResult(parmToEdit.getGridInfo().getGridType());
}
}
@ -246,7 +247,7 @@ public class SmartToolController extends BaseGfePyController {
* @return the result of the execution in Java format
* @throws JepException
*/
protected Object getNumericResult(GridType type) throws JepException {
protected Object getNumpyResult(GridType type) throws JepException {
Object result = null;
boolean resultFound = (Boolean) jep.getValue(RESULT + " is not None");
@ -308,9 +309,9 @@ public class SmartToolController extends BaseGfePyController {
Grid2DFloat dir = (grid.getVectorSlice()).getDirGrid();
String magName = argName + "Mag";
String dirName = argName + "Dir";
jep.setNumeric(magName, mag.getFloats(), mag.getXdim(),
jep.setNumpy(magName, mag.getFloats(), mag.getXdim(),
mag.getYdim());
jep.setNumeric(dirName, dir.getFloats(), dir.getXdim(),
jep.setNumpy(dirName, dir.getFloats(), dir.getXdim(),
dir.getYdim());
jep.eval(argName + " = [" + magName + ", " + dirName + "]");
jep.eval(magName + " = None");
@ -318,7 +319,7 @@ public class SmartToolController extends BaseGfePyController {
} else if (argValue instanceof ScalarGridData) {
ScalarGridData grid = (ScalarGridData) argValue;
Grid2DFloat f = (grid.getScalarSlice()).getScalarGrid();
jep.setNumeric(argName, f.getFloats(), f.getXdim(), f.getYdim());
jep.setNumpy(argName, f.getFloats(), f.getXdim(), f.getYdim());
} else if (argValue instanceof DiscreteGridData) {
DiscreteGridData grid = (DiscreteGridData) argValue;
jep.set("discreteGridData", grid);

Binary file not shown.

View file

@ -1,77 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.gfe.smartinit;
import jep.INumpyable;
/**
* TODO Add Description
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 1, 2008 njensen Initial creation
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class FakeTopo implements INumpyable {
// TODO need real topo databases!
private static final int x = 145;
private static final int y = 145;
/*
* (non-Javadoc)
*
* @see jep.INumpyable#getNumPy()
*/
@Override
public Object[] getNumPy() {
return new Object[] { new float[x * y] };
}
/*
* (non-Javadoc)
*
* @see jep.INumpyable#getNumpyX()
*/
@Override
public int getNumpyX() {
return x;
}
/*
* (non-Javadoc)
*
* @see jep.INumpyable#getNumpyY()
*/
@Override
public int getNumpyY() {
return y;
}
}

View file

@ -28,6 +28,7 @@
# 04/04/13 #1787 randerso fix validTime check to work with accumulative parms
# fix logging so you can actually determine why
# a smartInit is not calculating a parameter
# Oct 29, 2013 2476 njensen Improved getting wx/discrete keys when retrieving data
#
##
import string, sys, re, time, types, getopt, fnmatch, LogStream, DatabaseID, JUtil, AbsTime, TimeRange
@ -967,12 +968,16 @@ class Forecaster(GridUtilities):
pytr = TimeRange.encodeJavaTimeRange(tr)
pkeys = TimeRange.javaTimeRangeListToPyList(p.getKeys())
if pytr in pkeys:
slice = p.getItem(tr)
slice = slice.__numpy__
jslice = p.getItem(tr)
slice = jslice.__numpy__
if len(slice) == 1:
if slice[0].dtype != int8:
# scalar
slice = slice[0]
elif len(slice) == 2 and type(slice[1]) is str:
exec "slice[1] = " + slice[1]
else:
# discrete or weather
keys = JUtil.javaObjToPyVal(jslice.getKeyList())
slice.append(keys)
cache[arg] = (slice, pytr)
else:
cache[arg] = (None, time)
@ -1048,11 +1053,16 @@ class Forecaster(GridUtilities):
if type(rval) is not ndarray:
if type(rval) is not tuple:
jrval = rval
rval = rval.__numpy__
if len(rval) == 1:
if rval[0].dtype != int8:
# scalar
rval = rval[0]
elif len(rval) == 2 and type(rval[1]) is str:
exec "rval[1] = " + rval[1]
else:
# discrete or weather
keys = JUtil.javaObjToPyVal(jrval.getKeyList())
rval.append(keys)
cache[we] = (rval, time)
if rval is not None and cache['mtime'][0] is not None and doStore:
parm = self.__getNewWE(we)
@ -1211,9 +1221,13 @@ class IFPIO:
slice = self.getSrcWE(name, 0).getItem(time)
out = slice.__numpy__
if len(out) == 1:
if out[0].dtype != int8:
# scalar
out = out[0]
elif len(out) == 2 and type(out[1]) is str:
exec "out[1] = " + out[1]
else:
# discrete or weather
keys = JUtil.javaObjToPyVal(slice.getKeyList())
out.append(keys)
else:
out = self._getcube(self.eta, name, time)
return out
@ -1239,12 +1253,16 @@ class IFPIO:
pres = []
for l in lvls:
p = self.getSrcWE(parm + "_" + l, 0)
slice = p.getItem(time)
slice = slice.__numpy__
jslice = p.getItem(time)
slice = jslice.__numpy__
if len(slice) == 1:
if slice[0].dtype != int8:
# scalar
slice = slice[0]
elif len(slice) == 2 and type(slice[1]) is str:
exec "slice[1] = " + slice[1]
else:
# discrete or weather
keys = JUtil.javaObjToPyVal(jslice.getKeyList())
slice.append(keys)
lst.append(slice)
pres.append(int(l[2:]))
if type(lst[0]) == types.TupleType or type(lst[0]) == types.ListType:

View file

@ -131,7 +131,7 @@ public class GridLocation extends PersistableDataObject<String> implements
}
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { data };
}
@ -1048,7 +1048,7 @@ public class GridLocation extends PersistableDataObject<String> implements
System.out.println(gridCoord.x + "," + gridCoord.y + " " + latLon);
PythonNumpyLatLonGrid latLonGrid = gloc.getLatLonGrid();
float[] data = (float[]) latLonGrid.getNumPy()[0];
float[] data = (float[]) latLonGrid.getNumpy()[0];
for (int x = 0; x < gloc.getNx(); x++) {
for (int y = 0; y < gloc.getNy(); y++) {
int idx = 2 * ((x * gloc.ny) + y);

View file

@ -408,7 +408,7 @@ public class Grid2DBoolean implements IGrid2D, Cloneable, INumpyable,
}
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { buffer.array() };
}

View file

@ -414,7 +414,7 @@ public class Grid2DByte implements IGrid2D, Cloneable, INumpyable,
}
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { buffer.array() };
}

View file

@ -425,7 +425,7 @@ public class Grid2DFloat implements IGrid2D, Cloneable, INumpyable,
}
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { buffer.array() };
}

View file

@ -36,7 +36,6 @@ import com.raytheon.uf.common.dataplugin.gfe.discrete.DiscreteKey;
import com.raytheon.uf.common.dataplugin.gfe.grid.Grid2DBit;
import com.raytheon.uf.common.dataplugin.gfe.grid.Grid2DByte;
import com.raytheon.uf.common.dataplugin.gfe.grid.IGrid2D;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.common.status.IUFStatusHandler;
@ -58,6 +57,7 @@ import com.raytheon.uf.common.time.TimeRange;
* string
* 08/13/2013 1571 randerso Removed toString to stop it from hanging the
* debugger when trying to display the grid
* 10/29/2013 2476 njensen Updated getNumpy() and added getKeyList()
* </pre>
*
* @author chammack
@ -789,16 +789,8 @@ public class DiscreteGridSlice extends AbstractGridSlice implements Cloneable {
}
@Override
public Object[] getNumPy() {
Object[] numpy = new Object[2];
numpy[0] = getDiscreteGrid().getBuffer().array();
List<String> keyList = new ArrayList<String>();
for (DiscreteKey k : key) {
keyList.add(k.toString());
}
String pyList = PyUtil.listToList(keyList);
numpy[1] = pyList;
return numpy;
public Object[] getNumpy() {
return new Object[] { getDiscreteGrid().getBuffer().array() };
}
@Override
@ -860,4 +852,12 @@ public class DiscreteGridSlice extends AbstractGridSlice implements Cloneable {
diskCache.removeFromCache(cacheId);
}
}
public List<String> getKeyList() {
List<String> list = new ArrayList<String>(key.length);
for (DiscreteKey k : key) {
list.add(k.toString());
}
return list;
}
}

View file

@ -72,10 +72,10 @@ public class PythonWeatherGridSlice extends AbstractGridSlice {
/*
* (non-Javadoc)
*
* @see jep.INumpyable#getNumPy()
* @see jep.INumpyable#getNumpy()
*/
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
Object[] numpy = new Object[2];
numpy[0] = weatherGrid.getBuffer().array();
String pyList = PyUtil.listToList(keys);

View file

@ -937,7 +937,7 @@ public class ScalarGridSlice extends AbstractGridSlice implements
}
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { this.getScalarGrid().getFloats() };
}

View file

@ -1225,7 +1225,7 @@ public class VectorGridSlice extends ScalarGridSlice implements Cloneable,
}
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { this.getMagGrid().getFloats(),
this.getDirGrid().getFloats() };
}

View file

@ -35,7 +35,6 @@ import com.raytheon.uf.common.dataplugin.gfe.grid.Grid2DByte;
import com.raytheon.uf.common.dataplugin.gfe.grid.IGrid2D;
import com.raytheon.uf.common.dataplugin.gfe.weather.WeatherKey;
import com.raytheon.uf.common.dataplugin.gfe.weather.WeatherSubKey;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.common.status.IUFStatusHandler;
@ -56,6 +55,7 @@ import com.raytheon.uf.common.time.TimeRange;
* Jan 30, 2013 15719 jdynina Allowed more than 128 char wx string
* Aug 13, 2013 1571 randerso Removed toString to stop it from hanging the
* debugger when trying to display the grid
* Oct 29, 2013 2476 njensen Updated getNumpy() and added getKeyList()
*
* </pre>
*
@ -814,16 +814,8 @@ public class WeatherGridSlice extends AbstractGridSlice {
}
@Override
public Object[] getNumPy() {
Object[] numpy = new Object[2];
numpy[0] = getWeatherGrid().getBuffer().array();
List<String> keyList = new ArrayList<String>();
for (WeatherKey k : keys) {
keyList.add(k.toString());
}
String pyList = PyUtil.listToList(keyList);
numpy[1] = pyList;
return numpy;
public Object[] getNumpy() {
return new Object[] { getWeatherGrid().getBuffer().array() };
}
@Override
@ -884,4 +876,12 @@ public class WeatherGridSlice extends AbstractGridSlice {
diskCache.removeFromCache(cacheId);
}
}
public List<String> getKeyList() {
List<String> list = new ArrayList<String>(keys.length);
for (WeatherKey k : keys) {
list.add(k.toString());
}
return list;
}
}

View file

@ -52,10 +52,10 @@ public class PythonNumpyFloatArray implements INumpyable {
/*
* (non-Javadoc)
*
* @see jep.INumpyable#getNumPy()
* @see jep.INumpyable#getNumpy()
*/
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { messageData };
}

View file

@ -46,10 +46,10 @@ public class PythonNumpyByteArray implements INumpyable {
/*
* (non-Javadoc)
*
* @see jep.INumpyable#getNumPy()
* @see jep.INumpyable#getNumpy()
*/
@Override
public Object[] getNumPy() {
public Object[] getNumpy() {
return new Object[] { messageData };
}

View file

@ -20,7 +20,8 @@
package jep;
/**
* TODO Add Description
* Interface representing a Java object that can be transformed into a numpy
* array.
*
* <pre>
* SOFTWARE HISTORY
@ -39,14 +40,21 @@ public interface INumpyable {
/**
* Gets an Object[] representation of the object to transform into numpy.
* Each index in the Object[] should be another array of the primitive type,
* e.g. {float[], float[]}
* e.g. {float[], float[]}. The result in python will then be a python
* list, e.g. [numpy.ndarray(dtype=float32), numpy.ndarray(dtype=float32)].
*
* @return
*/
public Object[] getNumPy();
public Object[] getNumpy();
/**
* Gets the x dimension of the arrays returned by getNumpy().
*/
public int getNumpyX();
/**
* Gets the y dimension of hte arrays returned by getNumpy().
*/
public int getNumpyY();
}

View file

@ -821,7 +821,7 @@ public final class Jep {
throws JepException;
// added by njensen
public void setNumeric(String name, float[] v, int nx, int ny) throws JepException {
public void setNumpy(String name, float[] v, int nx, int ny) throws JepException {
if(this.closed)
throw new JepException("Jep has been closed.");
isValidThread();
@ -832,7 +832,7 @@ public final class Jep {
private native void setNumeric(long tstate, String name, float[] v, int nx, int ny)
throws JepException;
// end of added by njensen
public void setNumeric(String name, int[] v, int nx, int ny) throws JepException {
public void setNumpy(String name, int[] v, int nx, int ny) throws JepException {
if(this.closed)
throw new JepException("Jep has been closed.");
isValidThread();
@ -843,7 +843,7 @@ public final class Jep {
private native void setNumeric(long tstate, String name, int[] v, int nx, int ny)
throws JepException;
public void setNumeric(String name, byte[] v, int nx, int ny) throws JepException {
public void setNumpy(String name, byte[] v, int nx, int ny) throws JepException {
if(this.closed)
throw new JepException("Jep has been closed.");
isValidThread();

View file

@ -86,17 +86,11 @@ static jmethodID objectGetClass = 0;
static jmethodID classGetMethods = 0;
static jmethodID classGetFields = 0;
// all following static variables added by njensen
static jmethodID xMethod = 0;
static jmethodID yMethod = 0;
static jmethodID getMethod = 0;
static jmethodID getNumpyMethod = 0;
// added by njensen
static jclass floatarrayclass = NULL;
static jclass bytearrayclass = NULL;
static jclass intarrayclass = NULL;
static jclass stringclass = NULL;
// added by njensen
static jmethodID classGetName = 0;
static PyObject* classnamePyJMethodsDict = NULL;
@ -742,10 +736,6 @@ static PyObject* pyjobject_numpy(PyJobject_Object *obj) {
int i=0;
/* updated by bkowal */
npy_intp *dims = NULL;
jfloat *dataFloat = NULL;
jbyte *dataByte = NULL;
jint *dataInt = NULL;
const char *message = NULL;
jobjectArray objarray = NULL;
PyObject *resultList = NULL;
jint xsize = 0;
@ -753,12 +743,15 @@ static PyObject* pyjobject_numpy(PyJobject_Object *obj) {
jsize listSize =0;
JNIEnv *env = pyembed_get_env();
// methods are forever but classes are fleeting
jclass numpyable = (*env)->FindClass(env, "jep/INumpyable");
if((*env)->IsInstanceOf(env, obj->object, numpyable))
{
if(xMethod == NULL)
xMethod = (*env)->GetMethodID(env, numpyable, "getNumpyX", "()I");
xsize = (jint) (*env)->CallIntMethod(env, obj->object, xMethod);
if(yMethod == NULL)
yMethod = (*env)->GetMethodID(env, numpyable, "getNumpyY", "()I");
ysize = (jint) (*env)->CallIntMethod(env, obj->object, yMethod);
@ -766,8 +759,9 @@ static PyObject* pyjobject_numpy(PyJobject_Object *obj) {
dims[0] = ysize;
dims[1] = xsize;
getMethod = (*env)->GetMethodID(env, numpyable, "getNumPy", "()[Ljava/lang/Object;");
objarray = (jobjectArray) (*env)->CallObjectMethod(env, obj->object, getMethod);
if(getNumpyMethod == NULL)
getNumpyMethod = (*env)->GetMethodID(env, numpyable, "getNumpy", "()[Ljava/lang/Object;");
objarray = (jobjectArray) (*env)->CallObjectMethod(env, obj->object, getNumpyMethod);
if(process_java_exception(env) || !objarray)
{
Py_INCREF(Py_None);
@ -775,58 +769,18 @@ static PyObject* pyjobject_numpy(PyJobject_Object *obj) {
}
listSize = (*env)->GetArrayLength(env, objarray);
initNumpy();
resultList = PyList_New(listSize);
if(floatarrayclass == NULL)
floatarrayclass = (*env)->FindClass(env, "[F");
if(bytearrayclass == NULL)
bytearrayclass = (*env)->FindClass(env, "[B");
if(intarrayclass == NULL)
intarrayclass = (*env)->FindClass(env, "[I");
if(stringclass == NULL)
stringclass = (*env)->FindClass(env, "java/lang/String");
for(i=0; i < listSize; i=i+1)
{
PyObject *pyjob;
PyObject *pyjob = NULL;
jobject jo = (*env)->GetObjectArrayElement(env, objarray, i);
if((*env)->IsInstanceOf(env, jo, floatarrayclass))
pyjob = javaToNumpyArray(env, jo, dims);
if(pyjob == NULL)
{
pyjob = PyArray_SimpleNew(2, dims, NPY_FLOAT32);
dataFloat = (*env)->GetFloatArrayElements(env, jo, 0);
memcpy(((PyArrayObject *)pyjob)->data,
dataFloat, ysize * xsize * sizeof(float));
(*env)->ReleaseFloatArrayElements(env, jo, dataFloat, 0);
}
else if((*env)->IsInstanceOf(env, jo, bytearrayclass))
{
pyjob = PyArray_SimpleNew(2, dims, NPY_BYTE);
dataByte = (*env)->GetByteArrayElements(env, jo, 0);
memcpy(((PyArrayObject *)pyjob)->data,
dataByte, ysize * xsize * 1);
(*env)->ReleaseByteArrayElements(env, jo, dataByte, 0);
}
else if((*env)->IsInstanceOf(env, jo, intarrayclass))
{
pyjob = PyArray_SimpleNew(2, dims, NPY_INT32);
dataInt = (*env)->GetIntArrayElements(env, jo, 0);
memcpy(((PyArrayObject *)pyjob)->data,
dataInt, ysize * xsize * sizeof(int));
(*env)->ReleaseIntArrayElements(env, jo, dataInt, 0);
}
else if((*env)->IsInstanceOf(env, jo, stringclass))
{
message = jstring2char(env, jo);
pyjob = PyString_FromString(message);
release_utf_char(env, jo, message);
}
else
{
Py_INCREF(Py_None);
pyjob = Py_None;
PyErr_Format(PyExc_TypeError, "Cannot transform INumpyable.getNumpy()[%i] java object to numpy array", i);
free(dims);
Py_DECREF(resultList);
return NULL;
}
PyList_SetItem(resultList, i, pyjob);
(*env)->DeleteLocalRef(env, jo);
@ -837,20 +791,11 @@ static PyObject* pyjobject_numpy(PyJobject_Object *obj) {
}
else
{
Py_INCREF(Py_None);
return Py_None;
PyErr_Format(PyExc_TypeError, "Object does not implement INumpyable and therefore cannot be transformed to numpy array");
return NULL;
}
}
// added by njensen
static void initNumpy(void)
{
if (!numpyInit)
{
import_array();
numpyInit = 1;
}
}
// set attribute v for object.
// uses obj->attr dictionary for storage.

View file

@ -69,7 +69,6 @@ int pyjobject_check(PyObject *obj);
//added by njensen
static PyObject* pyjobject_numpy(PyJobject_Object *obj);
static void initNumpy(void);
static int numpyInit = 0;
#endif // ndef pyjobject

View file

@ -95,6 +95,7 @@ jclass JBOOLEAN_ARRAY_TYPE = NULL;
jclass JDOUBLE_ARRAY_TYPE = NULL;
jclass JFLOAT_ARRAY_TYPE = NULL;
jclass JBYTE_ARRAY_TYPE = NULL;
jclass JSHORT_ARRAY_TYPE = NULL;
// cached methodids
jmethodID objectToString = 0;
@ -905,6 +906,15 @@ int cache_primitive_classes(JNIEnv *env) {
(*env)->DeleteLocalRef(env, clazz);
}
if(JSHORT_ARRAY_TYPE == NULL) {
clazz = (*env)->FindClass(env, "[S");
if((*env)->ExceptionOccurred(env))
return 0;
JSHORT_ARRAY_TYPE = (*env)->NewGlobalRef(env, clazz);
(*env)->DeleteLocalRef(env, clazz);
}
return 1;
}
@ -985,6 +995,11 @@ void unref_cache_primitive_classes(JNIEnv *env) {
(*env)->DeleteGlobalRef(env, JDOUBLE_ARRAY_TYPE);
JDOUBLE_ARRAY_TYPE = NULL;
}
if(JSHORT_ARRAY_TYPE != NULL) {
(*env)->DeleteGlobalRef(env, JSHORT_ARRAY_TYPE);
JSHORT_ARRAY_TYPE = NULL;
}
}
@ -1402,7 +1417,7 @@ jvalue convert_pynumpyarg_jvalue(JNIEnv *env,
arr = NULL;
if(param != Py_None && !pyjarray_check(param)) {
initUtil();
initNumpy();
if(PyArray_Check(param))
{
@ -1580,7 +1595,7 @@ jvalue convert_pyarg_jvalue(JNIEnv *env,
}
else {
//added by njensen
initUtil();
initNumpy();
if(PyArray_Check(param))
{
ret.l = numpyToJavaArray(env, param, NULL);
@ -1723,7 +1738,7 @@ jarray numpyToJavaArray(JNIEnv* env, PyObject *param, jclass desiredType)
PyArrayObject *pa = NULL;
int minDim = 0;
int maxDim = 0;
initUtil();
initNumpy();
sz = PyArray_Size(param);
if(desiredType == NULL)
@ -1732,6 +1747,8 @@ jarray numpyToJavaArray(JNIEnv* env, PyObject *param, jclass desiredType)
desiredType = JBOOLEAN_ARRAY_TYPE;
else if(((PyArrayObject *) param)->descr->type_num == NPY_BYTE)
desiredType = JBYTE_ARRAY_TYPE;
else if(((PyArrayObject *) param)->descr->type_num == NPY_INT16)
desiredType = JSHORT_ARRAY_TYPE;
else if(((PyArrayObject *) param)->descr->type_num == NPY_INT32)
desiredType = JINT_ARRAY_TYPE;
else if(((PyArrayObject *) param)->descr->type_num == NPY_INT64)
@ -1762,6 +1779,15 @@ jarray numpyToJavaArray(JNIEnv* env, PyObject *param, jclass desiredType)
pa = (PyArrayObject *) nvalue;
(*env)->SetByteArrayRegion(env, arr, 0, sz, (const jbyte *)pa->data);
}
else if((*env)->IsSameObject(env, desiredType, JSHORT_ARRAY_TYPE)
&& (((PyArrayObject *) param)->descr->type_num == NPY_INT16))
{
arr = (*env)->NewShortArray(env, sz);
nobj = PyArray_ContiguousFromObject(param, NPY_INT16, minDim, maxDim);
nvalue = (PyObject *)PyArray_Cast((PyArrayObject *)nobj, NPY_INT16);
pa = (PyArrayObject *) nvalue;
(*env)->SetShortArrayRegion(env, arr, 0, sz, (const jshort *)pa->data);
}
else if((*env)->IsSameObject(env, desiredType, JINT_ARRAY_TYPE)
&& (((PyArrayObject *) param)->descr->type_num == NPY_INT32))
{
@ -1808,6 +1834,75 @@ jarray numpyToJavaArray(JNIEnv* env, PyObject *param, jclass desiredType)
return arr;
}
// added by njensen
PyObject* javaToNumpyArray(JNIEnv* env, jobject jo, npy_intp *dims)
{
PyObject *pyjob = NULL;
int ysize, xsize;
ysize = dims[0];
xsize = dims[1];
initNumpy();
if((*env)->IsInstanceOf(env, jo, JBOOLEAN_ARRAY_TYPE))
{
jboolean *dataBool = NULL;
pyjob = PyArray_SimpleNew(2, dims, NPY_BOOL);
dataBool = (*env)->GetBooleanArrayElements(env, jo, 0);
memcpy(((PyArrayObject *)pyjob)->data, dataBool, ysize * xsize * 1);
(*env)->ReleaseBooleanArrayElements(env, jo, dataBool, 0);
}
else if((*env)->IsInstanceOf(env, jo, JBYTE_ARRAY_TYPE))
{
jbyte *dataByte = NULL;
pyjob = PyArray_SimpleNew(2, dims, NPY_BYTE);
dataByte = (*env)->GetByteArrayElements(env, jo, 0);
memcpy(((PyArrayObject *)pyjob)->data, dataByte, ysize * xsize * 1);
(*env)->ReleaseByteArrayElements(env, jo, dataByte, 0);
}
else if((*env)->IsInstanceOf(env, jo, JSHORT_ARRAY_TYPE))
{
jshort *dataShort = NULL;
pyjob = PyArray_SimpleNew(2, dims, NPY_INT16);
dataShort = (*env)->GetShortArrayElements(env, jo, 0);
memcpy(((PyArrayObject *)pyjob)->data, dataShort, ysize * xsize * 2);
(*env)->ReleaseShortArrayElements(env, jo, dataShort, 0);
}
else if((*env)->IsInstanceOf(env, jo, JINT_ARRAY_TYPE))
{
jint *dataInt = NULL;
pyjob = PyArray_SimpleNew(2, dims, NPY_INT32);
dataInt = (*env)->GetIntArrayElements(env, jo, 0);
memcpy(((PyArrayObject *)pyjob)->data, dataInt, ysize * xsize * 4);
(*env)->ReleaseIntArrayElements(env, jo, dataInt, 0);
}
else if((*env)->IsInstanceOf(env, jo, JLONG_ARRAY_TYPE))
{
jlong *dataLong = NULL;
pyjob = PyArray_SimpleNew(2, dims, NPY_INT64);
dataLong = (*env)->GetLongArrayElements(env, jo, 0);
memcpy(((PyArrayObject *)pyjob)->data, dataLong, ysize * xsize * 8);
(*env)->ReleaseLongArrayElements(env, jo, dataLong, 0);
}
else if((*env)->IsInstanceOf(env, jo, JFLOAT_ARRAY_TYPE))
{
jfloat *dataFloat = NULL;
pyjob = PyArray_SimpleNew(2, dims, NPY_FLOAT32);
dataFloat = (*env)->GetFloatArrayElements(env, jo, 0);
memcpy(((PyArrayObject *)pyjob)->data, dataFloat, ysize * xsize * 4);
(*env)->ReleaseFloatArrayElements(env, jo, dataFloat, 0);
}
else if((*env)->IsInstanceOf(env, jo, JDOUBLE_ARRAY_TYPE))
{
jdouble *dataDouble = NULL;
pyjob = PyArray_SimpleNew(2, dims, NPY_FLOAT64);
dataDouble = (*env)->GetDoubleArrayElements(env, jo, 0);
memcpy(((PyArrayObject *)pyjob)->data, dataDouble, ysize * xsize * 8);
(*env)->ReleaseDoubleArrayElements(env, jo, dataDouble, 0);
}
return pyjob;
}
// added by njensen, code from brockwoo
jarray pylistToJStringList(JNIEnv* env, PyObject* plist)
{
@ -1827,12 +1922,12 @@ jarray pylistToJStringList(JNIEnv* env, PyObject* plist)
}
// added by njensen
static void initUtil(void)
static void initNumpy(void)
{
if (!utilInit)
if (!numpyInited)
{
import_array();
utilInit = 1;
numpyInited = 1;
}
}

View file

@ -37,6 +37,9 @@
#endif
#include <Python.h>
// added by njensen
#include "numpy/arrayobject.h"
#ifndef _Included_util
#define _Included_util
@ -106,11 +109,12 @@ int process_py_exception(JNIEnv*, int);
// added by njensen
char *PyTraceback_AsString(PyObject*);
static void initUtil(void);
static int utilInit = 0;
static void initNumpy(void);
static int numpyInited = 0;
jstring javaStacktrace_tostring(JNIEnv*, jthrowable);
jarray numpyToJavaArray(JNIEnv*, PyObject*, jclass);
jarray pylistToJStringList(JNIEnv*, PyObject*);
PyObject* javaToNumpyArray(JNIEnv*, jobject, npy_intp*);
// convert java exception to pyerr.
// true (1) if an exception was processed.

View file

@ -202,8 +202,8 @@ public class TestContourAnalyzer {
String label) {
assertEquals(label + ":getXdim()", expected.getXdim(), result.getXdim());
assertEquals(label + ":getYdim()", expected.getYdim(), result.getYdim());
assertArrayEquals(label + ":values", expected.getNumPy(),
result.getNumPy());
assertArrayEquals(label + ":values", expected.getNumpy(),
result.getNumpy());
}
/**