Issue #1497 ported python fillEditArea to Java to boost speed

Change-Id: Idbc2a027914e1a584d36551781df21ed9bf63c36

Former-commit-id: 32cf1236638c64a3e047398ca829d79d3b7cb5ef
This commit is contained in:
Nate Jensen 2013-01-17 08:58:35 -06:00 committed by Gerrit Code Review
parent 037dabb683
commit 15e1731ef3
2 changed files with 190 additions and 0 deletions

View file

@ -0,0 +1,80 @@
##
# 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.
##
#
# Provides Java implementations of common smart utility functions
# to boost performance.
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 01/14/13 njensen Initial Creation.
#
#
#
import jep
from com.raytheon.uf.common.dataplugin.gfe.util import SmartUtils as JavaSmartUtils
import numpy
def __getMaskIndiciesForJava(mask):
flatMask = mask.flat #flatten the array
flatIndicies = numpy.nonzero(flatMask) # get the indicies of the set cells
ysize = mask.shape[1]
indexes = []
# convert the flat incicies to the x, y indicies
for i in flatIndicies:
indexes.append((i / ysize, i % ysize))
# Make two new jarrays to hold the final coordinate tuples
size = len(indexes[0][0])
xcoords = jep.jarray(size, jep.JINT_ID)
ycoords = jep.jarray(size, jep.JINT_ID)
#===================================================================
# Convert the coordinates from a tuple of numpy arrays to a list of
# coordinate tuples
for index in xrange(size):
try:
x = indexes[0][0][index]
y = indexes[0][1][index]
xcoords[index] = int(x)
ycoords[index] = int(y)
except Exception, e:
print e
return xcoords, ycoords
def fillEditArea(grid, fillMask, borderMask):
editPointsX, editPointsY = __getMaskIndiciesForJava(fillMask)
borderPointsX, borderPointsY = __getMaskIndiciesForJava(borderMask)
gridObj = JavaSmartUtils.fillEditArea(grid, grid.shape[1], grid.shape[0], \
editPointsY, editPointsX, borderPointsY, borderPointsX)
retObj = gridObj.__numpy__[0]
return retObj

View file

@ -0,0 +1,110 @@
/**
* 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.uf.common.dataplugin.gfe.util;
import jep.INumpyable;
import com.raytheon.uf.common.python.PythonNumpyFloatArray;
/**
* Java port of python utility functions. Ported to Java to boost performance to
* surpass python's poor looping performance.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 11, 2013 njensen Initial creation
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class SmartUtils {
/**
* Define a method to fill the specified edit area. Ported from python.
*
* @param grid
* @param gridNx
* @param gridNy
* @param editPointsX
* @param editPointsY
* @param borderPointsX
* @param borderPointsY
* @return
*/
public static INumpyable fillEditArea(float[] grid, int gridNx, int gridNy,
int[] editPointsX, int[] editPointsY, int[] borderPointsX,
int[] borderPointsY) {
// edit points and border points are a list of (x,y) indices
int[] e = new int[2];
int[] b = new int[2];
for (int i = 0; i < editPointsX.length; i++) {
e[0] = editPointsX[i];
e[1] = editPointsY[i];
double numSum = 0.0;
double denomSum = 0.0;
for (int k = 0; k < borderPointsX.length; k++) {
b[0] = borderPointsX[k];
b[1] = borderPointsY[k];
// points in the same row, column or diagonal
int xdiff = e[0] - b[0];
int ydiff = e[1] - b[1];
int absXdiff = (xdiff < 0) ? -xdiff : xdiff;
int absYdiff = (ydiff < 0) ? -ydiff : ydiff;
if (e[0] == b[0] || e[1] == b[1] || absXdiff == absYdiff) {
double xdist = xdiff;
double ydist = ydiff;
// calculate the distance to the border point
double dist = Math.sqrt(xdist * xdist + ydist * ydist);
// value = grid[b[0], b[1]]
float value = grid[b[0] + (gridNx * b[1])];
// Accumulate the distance-weighted average
numSum = numSum + value / dist;
denomSum = denomSum + 1 / dist;
}
}
int eIndex = e[0] + (gridNx * e[1]);
if (denomSum > 0.0f) {
// grid[e[0], e[1]] = numSum / denomSum;
grid[eIndex] = (float) (numSum / denomSum);
} else {
// grid[e[0], e[1]] = 0.0;
grid[eIndex] = 0.0f;
}
}
// Return completed grid
return new PythonNumpyFloatArray(grid, gridNx, gridNy);
}
}