diff --git a/cave/com.raytheon.viz.gfe/localization/gfe/userPython/utilities/SmartScript.py b/cave/com.raytheon.viz.gfe/localization/gfe/userPython/utilities/SmartScript.py index b7dd5efa6d..175258851a 100644 --- a/cave/com.raytheon.viz.gfe/localization/gfe/userPython/utilities/SmartScript.py +++ b/cave/com.raytheon.viz.gfe/localization/gfe/userPython/utilities/SmartScript.py @@ -78,7 +78,8 @@ # Sep 11, 2015 4858 dgilling Remove notification processing from publishElements. # Jan 20, 2016 4751 randerso Fix type of mask returned from getComposite() to work with numpy 1.9.2 # Jan 28, 2016 5129 dgilling Support changes to IFPClient. -# 02/22/2016 5374 randerso Added support for sendWFOMessage +# Feb 22, 2016 5374 randerso Added support for sendWFOMessage +# Apr 05, 2016 5539 randerso Added exception when attempting create more than 256 Wx keys # ######################################################################## import types, string, time, sys @@ -2198,6 +2199,10 @@ class SmartScript(BaseTool.BaseTool): for str in keys: if sortedUglyStr == self.sortUglyStr(str): return keys.index(str) + + if len(keys) >= 256: + raise IndexError("Attempt to create more than 256 Wx keys") + keys.append(uglyStr) return len(keys) - 1 diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/griddata/DiscreteGridData.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/griddata/DiscreteGridData.java index 95bc1a1c6e..b6c11e8385 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/griddata/DiscreteGridData.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/griddata/DiscreteGridData.java @@ -72,6 +72,7 @@ import com.vividsolutions.jts.geom.MultiPolygon; * 02/19/2013 1637 randerso Added throws declarations to translateDataFrom * 10/31/2013 2508 randerso Change to use DiscreteGridSlice.getKeys() * Apr 23, 2015 4259 njensen Removed unused INumpyable + * Apr 04, 2016 5539 randerso Fix unsigned byte issues * * * @@ -918,7 +919,7 @@ public class DiscreteGridData extends AbstractGridData { for (int j = 0; j < dim.y; j++) { if (points.get(i, j) == 1) { DiscreteKey combined = DiscreteKey.combine( - key.get(values.get(i, j)), + key.get(0xFF & values.get(i, j)), doGetDiscreteValue(i, j)); grid.set(i, j, lookupKeyValue(combined)); } diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/internal/ISCDataAccess.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/internal/ISCDataAccess.java index 746d4fc6a6..a0fcd22626 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/internal/ISCDataAccess.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/internal/ISCDataAccess.java @@ -76,6 +76,7 @@ import com.vividsolutions.jts.geom.Coordinate; * 10/31/2013 2508 randerso Change to use DiscreteGridSlice.getKeys() * 09/01/2014 3572 randerso Removed ourSiteMap as it was unused and the only * thing that used Grid2DBoolean + * 04/04/2016 5539 randerso Fix unsigned byte issues * * * @@ -462,7 +463,7 @@ public class ISCDataAccess implements IISCDataAccess { for (int i = 0; i < siteMask.getXdim(); i++) { if (siteMask.getAsBoolean(i, j)) { byte index = lookupKeyValue(keyIndexMap, - iscKey[iscGrid.get(i, j)]); + iscKey[0xFF & iscGrid.get(i, j)]); slice.getWeatherGrid().set(i, j, index); } } @@ -551,7 +552,7 @@ public class ISCDataAccess implements IISCDataAccess { for (int i = 0; i < siteMask.getXdim(); i++) { if (siteMask.getAsBoolean(i, j)) { byte index = lookupKeyValue(keyIndexMap, - iscKey[iscGrid.get(i, j)]); + iscKey[0xFF & iscGrid.get(i, j)]); slice.getDiscreteGrid().set(i, j, index); } } diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/parm/Parm.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/parm/Parm.java index d4f220b606..9675628544 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/parm/Parm.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/core/parm/Parm.java @@ -191,6 +191,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Sep 10, 2015 #4782 randerso Converted inParmEdit to ReentrantLock to force * updates to be run consecutively. * Cleaned up TODOs, FIXMEs and deprecations. + * Apr 04, 2016 #5539 randerso Fix unsigned byte issues * * * @@ -2161,10 +2162,9 @@ public abstract class Parm implements Comparable { .getGridSlice()).getKeys(); Grid2DByte grid1 = ((WeatherGridSlice) grids[k] .getGridSlice()).getWeatherGrid(); - WeatherKey tmpKey = key1[grid1.get(i, j)]; + WeatherKey tmpKey = key1[0xFF & grid1.get(i, j)]; WeatherSubKey gpkeys[] = tmpKey.getSubKeys().toArray( new WeatherSubKey[tmpKey.getSubKeys().size()]); - // key1[grid1(i, j)].subKeys(); for (int m = 0; m < gpkeys.length; m++) { int index = subKeys.indexOf(gpkeys[m]); if (index == -1) { @@ -2236,8 +2236,7 @@ public abstract class Parm implements Comparable { .getGridSlice()).getKeys(); Grid2DByte grid1 = ((DiscreteGridSlice) grids[k] .getGridSlice()).getDiscreteGrid(); - // TextString kv = key1[grid1(i, j)].keyAsString(); - DiscreteKey kv = key1[grid1.get(i, j)]; + DiscreteKey kv = key1[0xFF & grid1.get(i, j)]; // add it to the dictionary MutableInteger cnt = values.get(kv); if (cnt == null) { @@ -3706,7 +3705,7 @@ public abstract class Parm implements Comparable { .getGridSlice()); WeatherKey[] key1 = slice.getKeys(); Grid2DByte grid1 = slice.getWeatherGrid(); - WeatherKey key1ij = key1[grid1.get(i, j)]; + WeatherKey key1ij = key1[0xFF & grid1.get(i, j)]; subkeys.addAll(key1ij.getSubKeys()); } @@ -3760,7 +3759,7 @@ public abstract class Parm implements Comparable { .getGridSlice()).getKeys(); Grid2DByte grid1 = ((DiscreteGridSlice) grids[k] .getGridSlice()).getDiscreteGrid(); - DiscreteKey dkv = key1[grid1.get(i, j)]; + DiscreteKey dkv = key1[0xFF & grid1.get(i, j)]; String dks = dkv.toString(); // add it to the dictionary Integer count = values.get(dks); diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/interpolation/DiscreteInterp.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/interpolation/DiscreteInterp.java index 3f279aacca..d197e250ba 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/interpolation/DiscreteInterp.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/interpolation/DiscreteInterp.java @@ -121,10 +121,11 @@ import com.raytheon.viz.gfe.Activator; * *
  * SOFTWARE HISTORY
- * Date			Ticket#		Engineer	Description
- * ------------	----------	-----------	--------------------------
- * Jun 2, 2008		#1161	randerso	Initial creation
- * Oct 31, 2013     #2508   randerso    Change to use DiscreteGridSlice.getKeys()
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun  2, 2008  #1161     randerso    Initial creation
+ * Oct 31, 2013  #2508     randerso    Change to use DiscreteGridSlice.getKeys()
+ * Apr 04, 2016  #5539     randerso    Fix unsigned byte issues
  * 
  * 
* @@ -479,7 +480,7 @@ public class DiscreteInterp extends Interp { // input byte index grids, but with values for the weatherKeys // in _allKeys. - byte index; + int index; DiscreteKey key; // For every grid point in the grids, load the new working grids @@ -488,7 +489,7 @@ public class DiscreteInterp extends Interp { for (i = 0; i < _xDim; i++) { for (j = 0; j < _yDim; j++) { // get the index value from the actual first input grid of bytes - index = grid1.get(i, j); + index = 0xFF & grid1.get(i, j); // Can save a lot of processing here if index=0 // ALWAYS means "no weather": the workGrid1 and 2 values @@ -508,7 +509,7 @@ public class DiscreteInterp extends Interp { // get the index value from the actual second input grid of // bytes - index = grid2.get(i, j); + index = 0xFF & grid2.get(i, j); // get its key key = keys2[index]; // find this key in the new list, and save the corresponding diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/ifpAG/ASCIIGrid.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/ifpAG/ASCIIGrid.java index 90c300cd9f..c10314e9eb 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/ifpAG/ASCIIGrid.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/ifpAG/ASCIIGrid.java @@ -75,12 +75,13 @@ import com.vividsolutions.jts.geom.Coordinate; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Apr 13, 2011 #8393 dgilling Initial creation - * 02/19/13 #1637 randerso Added exception handling for Discrete and Weather - * 10/31/2013 #2508 randerso Change to use DiscreteGridSlice.getKeys() - * 04/22/2014 #3050 randerso Allow exceptions to propagate to caller from readASCIIGridData - * Jan 14, 2016 #5237 tgurney Allow outputAsciiGridData to take - * OutputStream as well as File + * Apr 13, 2011 #8393 dgilling Initial creation + * 02/19/13 #1637 randerso Added exception handling for Discrete and Weather + * 10/31/2013 #2508 randerso Change to use DiscreteGridSlice.getKeys() + * 04/22/2014 #3050 randerso Allow exceptions to propagate to caller from readASCIIGridData + * 01/14/2016 #5237 tgurney Allow outputAsciiGridData to take + * OutputStream as well as File + * 04/04/2016 #5539 randerso Fixed unsigned byte issues * * * @@ -341,7 +342,7 @@ public class ASCIIGrid { WeatherGridSlice weather = (WeatherGridSlice) gs; for (int i = weather.getWeatherGrid().getYdim() - 1; i >= 0; i--) { for (int j = 0; j < weather.getWeatherGrid().getXdim(); j++) { - String key = weather.getKeys()[weather + String key = weather.getKeys()[0xFF & weather .getWeatherGrid().get(j, i)].toString(); printStream.println(key); } @@ -352,7 +353,7 @@ public class ASCIIGrid { for (int i = discrete.getDiscreteGrid().getYdim() - 1; i >= 0; i--) { for (int j = 0; j < discrete.getDiscreteGrid() .getXdim(); j++) { - String key = discrete.getKeys()[discrete + String key = discrete.getKeys()[0xFF & discrete .getDiscreteGrid().get(j, i)].toString(); printStream.println(key); } diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/handler/GetPointDataHandler.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/handler/GetPointDataHandler.java index f0b6568ab3..881c6774e6 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/handler/GetPointDataHandler.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/handler/GetPointDataHandler.java @@ -35,8 +35,8 @@ import javax.measure.unit.Unit; import com.raytheon.edex.plugin.gfe.server.IFPServer; import com.raytheon.edex.plugin.gfe.server.database.GridDatabase; import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID; -import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridParmInfo.GridType; import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation; +import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridParmInfo.GridType; import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID; import com.raytheon.uf.common.dataplugin.gfe.point.GFEPointDataContainer; import com.raytheon.uf.common.dataplugin.gfe.point.GFEPointDataContainers; @@ -70,6 +70,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Jun 13, 2013 #2044 randerso Refactored to use IFPServer * Oct 31, 2013 #2508 randerso Change to use DiscreteGridSlice.getKeys() * Apr 23, 2014 #3006 randerso Restructured code to work with multi-hour grids + * Apr 04, 2016 #5539 randerso Fixed unsigned byte issues * * * @@ -209,7 +210,7 @@ public class GetPointDataHandler extends BaseGfeRequestHandler implements byte discreteValue = discreteSlice .getDiscreteGrid().get(x, y); String discreteKey = discreteSlice - .getKeys()[discreteValue] + .getKeys()[0xFF & discreteValue] .toString(); type = Type.STRING; view.setData(param, type, unit, discreteKey); @@ -218,7 +219,7 @@ public class GetPointDataHandler extends BaseGfeRequestHandler implements WeatherGridSlice weatherSlice = (WeatherGridSlice) slice; byte wxValue = weatherSlice .getWeatherGrid().get(x, y); - String wxKey = weatherSlice.getKeys()[wxValue] + String wxKey = weatherSlice.getKeys()[0xFF & wxValue] .toString(); type = Type.STRING; view.setData(param, type, unit, wxKey); diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/ifpnetCDF.py b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/ifpnetCDF.py index d01ea1a26e..a2620efc39 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/ifpnetCDF.py +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/ifpnetCDF.py @@ -41,6 +41,8 @@ # 05/13/2015 4427 dgilling Add siteIdOverride field. # 08/06/2015 4718 dgilling Optimize casting when using where with # NumPy 1.9. +# 04/07/2016 5539 randerso Reversed order of parameters/return value in collapseKey +# to match order of Wx/Discrete tuple # ## @@ -924,21 +926,20 @@ def storeVectorWE(we, trList, file, timeRange, ###-------------------------------------------------------------------------### # Collapse key and bytes. (for discrete and weather) -### Returns tuple of (updated key, updated grid) -def collapseKey(keys, grid): +### Returns tuple of (updated grid, updated key) +def collapseKey(grid, keys): #make list of unique indexes in the grid flatGrid = grid.flat - used = [] + used = numpy.zeros((len(keys)), dtype=numpy.bool) for n in range(flatGrid.__array__().shape[0]): - if flatGrid[n] not in used: - used.append(flatGrid[n]) + used[0xFF & flatGrid[n]] = True #make reverse map map = [] newKeys = [] j = 0 for i in range(len(keys)): - if i in used: + if used[i]: map.append(j) newKeys.append(keys[i]) j = j + 1 @@ -948,10 +949,10 @@ def collapseKey(keys, grid): # modify the data newGrid = grid for k in range(len(map)): - mask = numpy.equal(k, grid) + mask = numpy.equal(numpy.int8(k), grid) newGrid = numpy.where(mask, numpy.int8(map[k]), newGrid).astype(numpy.int8) - return (newKeys, newGrid) + return (newGrid, newKeys) ###-------------------------------------------------------------------------### # Stores the specified Weather WE in the netCDF file whose grids fall within @@ -987,7 +988,7 @@ def storeWeatherWE(we, trList, file, timeRange, databaseID, invMask, clipArea, s # Process the weather keys so we store only what is necessary for g in range(byteCube.shape[0]): - (keyList[g], byteCube[g]) = collapseKey(keyList[g], byteCube[g]) + (byteCube[g], keyList[g]) = collapseKey(byteCube[g], keyList[g]) # Mask the values fillValue = -127 @@ -1072,7 +1073,7 @@ def storeDiscreteWE(we, trList, file, timeRange, databaseID, invMask, clipArea, # Process the discrete keys so we store only what is necessary for g in range(byteCube.shape[0]): - (keyList[g], byteCube[g]) = collapseKey(keyList[g], byteCube[g]) + (byteCube[g], keyList[g]) = collapseKey(byteCube[g], keyList[g]) # Mask the values fillValue = -127 diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/mergeGrid.py b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/mergeGrid.py index 6ddf7a8b9b..031c9f0664 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/mergeGrid.py +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/mergeGrid.py @@ -39,7 +39,7 @@ import LogStream, fcntl # 11/05/13 2517 randerso Improve memory utilization # 08/06/2015 4718 dgilling Optimize casting when using where with # NumPy 1.9. -# +# 04/07/2016 5539 randerso Fixed issues with Wx/Discretes with large number of keys # # @@ -79,6 +79,9 @@ class MergeGrid: index = keyMap.index(key) return index except: + if (len(keyMap) >= 256): + raise IndexError("Attempt to create more than 256 Wx keys") + keyMap.append(key) return len(keyMap) - 1 @@ -186,6 +189,36 @@ class MergeGrid: return (magGrid, dirGrid) + ###-------------------------------------------------------------------------### + # Collapse key and bytes. (for discrete and weather) + ### Returns tuple of (updated grid, updated key) + def __collapseKey(self, grid, keys): + #make list of unique indexes in the grid + flatGrid = grid.flat + used = numpy.zeros((len(keys)), dtype=numpy.bool) + for n in range(flatGrid.__array__().shape[0]): + used[0xFF & flatGrid[n]] = True + + #make reverse map + map = [] + newKeys = [] + j = 0 + for i in range(len(keys)): + if used[i]: + map.append(j) + newKeys.append(keys[i]) + j = j + 1 + else: + map.append(-1) + + # modify the data + newGrid = grid + for k in range(len(map)): + mask = numpy.equal(numpy.int8(k), grid) + newGrid = numpy.where(mask, numpy.int8(map[k]), newGrid).astype(numpy.int8) + + return (newGrid, newKeys) + #--------------------------------------------------------------------- # merge weather grid # @@ -208,6 +241,11 @@ class MergeGrid: noWxGrid = numpy.empty_like(gridA[0]) noWxGrid.fill(self.__findKey(noWx, noWxKeys)) gridB = (noWxGrid, noWxKeys) + else: + # clear out the masked area in gridB and collapse gridB's keys + grid, keys = gridB + grid[mask]= self.__findKey(noWx, keys) + gridB = self.__collapseKey(grid, keys) (commonkey, remapG, dbG) = self.__commonizeKey(gridA, gridB) mergedGrid = numpy.where(mask, remapG, dbG) return (mergedGrid, commonkey) @@ -242,6 +280,11 @@ class MergeGrid: noGrid = numpy.empty_like(gridA[0]) noGrid.fill(self.__findKey(noKey, noKeys)) gridB = (noGrid, noKeys) + else: + # clear out the masked area in gridB and collapse gridB's keys + grid, keys = gridB + grid[mask] = self.__findKey(noKey, keys) + gridB = self.__collapseKey(grid, keys) (commonkey, remapG, dbG) = \ self.__commonizeKey(gridA, gridB) diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/grid/Grid2DByte.java b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/grid/Grid2DByte.java index 567a702292..53b5a3e4ed 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/grid/Grid2DByte.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/grid/Grid2DByte.java @@ -42,6 +42,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Oct 22, 2008 1624 wdougherty Speed up translate method * Sep 01, 2014 3572 randerso Changed getNumpy to use getBytes() * Apr 23, 2015 4259 njensen Updated for new JEP API + * Apr 04, 2016 5539 randerso Fixed toString method to handle unsigned bytes * * * @@ -103,7 +104,7 @@ public class Grid2DByte implements IGrid2D, Cloneable { */ public Grid2DByte(int xDim, int yDim, byte[] data) { this(xDim, yDim); - if (xDim * yDim != data.length) { + if ((xDim * yDim) != data.length) { throw new IllegalArgumentException( "Dimensions do not match data length (" + xDim + "," + yDim + ") " + data.length); @@ -122,7 +123,7 @@ public class Grid2DByte implements IGrid2D, Cloneable { * ByteBuffer of initialization data */ public Grid2DByte(int xDim, int yDim, ByteBuffer data) { - if (xDim * yDim != data.limit()) { + if ((xDim * yDim) != data.limit()) { throw new IllegalArgumentException( "Dimensions do not match data length (" + xDim + "," + yDim + ") " + data.limit()); @@ -165,7 +166,7 @@ public class Grid2DByte implements IGrid2D, Cloneable { if (!isValid(xDim, yDim)) { throw new IllegalArgumentException("Dimensions not valid"); } - return buffer.get(yDim * this.xdim + xDim); + return buffer.get((yDim * this.xdim) + xDim); } /** @@ -180,7 +181,7 @@ public class Grid2DByte implements IGrid2D, Cloneable { if (!isValid(xDim, yDim)) { throw new IllegalArgumentException("Dimensions not valid"); } - buffer.put(yDim * this.xdim + xDim, aValue); + buffer.put((yDim * this.xdim) + xDim, aValue); } public void set(int xDim, int yDim, int aValue) { @@ -205,7 +206,7 @@ public class Grid2DByte implements IGrid2D, Cloneable { @Override public boolean isValid(int x, int y) { - return (x < xdim && y < ydim && x >= 0 && y >= 0); + return ((x < xdim) && (y < ydim) && (x >= 0) && (y >= 0)); } /** @@ -224,7 +225,7 @@ public class Grid2DByte implements IGrid2D, Cloneable { * y coordinate to clear */ public void clear(int x, int y) { - buffer.put(y * xdim + x, (byte) 0); + buffer.put((y * xdim) + x, (byte) 0); } /** @@ -241,7 +242,7 @@ public class Grid2DByte implements IGrid2D, Cloneable { // make another Grid2DByte Grid2DByte rVal = new Grid2DByte(this.xdim, this.ydim, (byte) 0); - if (Math.abs(deltaCoord.x) < xdim && Math.abs(deltaCoord.y) < ydim) { + if ((Math.abs(deltaCoord.x) < xdim) && (Math.abs(deltaCoord.y) < ydim)) { // Find iteration limits for X int fromXStart; int toXStart; @@ -275,8 +276,8 @@ public class Grid2DByte implements IGrid2D, Cloneable { byte[] toA = rVal.getBuffer().array(); // Calculate from/to array offsets of the first point. - int fromOffset = fromYStart * xdim + fromXStart; - int toOffset = toYStart * xdim + toXStart; + int fromOffset = (fromYStart * xdim) + fromXStart; + int toOffset = (toYStart * xdim) + toXStart; // For each row, copy cols bytes of data. // Then update offsets for next row. @@ -328,9 +329,9 @@ public class Grid2DByte implements IGrid2D, Cloneable { @Override public Grid2DByte subGrid(int minX, int minY, int maxX, int maxY) { - Grid2DByte rVal = new Grid2DByte(maxX + 1 - minX, maxY + 1 - minY); - for (int y = minY; y < maxY + 1; y++) { - for (int x = minX; x < maxX + 1; x++) { + Grid2DByte rVal = new Grid2DByte((maxX + 1) - minX, (maxY + 1) - minY); + for (int y = minY; y < (maxY + 1); y++) { + for (int x = minX; x < (maxX + 1); x++) { rVal.buffer.put(this.get(x, y)); } } @@ -345,7 +346,8 @@ public class Grid2DByte implements IGrid2D, Cloneable { Grid2DByte rhsGrid2DByte = (Grid2DByte) rhs; - if (this.xdim != rhsGrid2DByte.xdim || this.ydim != rhsGrid2DByte.ydim) { + if ((this.xdim != rhsGrid2DByte.xdim) + || (this.ydim != rhsGrid2DByte.ydim)) { return false; } @@ -374,9 +376,10 @@ public class Grid2DByte implements IGrid2D, Cloneable { Grid2DByte sourceGrid2DByte = (Grid2DByte) sourceGrid; - if (this.xdim != sourceGrid2DByte.xdim || this.xdim != maskGrid.xdim - || this.ydim != sourceGrid2DByte.ydim - || this.ydim != maskGrid.ydim) { + if ((this.xdim != sourceGrid2DByte.xdim) + || (this.xdim != maskGrid.xdim) + || (this.ydim != sourceGrid2DByte.ydim) + || (this.ydim != maskGrid.ydim)) { throw new IllegalArgumentException( "This grid, the input grid, and the input mask grid must have equal dimensions"); } @@ -407,7 +410,7 @@ public class Grid2DByte implements IGrid2D, Cloneable { rVal += xdim + "X" + ydim + "\n[\n"; for (int y = 0; y < ydim; y++) { for (int x = 0; x < xdim; x++) { - rVal += this.get(x, y) + (x + 1 == xdim ? "" : ","); + rVal += (0xFF & this.get(x, y)) + ((x + 1) == xdim ? "" : ","); } rVal += "\n"; } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/slice/WeatherGridSlice.java b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/slice/WeatherGridSlice.java index f531e35b81..6e0fa5bdd7 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/slice/WeatherGridSlice.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/slice/WeatherGridSlice.java @@ -53,13 +53,14 @@ import com.raytheon.uf.common.time.TimeRange; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Mar 15, 2011 randerso Initial creation - * 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() - * Apr 23, 2015 4259 njensen Updated for new JEP API - * Nov 03, 2015 5061 randerso Fixed null pointer in equals() + * Mar 15, 2011 randerso Initial creation + * 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() + * Apr 23, 2015 4259 njensen Updated for new JEP API + * Nov 03, 2015 5061 randerso Fixed null pointer in equals() + * Apr 05, 2016 5539 randerso Cleaned up collapse method * * * @@ -645,63 +646,81 @@ public class WeatherGridSlice extends AbstractGridSlice { return; } - // make a histogram, indicating what is and what isn't - // used in the weather keys - boolean[] used = new boolean[keys.length]; - int[] invMapping = new int[keys.length]; - for (int i = 0; i < used.length; i++) { - invMapping[i] = i; - used[i] = false; - } - - // process the grid - for (int i = 0; i < weatherGrid.getXdim(); i++) { - for (int j = 0; j < weatherGrid.getYdim(); j++) { - used[0xFF & weatherGrid.get(i, j)] = true; - } - } // indicate used - - // clear the invmapping if not used - for (int i = 0; i < used.length; i++) { - if (!used[i]) { - invMapping[i] = -1; - } - } - - // eliminate duplicate keys - int nk = 0; - List tmpKeys = new ArrayList(); - for (int i = 0; i < used.length; i++) { - if (used[i]) { - tmpKeys.add(keys[i]); - invMapping[i] = nk; - for (int j = i + 1; j < used.length; j++) { - if (keys[i].equals(keys[j])) { - invMapping[j] = nk; // key index - used[j] = false; // to prevent reprocessing - } + try { + int max = 0; + for (byte b : weatherGrid.getBytes()) { + int unsigned = 0xFF & b; + if (unsigned > max) { + max = unsigned; } - nk++; } - } - WeatherKey[] newKeys = tmpKeys.toArray(new WeatherKey[tmpKeys.size()]); - // anything to do? - if (Arrays.equals(newKeys, keys)) { - return; - } - - // now remap the data - for (int i = 0; i < weatherGrid.getXdim(); i++) { - for (int j = 0; j < weatherGrid.getYdim(); j++) { - weatherGrid.set(i, j, - (byte) invMapping[0xFF & weatherGrid.get(i, j)]); + if (max >= keys.length) { + throw new IndexOutOfBoundsException("Grid contains index (" + + max + ") > keys.length (" + keys.length + ")"); } - } - // store the grid - setWeatherGrid(weatherGrid); - keys = newKeys; + // make a histogram, indicating what is and what isn't + // used in the weather keys + boolean[] used = new boolean[keys.length]; + int[] invMapping = new int[keys.length]; + for (int i = 0; i < used.length; i++) { + invMapping[i] = i; + used[i] = false; + } + + // process the grid + for (int i = 0; i < weatherGrid.getXdim(); i++) { + for (int j = 0; j < weatherGrid.getYdim(); j++) { + used[0xFF & weatherGrid.get(i, j)] = true; // indicate used + } + } + + // clear the invmapping if not used + for (int i = 0; i < used.length; i++) { + if (!used[i]) { + invMapping[i] = -1; + } + } + + // eliminate duplicate keys + int nk = 0; + List tmpKeys = new ArrayList(); + for (int i = 0; i < used.length; i++) { + if (used[i]) { + tmpKeys.add(keys[i]); + invMapping[i] = nk; + for (int j = i + 1; j < used.length; j++) { + if (keys[i].equals(keys[j])) { + invMapping[j] = nk; // key index + used[j] = false; // to prevent reprocessing + } + } + nk++; + } + } + WeatherKey[] newKeys = tmpKeys.toArray(new WeatherKey[tmpKeys + .size()]); + + // anything to do? + if (Arrays.equals(newKeys, keys)) { + return; + } + + // now remap the data + for (int i = 0; i < weatherGrid.getXdim(); i++) { + for (int j = 0; j < weatherGrid.getYdim(); j++) { + weatherGrid.set(i, j, + (byte) invMapping[0xFF & weatherGrid.get(i, j)]); + } + } + // store the grid + setWeatherGrid(weatherGrid); + keys = newKeys; + } catch (IndexOutOfBoundsException e) { + statusHandler.error(e.getLocalizedMessage(), e); + throw e; + } } @Override