Issue #2661 Use only u,v to represent vector grids in derived parameters and D2D.

Change-Id: I7ea007f0f919017e8212716cc15712c7ed611e69

Former-commit-id: ee11e5d13c [formerly a8bcec4a2fa9ddd49dc300ebd63aebfdfb41723e]
Former-commit-id: ac33fb9463
This commit is contained in:
Ben Steffensmeier 2014-01-14 11:47:50 -06:00
parent 7efb35be30
commit be163ebf2a
58 changed files with 447 additions and 2203 deletions

View file

@ -2,22 +2,16 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2 Bundle-ManifestVersion: 2
Bundle-Name: Derived Parameter Python Plug-in Bundle-Name: Derived Parameter Python Plug-in
Bundle-SymbolicName: com.raytheon.uf.viz.derivparam.python;singleton:=true Bundle-SymbolicName: com.raytheon.uf.viz.derivparam.python;singleton:=true
Bundle-Version: 1.0.0.qualifier Bundle-Version: 1.14.0.qualifier
Bundle-Activator: com.raytheon.uf.viz.derivparam.python.Activator
Bundle-Vendor: RAYTHEON Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Require-Bundle: com.raytheon.uf.common.status;bundle-version="1.12.1174", Require-Bundle: com.raytheon.uf.common.python,
com.raytheon.uf.common.serialization;bundle-version="1.12.1174", com.raytheon.uf.common.python.concurrent,
com.raytheon.uf.common.python;bundle-version="1.12.1174", com.raytheon.uf.viz.derivparam;bundle-version="1.14.0",
com.raytheon.uf.viz.core;bundle-version="1.12.1174", com.raytheon.uf.viz.core;bundle-version="1.13.0",
com.raytheon.uf.viz.derivparam;bundle-version="1.12.1174", com.raytheon.uf.common.wxmath,
com.raytheon.uf.common.datastorage;bundle-version="1.12.1174", com.raytheon.uf.common.util,
org.jep;bundle-version="1.0.0", com.raytheon.uf.common.datastorage
org.eclipse.ui;bundle-version="3.6.1",
org.eclipse.core.runtime;bundle-version="3.6.0",
com.raytheon.uf.common.util;bundle-version="1.12.1174",
com.raytheon.uf.common.python.concurrent;bundle-version="1.0.0",
com.raytheon.uf.common.wxmath
Export-Package: com.raytheon.uf.viz.derivparam.python, Export-Package: com.raytheon.uf.viz.derivparam.python,
com.raytheon.uf.viz.derivparam.python.function com.raytheon.uf.viz.derivparam.python.function

View file

@ -18,10 +18,9 @@
# further licensing information. # further licensing information.
## ##
from numpy import add from numpy import add,array,zeros_like
from numpy import array
from Vector import execute as Vector import Vector
def execute(*args): def execute(*args):
""" Perform scalar or vector addition """ Perform scalar or vector addition
@ -38,33 +37,11 @@ def scalarAddition(args):
return reduce(add, args) return reduce(add, args)
def vectorAddition(args): def vectorAddition(args):
uResult = zeros_like(args[0][0])
vResult = zeros_like(args[0][0])
from numpy import zeros for u, v in args:
uResult += u
vResult += v
targetShape = args[0][2].shape return Vector.componentsTo(uResult, vResult)
targetType = args[0][2].dtype
uResult = zeros(shape=(targetShape), dtype=targetType)
vResult = zeros(shape=(targetShape), dtype=targetType)
for arg in args:
uResult = scalarAddition((uResult, arg[2]))
vResult = scalarAddition((vResult, arg[3]))
return Vector(uResult, vResult)
def test():
if not( all(execute(array([1., 2.]), array([3., 4.])) == array([4., 6.]))):
raise Exception
Vector1 = Vector(array([1.,2.]),array([0.,270.]),True)
Vector2 = Vector(array([3.,4.]),array([180.,90.]),True)
(mag, dir, u, v) = execute(Vector1,Vector2)
if not( all(mag == array([2., 2.])) and all(dir.round(0) == array([180., 90.]))):
raise Exception
if not( all(execute(array([1., 2.]), 3.) == array([4., 5.]))):
raise Exception
print "Add Test Complete"

View file

@ -20,7 +20,7 @@
## @file CompBy.py ## @file CompBy.py
from numpy import cos, sin, sqrt from numpy import cos, sin, sqrt
from Vector import execute as Vector import Vector
## ##
# This function is based on the comp_by.f Fortran function by J. Ramer, Jul 1 2003. # This function is based on the comp_by.f Fortran function by J. Ramer, Jul 1 2003.
@ -50,8 +50,8 @@ def execute(Vecs, ThGrd, Angle=0):
# pi/180 for degrees to radians conversion # pi/180 for degrees to radians conversion
dgtord = 0.01745329252 dgtord = 0.01745329252
Vecs_U, Vecs_V = Vecs[2], Vecs[3] Vecs_U, Vecs_V = Vecs
ThGrd_U, ThGrd_V = ThGrd[2], ThGrd[3] ThGrd_U, ThGrd_V = ThGrd
if Angle != 0: if Angle != 0:
# Strip off any 1000s from angle. # Strip off any 1000s from angle.
@ -85,7 +85,7 @@ def execute(Vecs, ThGrd, Angle=0):
comp = rotated_u * mag comp = rotated_u * mag
comp2 = rotated_v * mag comp2 = rotated_v * mag
return Vector(comp, comp2) return Vector.componentsTo(comp, comp2)
else: else:
# initialize to u and v from ThGrd # initialize to u and v from ThGrd
rotated_u = ThGrd_U rotated_u = ThGrd_U

View file

@ -49,7 +49,7 @@ def execute(A0, A1, B0, B1):
v1 = A1[3] v1 = A1[3]
uDeriv = execute(u0, u1, B0, B1) uDeriv = execute(u0, u1, B0, B1)
vDeriv = execute(v0, v1, B0, B1) vDeriv = execute(v0, v1, B0, B1)
return Vector.execute(uDeriv, vDeriv) return Vector.componentsTo(uDeriv, vDeriv)
Adiff = A1-A0 Adiff = A1-A0
Bdiff = B1-B0 Bdiff = B1-B0

View file

@ -28,10 +28,7 @@ def execute(*args):
if type(diffArgs[0]) == tuple: if type(diffArgs[0]) == tuple:
for i in range(1, len(diffArgs)): for i in range(1, len(diffArgs)):
diffVectorArg = list(diffArgs[i]) diffArgs[i] = (-diffArgs[i][0], -diffArgs[i][1])
diffVectorArg[2] = -diffVectorArg[2]
diffVectorArg[3] = -diffVectorArg[3]
diffArgs[i] = tuple(diffVectorArg)
return apply(Add, diffArgs) return apply(Add, diffArgs)
else: else:
result = 0 result = 0
@ -39,23 +36,3 @@ def execute(*args):
for i in range(1, len(diffArgs)): for i in range(1, len(diffArgs)):
result -= diffArgs[i] result -= diffArgs[i]
return result return result
def test():
from numpy import array
if not(all(execute(array([1., 2.]), array([3., 4.])) == array([ - 2, - 2]))):
raise Exception
from Vector import execute as Vector
# using meteoroligcal directions
Vector1 = Vector(array([1., 2.]), array([0., 270.]), True)
Vector2 = Vector(array([3., 4.]), array([180., 90.]), True)
(mag, dir, u, v) = execute(Vector1, Vector2)
if not(all(mag == array([2., 2.])) and all(dir.round(0) == array([180., 90.]))):
print mag
print dir
raise Exception
print "Difference Test Complete"

View file

@ -43,8 +43,7 @@ def execute(vec, dx, dy, quan=1.0):
dvdy = diff_v/dy[i,j] \n dvdy = diff_v/dy[i,j] \n
diverg[i,j] = (dudx + dvdy)/2 \n diverg[i,j] = (dudx + dvdy)/2 \n
""" """
vec_U = vec[2] vec_U,vec_V = vec
vec_V = vec[3]
vshape = shape(vec_U) vshape = shape(vec_U)

View file

@ -20,8 +20,7 @@
## @file Geowind.py ## @file Geowind.py
from numpy import isscalar from numpy import isscalar,NaN
from numpy import NaN
import Vector import Vector
g = 9.806 # Gravitational acceleration (m/s^2) g = 9.806 # Gravitational acceleration (m/s^2)
@ -79,5 +78,5 @@ def execute(Height, dx, dy, coriolis):
result_U = result_U result_U = result_U
result_V = result_V result_V = result_V
result = Vector.execute(result_U, result_V) result = Vector.componentsTo(result_U, result_V)
return result return result

View file

@ -66,5 +66,5 @@ def execute(scalar, dx, dy):
result_u[:,1:-1] = ans_u result_u[:,1:-1] = ans_u
result_v[1:-1,:] = ans_v result_v[1:-1,:] = ans_v
return Vector.execute(result_u, result_v) return Vector.componentsTo(result_u, result_v)

View file

@ -20,7 +20,7 @@
from Add import execute as Add from Add import execute as Add
from Multiply import execute as Multiply from Multiply import execute as Multiply
from numpy import zeros, ndarray from numpy import zeros_like, ndarray
def execute(*args): def execute(*args):
"""Perform a linear transform """Perform a linear transform
@ -35,16 +35,13 @@ def execute(*args):
if type(args[0]) == tuple: if type(args[0]) == tuple:
targetShape = args[0][0].shape zeroArray = zeros_like(args[0][0])
targetType = args[0][0].dtype result = (zeroArray, zeroArray.copy())
zeroArray = zeros(shape=(targetShape), dtype=targetType)
result = (zeroArray, zeroArray.copy(), zeroArray.copy(), zeroArray.copy())
else: else:
for arg in args: for arg in args:
if (type(arg) == ndarray): if (type(arg) == ndarray):
targetShape = arg.shape result = zeros_like(arg)
targetType = arg.dtype break
result = zeros(shape=targetShape, dtype=targetType)
termLength = 2 termLength = 2
@ -58,23 +55,3 @@ def execute(*args):
result = Add(result, Multiply(coefficient, variable)) result = Add(result, Multiply(coefficient, variable))
return result return result
def test():
from numpy import array
if not( all(execute(array([1., 2.]), array([3., 4.]), array([1., 2.]), array([3., 4.])) == array([6., 16.]))):
raise Exception
from Vector import execute as Vector
# using meteorological direction
Vector1 = Vector(array([1., 2.]), array([0., 270.]), True)
Vector2 = Vector(array([3., 4.]), array([180., 90.]), True)
(mag, dir, u, v) = execute(Vector1, array([3., 4.]), Vector2, array([3., 4.]))
if not( all(mag == array([6., 8.])) and all(dir.round(0) == array([180., 90.]))):
print mag
print dir
raise Exception
print "LinTrans Test Complete"

View file

@ -21,9 +21,8 @@
from numpy import log, exp from numpy import log, exp
import PartialDerivative as Partial import PartialDerivative as Partial
import DgeoComps as DgeoComps import DgeoComps
from Vector import execute as Vector import Vector
## ##
# Find Q vectors from height, temp, and pressure. # Find Q vectors from height, temp, and pressure.
# #
@ -44,7 +43,7 @@ from Vector import execute as Vector
def execute(GHxSM, TxSM, P, dx, dy, coriolis): def execute(GHxSM, TxSM, P, dx, dy, coriolis):
result_u, result_v, dtdx, dtdy = calculate(GHxSM, TxSM, P, dx, dy, coriolis) result_u, result_v, dtdx, dtdy = calculate(GHxSM, TxSM, P, dx, dy, coriolis)
# convert the results we want to unmasked arrays # convert the results we want to unmasked arrays
return Vector(result_u, result_v) return Vector.componentsTo(result_u, result_v)
## ##
# Find Q vectors and dtemp/dx and dtemp/dy from height, temp, and pressure. # Find Q vectors and dtemp/dx and dtemp/dy from height, temp, and pressure.

View file

@ -22,7 +22,7 @@ from numpy import log, exp
import PartialDerivative as Partial import PartialDerivative as Partial
import DgeoComps as DgeoComps import DgeoComps as DgeoComps
from Vector import execute as Vector import Vector
## ##
# Find Q vectors from upper and lower height and pressure. # Find Q vectors from upper and lower height and pressure.
@ -47,7 +47,7 @@ def execute(height_up, height_lo, pressure_up, pressure_lo, dx, dy, coriolis):
qx, qy, dtdx, dtdy = calculate(height_up, height_lo, pressure_up, pressure_lo, dx, dy, coriolis) qx, qy, dtdx, dtdy = calculate(height_up, height_lo, pressure_up, pressure_lo, dx, dy, coriolis)
# unmask the arrays we're interested in # unmask the arrays we're interested in
return Vector(qx, qy) return Vector.componentsTo(qx, qy)
## ##
# Find Q vectors and dtdx and dtdy from upper and lower height and pressure. # Find Q vectors and dtdx and dtdy from upper and lower height and pressure.

View file

@ -29,34 +29,6 @@ def execute(*args):
""" """
if type(args[0]) == tuple: if type(args[0]) == tuple:
return vectorMagnitude(args[0]) return hypot(args[0][0], args[0][1])
else: else:
return componentMagnitude(args[0], args[1]) return hypot(args[0], args[1])
def vectorMagnitude(vector):
""" Return the first item in the vector tuple (its the magnitude)
vector tuples are assumed to follow the tuple returned by the
Vector.execute method. That is (mag,dir,u,v)
"""
return vector[0]
def componentMagnitude(u, v):
return hypot(u, v)
def test():
from Vector import execute as Vector
from numpy import array
testVector = Vector(array([1., 2.]), array([180., 270.]), True)
result = execute(testVector)
if not(all(result == array([1.,2.]))):
raise Exception
result = execute(testVector[2],testVector[3])
if not(all(result == array([1.,2.]))):
raise Exception
print "Magnitude Test Complete"

View file

@ -19,7 +19,7 @@
## ##
from numpy import multiply from numpy import multiply
from Vector import execute as Vector import Vector
def execute(*args): def execute(*args):
""" Perform multiplication of any number of scalars or of a vector and a scalar. """ Perform multiplication of any number of scalars or of a vector and a scalar.
@ -32,27 +32,8 @@ def execute(*args):
return scalarMultiply(args) return scalarMultiply(args)
def scalarMultiply(args): def scalarMultiply(args):
return reduce(multiply, args) return reduce(multiply, args)
def vectorMultiply(args): def vectorMultiply(args):
return Vector.componentsTo(scalarMultiply((args[0][0], args[1])), scalarMultiply((args[0][1], args[1])))
vector = args[0]
scalar = args[1]
return Vector(scalarMultiply((vector[2], scalar)), scalarMultiply((vector[3], scalar)))
def test():
from numpy import array
if not(all(execute(array([2., 4.]), 2.) == array([4., 8.]))):
raise Exception
vector = Vector(array([2., 4.]), array([0., 270.]), True)
(mag, dir, u, v) = execute(vector, 2.)
if not(all(mag == array([4., 8.])) and all(dir == array([0., 270.]))):
raise Exception
print "Multiply Test Complete"

View file

@ -21,10 +21,9 @@
#import sys #import sys
#sys.path.append("..") #sys.path.append("..")
from numpy import ndarray,NaN from numpy import ndarray,NaN, float32
from numpy import float32
from Vector import execute as Vector
from Multiply import execute as Multiply from Multiply import execute as Multiply
import Vector
## ##
# This routine computes the non-advective local change of an arbitrary # This routine computes the non-advective local change of an arbitrary
@ -72,72 +71,4 @@ def execute(u, v, a, dx, dy):
# calculate values for the middle # calculate values for the middle
dadydt[1:-1,1:-1] = -0.5 * (dudy*dadx + dvdy*dady) dadydt[1:-1,1:-1] = -0.5 * (dudy*dadx + dvdy*dady)
return Vector(-dadxdt, dadydt) return Vector.componentsTo(-dadxdt, dadydt)
def test():
ua = [[-1.38, -1.88, -2.49000001, -3.12999988, -3.7099998, -4.0999999],
[-1.22000003, -1.68999994, -2.26999998, -2.88999987, -3.46000004, -3.82999992],
[-1.03999996, -1.46999991, -2.00999999, -2.5999999, -3.12999988, -3.49000001],
[-0.84999996, -1.24000001, -1.70999992, -2.24000001, -2.73000002, -3.07999992],
[-0.64999998, -0.98999995, -1.39999998, -1.8499999, -2.28999996, -2.62999988],
[-0.44999999, -0.75, -1.09000003, -1.45999992, -1.82999992, -2.15999985]]
va = [[ 5.10999966, 5.42999983, 5.76999998, 6.10999966, 6.40999985, 6.63999987],
[ 4.63999987, 4.94000006, 5.23999977, 5.53999996, 5.80999994, 6.06999969],
[ 4.17000008, 4.44999981, 4.73999977, 5.01999998, 5.26999998, 5.52999973],
[ 3.68999982, 3.99000001, 4.27999973, 4.53999996, 4.76999998, 5.03999996],
[ 3.22000003, 3.53999996, 3.83999991, 4.0999999, 4.32999992, 4.5999999],
[ 2.75, 3.0999999, 3.41999984, 3.69999981, 3.92999983, 4.19000006]]
aa = [[ 441.26159668, 440.68197632, 440.29559326, 439.90917969, 439.71600342,
439.52279663],
[ 441.06838989, 440.68197632, 440.29559326, 439.90917969, 439.52279663,
439.52279663],
[ 441.06838989, 440.68197632, 440.29559326, 439.90917969, 439.52279663,
439.52279663],
[ 441.06838989, 440.68197632, 440.48876953, 440.10238647, 439.71600342,
439.52279663],
[ 441.06838989, 440.68197632, 440.48876953, 440.10238647, 439.90917969,
439.71600342],
[ 441.06838989, 440.68197632, 440.48876953, 440.10238647, 439.90917969,
439.71600342]]
dxa = [[ 34735.1328125, 34695.375, 34642.5625, 34590.0078125,
34537.7265625, 34485.7109375],
[ 34823.0859375, 34783.625, 34731.25390625, 34679.13671875,
34627.28125, 34575.69921875],
[ 34939.6328125, 34900.6171875, 34848.8359375, 34797.3046875,
34746.03125, 34695.01953125],
[ 35055.359375, 35016.7890625, 34965.6015625, 34914.6484375,
34863.953125, 34813.5234375],
[ 35170.2421875, 35132.125, 35081.5234375, 35031.1640625,
34981.046875, 34931.1875],
[ 35284.27734375, 35246.60546875, 35196.59765625, 35146.82421875,
35097.29296875, 35048.0078125]]
dya = [[ 34735.1328125, 34695.375, 34642.5625, 34590.0078125,
34537.7265625, 34485.7109375],
[ 34823.0859375, 34783.625, 34731.25390625, 34679.13671875,
34627.28125, 34575.69921875],
[ 34939.6328125, 34900.6171875, 34848.8359375, 34797.3046875,
34746.03125, 34695.01953125],
[ 35055.359375, 35016.7890625, 34965.6015625, 34914.6484375,
34863.953125, 34813.5234375],
[ 35170.2421875, 35132.125, 35081.5234375, 35031.1640625,
34981.046875, 34931.1875],
[ 35284.27734375, 35246.60546875, 35196.59765625, 35146.82421875,
35097.29296875, 35048.0078125 ]]
u = ndarray([6, 6], float32)
v = ndarray([6, 6], float32)
a = ndarray([6, 6], float32)
dx = ndarray([6, 6], float32)
dy = ndarray([6, 6], float32)
for i in range(0,6):
for j in range(0,6):
u[i,j] = ua[i][j]
v[i,j] = va[i][j]
a[i,j] = aa[i][j]
dx[i,j] = dxa[i][j]
dy[i,j] = dya[i][j]
res = execute(u, v, a, dx, dy)
print res[2].flatten()
print res[3].flatten()
#test()

View file

@ -19,15 +19,12 @@
### ###
## @file Negate.py ## @file Negate.py
import numpy import Vector
from Vector import execute as Vector
## ##
# Negates input # Negates input
def execute(input): def execute(input):
if type(input) == tuple: if type(input) == tuple:
u = -input[2] return Vector.componentTo(-input[0], -input[1])
v = -input[3]
return Vector(u,v)
else: else:
return -input return -input

View file

@ -50,8 +50,8 @@ import Vorticity
def execute(p_up, p_lo, o_up, o_lo, vector_up, vector_lo, dx, dy, coriolis): def execute(p_up, p_lo, o_up, o_lo, vector_up, vector_lo, dx, dy, coriolis):
"Calculate the isentropic potential vorticity through a layer." "Calculate the isentropic potential vorticity through a layer."
u_up, v_up = vector_up[2], vector_up[3] u_up, v_up = vector_up
u_lo, v_lo = vector_lo[2], vector_lo[3] u_lo, v_lo = vector_lo
# Calculate the absolute vorticity at each isentropic surface. # Calculate the absolute vorticity at each isentropic surface.

View file

@ -60,8 +60,8 @@ import Vorticity
def execute(t_up, t_lo, p_up, p_lo, vector_up, vector_lo, dx, dy, coriolis): def execute(t_up, t_lo, p_up, p_lo, vector_up, vector_lo, dx, dy, coriolis):
"" ""
u_up, v_up = vector_up[2], vector_up[3] u_up, v_up = vector_up
u_lo, v_lo = vector_lo[2], vector_lo[3] u_lo, v_lo = vector_lo
# Calculate the absolute vorticity at each isobaric surface. # Calculate the absolute vorticity at each isobaric surface.
avort1 = Vorticity.execute(u_up, v_up, coriolis, dx, dy) avort1 = Vorticity.execute(u_up, v_up, coriolis, dx, dy)
@ -70,8 +70,8 @@ def execute(t_up, t_lo, p_up, p_lo, vector_up, vector_lo, dx, dy, coriolis):
# Calculate the temperature gradient on each surface. # Calculate the temperature gradient on each surface.
grad_lo = Gradient.execute(t_lo, dx, dy) grad_lo = Gradient.execute(t_lo, dx, dy)
grad_up = Gradient.execute(t_up, dx, dy) grad_up = Gradient.execute(t_up, dx, dy)
dtdx1, dtdy1 = grad_lo[2], grad_lo[3] dtdx1, dtdy1 = grad_lo
dtdx2, dtdy2 = grad_up[2], grad_up[3] dtdx2, dtdy2 = grad_up
# Calculate difference arrays. # Calculate difference arrays.
dp = p_up - p_lo dp = p_up - p_lo
dt = t_up - t_lo dt = t_up - t_lo

View file

@ -19,9 +19,9 @@
## ##
from Add import execute as Add from Add import execute as Add
from Vector import execute as Vector from math import radians,cos,sin
from numpy import array from numpy import array,dot
from numpy import dot import Vector
def execute(*args): def execute(*args):
"""Rotate a vector """Rotate a vector
@ -39,54 +39,31 @@ def execute(*args):
return vectorTransformMatrix(args) return vectorTransformMatrix(args)
def rotateDegrees(args): def rotateDegrees(args):
v = args[0]
magnitude = args[0][0] r = radians(args[1])
direction = Add(args[0][1], args[1]) % 360 s = sin(r)
c = cos(r)
return Vector(magnitude, direction, True) return vectorTransformMatrix(v,c,-s,s,c)
def vectorTransformMatrix(args): def vectorTransformMatrix(args):
uComponent = args[0][2] uComponent,vComponent = args[0]
vComponent = args[0][3]
uComponentShape = uComponent.shape uComponentShape = uComponent.shape
vComponentShape = vComponent.shape vComponentShape = vComponent.shape
# in-place flatten the arrays # in-place flatten the arrays
uComponent.resize((uComponent.size,)) uComponent = uComponent.reshape((uComponent.size,))
vComponent.resize((vComponent.size,)) vComponent = vComponent.reshape((vComponent.size,))
vector = array([uComponent, vComponent]) vector = array([uComponent, vComponent])
transform = array([[args[1], args[2]], [args[3], args[4]]],dtype=uComponent.dtype) transform = array([[args[1], args[2]], [args[3], args[4]]],dtype=uComponent.dtype)
(u,v) = dot(transform, vector) u,v = dot(transform, vector)
# resize the arrays back to appropriate size # resize the arrays back to appropriate size
u.resize(uComponentShape) u.resize(uComponentShape)
v.resize(vComponentShape) v.resize(vComponentShape)
return Vector(u, v) return Vector.componentsTo(u, v)
def test():
from numpy import all
from numpy import array
try:
execute(1, 2, 3, 4);
raise Exception
except ValueError:
pass
(mag, dir, u, v) = execute((array([1., 2.]), array([90., 270.])), 180.)
if not(all(mag == array([1., 2.])) and all(dir == array([270., 90.]))):
raise Exception
(mag, dir, u, v) = execute((None, None, array([1., 3.]), array([2., 4.])), 3., 4., 5., 6.)
if not(all(u == array([11., 25.])) and all(v == array([17., 39.]))):
raise Exception
print "Rotate Test Complete"

View file

@ -1,36 +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.
##
import unittest
import numpy as np
import AdiabaticTemp
class TestAdiabaticTemp(unittest.TestCase):
def setup(self):
pass
def testExecute(self):
intemp = np.array([268.54, 270.5], dtype=np.float32)
inpres = np.array([770, 770], dtype=np.float32)
result = AdiabaticTemp.execute(intemp, inpres)
correct = np.array([278.37, 281.93], dtype=np.float32)
self.failUnless(np.allclose(result,correct, 0.01, 0.01), "result = " + repr(result))

View file

@ -1,93 +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.
##
import unittest
import numpy as np
import Advection
class TestAdvection(unittest.TestCase):
def setUp(self):
"""Set up arrays for calls to Advection.execute()."""
self.U = np.ones((5,5), dtype=np.float32)
self.V = np.ones_like(self.U);
self.Wind = (self.U,self.V)
self.Q = np.ones_like(self.U) * 0.5
self.dx = np.ones_like(self.U)
self.dy = np.ones_like(self.U)
def testOuterEdge(self):
"""Confirm that the outer edge is set to the invalid placeholder (1e37). """
vrtct = Advection.execute(self.Wind, self.Q, self.dx, self.dy)
self.assertEquals((5,5), vrtct.shape, "vrtct.shape")
self.assertEquals(np.float32, vrtct.dtype, "vrtct.dtype")
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==vrtct))
def testMiddleMath(self):
"""Test """
self.U[1,2] = 5
self.V[1,2] = 5
self.Q[3,2] = 0.8
vrtct = Advection.execute(self.Wind, self.Q, self.dx, self.dy)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 0, -0.15, 0, 1e37],
[1e37, -0.15, 0, 0.15, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==vrtct), "Advection is incorrect.\n" + repr(vrtct))
def testScalarDxDy(self):
"""Test Advection calculation when dx and dy are scalars instead of arrays."""
self.U[1,2] = 5
self.V[1,2] = 5
self.Q[3,2] = 0.8
vrtct = Advection.execute(self.Wind, self.Q, 0.1, 0.5)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 0, -1.5, 0, 1e37],
[1e37, -0.3, 0, 0.3, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==vrtct), "Advection is incorrect.\n" + repr(vrtct))
def testInvalidCell(self):
"""Test when a cell contains an invalid value."""
self.U[1,2] = 5
self.U[2,2] = 1e37
self.V[1,2] = 5
self.Q[3,2] = 0.8
vrtct = Advection.execute(self.Wind, self.Q, self.dx, self.dy)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 0, 1e37, 0, 1e37],
[1e37, -0.15, 0, 0.15, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==vrtct), "Advection is incorrect.\n" + repr(vrtct))
if "__main__" == __name__:
unittest.main()

View file

@ -1,142 +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.
##
import unittest
import numpy as np
import CompBy
class TestCompBy(unittest.TestCase):
"""Unit tests for CompBy function."""
def setUp(self):
"""Create arrays to use in calls to CompBy.execute()."""
self.U = np.ones((3,3), dtype=np.float32) * np.sqrt(2)
self.U[1,0] = np.sqrt(3)
self.V = np.ones((3,3), dtype=np.float32) * np.sqrt(2)
self.V[0,2] = -self.V[0,2]
self.Vector = (self.U, self.V)
self.ThU = np.ones((3,3), dtype=np.float32) * 0.1
self.ThU = np.cumsum(self.ThU, axis=0)
self.ThV = np.zeros((3,3), dtype=np.float32)
self.ThGrd = (self.ThU, self.ThV)
def testAngleZero(self):
"""Test with no rotation."""
comp = CompBy.execute(self.Vector, self.ThGrd, 0.0)
correctAnswer_U = np.ones((3,3), dtype=np.float32) * np.sqrt(2)
correctAnswer_U[1,0] = 1.73205078
correctAnswer_V = np.array([[0,0,0], [0,0,0], [0,0,0]], dtype=np.float32)
# check for correct answers.
if not np.all(correctAnswer_U==comp[0]):
self.fail(repr(comp))
if not np.all(correctAnswer_V==comp[1]):
self.fail(repr(comp))
def testAngle45(self):
"""Test with 45 degree rotation."""
comp = CompBy.execute(self.Vector, self.ThGrd, 45.0)
correctAnswer_U = np.zeros((3,3), dtype=np.float32)
correctAnswer_U[0,2] = np.sqrt(2)
correctAnswer_U[1,0] = 0.15891865
correctAnswer_V = np.zeros((3,3), dtype=np.float32)
correctAnswer_V[0,2] = -np.sqrt(2)
correctAnswer_V[1,0] = -0.15891865
# check for correct answers.
if not np.all(correctAnswer_U==comp[0]):
self.fail(repr(comp))
if not np.all(correctAnswer_V==comp[1]):
self.fail(repr(comp))
def testAngle90(self):
"""Test with rotation of 90 degrees."""
comp = CompBy.execute(self.Vector, self.ThGrd, 90.0)
correctAnswer_U = np.zeros((3,3), dtype=np.float32)
correctAnswer_V = np.ones((3,3), dtype=np.float32) * np.sqrt(2)
correctAnswer_V[0,2] = -np.sqrt(2)
# check for correct answers.
# note: We have to use allclose(a,b) instead of all(a==b) because of
# rounding errors in the degrees-to-radians conversion constant.
# Since this is the same constant used in the original Fortran code,
# the error should be identical.
if not np.allclose(correctAnswer_U,comp[0]):
self.fail(repr(comp))
if not np.all(correctAnswer_V==comp[1]):
self.fail(repr(comp))
def testAngle120(self):
"""Test angles above 90 but below 180."""
comp = CompBy.execute(self.Vector, self.ThGrd, 120.0)
correctAnswer_U = np.ones((3,3), dtype=np.float32) * 0.96592587
correctAnswer_U[0,2] = -0.25881901
correctAnswer_U[1,0] = 1.04538524
correctAnswer_U[2,:] = np.ones((1,3)) * 0.96592593
correctAnswer_V = np.ones((3,3), dtype=np.float32) * 1.67303264
correctAnswer_V[0,2] = -0.44828767
correctAnswer_V[1,0] = 1.81066024
correctAnswer_V[2,:] = np.ones((1,3)) * 1.67303276
# check for correct answers.
if not np.all(correctAnswer_U==comp[0]):
self.fail(repr(comp))
if not np.all(correctAnswer_V==comp[1]):
self.fail(repr(comp))
def testAngle225(self):
"""Test angles above 180 but below 1000."""
comp = CompBy.execute(self.Vector, self.ThGrd, 225.0)
correctAnswer_U = np.ones((3,3), dtype=np.float32) * np.sqrt(2)
correctAnswer_U[1,0] = 1.73205078
correctAnswer_V = np.array([[0,0,0], [0,0,0], [0,0,0]], dtype=np.float32)
# check for correct answers.
if not np.all(correctAnswer_U==comp[0]):
self.fail(repr(comp))
if not np.all(correctAnswer_V==comp[1]):
self.fail(repr(comp))
def testAngle2090(self):
"""Test with rotation of 2090 degrees."""
# 2000 portion should be stripped off, so values should be the same as testAngle90.
comp = CompBy.execute(self.Vector, self.ThGrd, 2090.0)
correctAnswer_U = np.zeros((3,3), dtype=np.float32)
correctAnswer_V = np.ones((3,3), dtype=np.float32) * np.sqrt(2)
correctAnswer_V[0,2] = -np.sqrt(2)
# check for correct answers.
# note: We have to use allclose(a,b) instead of all(a==b) because of
# rounding errors in the degrees-to-radians conversion constant.
# Since this is the same constant used in the original Fortran code,
# the error should be identical.
if not np.allclose(correctAnswer_U,comp[0]):
self.fail(repr(comp))
if not np.all(correctAnswer_V==comp[1]):
self.fail(repr(comp))
def testBigV(self):
"""Test with different ThGrd but no rotation."""
self.V = self.V + 8
comp = CompBy.execute(self.Vector, self.ThGrd, 0.0)
correctAnswer_U = np.ones((3,3), dtype=np.float32) * np.sqrt(2)
correctAnswer_U[1,0] = 1.73205078
correctAnswer_V = np.array([[0,0,0], [0,0,0], [0,0,0]], dtype=np.float32)
# check for correct answers.
if not np.all(correctAnswer_U==comp[0]):
self.fail(repr(comp))
if not np.all(correctAnswer_V==comp[1]):
self.fail(repr(comp))

View file

@ -1,58 +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.
###
import unittest
import numpy as np
import Deformation
##
# Unit test class for Deformation
class TestDeformation(unittest.TestCase):
def setUp(self):
self.U = np.ones((5,5), dtype=np.float32)
self.U += np.eye(5,5,0)
self.V = np.ones((5,5), dtype=np.float32)
self.V += np.eye(5,5,0).transpose()
self.Vector = (self.U, self.V)
self.dx = np.ones((5,5), dtype=np.float32)
self.dy = np.ones((5,5), dtype=np.float32)
def testExecute(self):
"Test basic results of execute method."
result = Deformation.execute(self.Vector, self.dx, self.dy)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 0, 1, 0, 1e37],
[1e37, 1, 0, 1, 1e37],
[1e37, 0, 1, 0, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.allclose(result, correctAnswer), "Wrong answers: " + repr(result))
def testMasked(self):
"Check that invalid data results in cells with ourNaN (1e37)"
self.Vector[1][1,1] = 1e37
result = Deformation.execute(self.Vector, self.dx, self.dy)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 0, 1e37, 0, 1e37],
[1e37, 1e37, 0, 1, 1e37],
[1e37, 0, 1, 0, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.allclose(result, correctAnswer), "Wrong answers: " + repr(result))

View file

@ -1,53 +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.
##
import unittest
import numpy as np
import Derivative
bad = 1e36
class TestDerivative(unittest.TestCase):
""
def setUp(self):
""
self.A0 = np.ones((3,3), dtype=np.float32)
self.A1 = np.array( range(9), dtype=np.float32).reshape((3,3))
self.A1 *= self.A1
self.A1 += self.A0
self.A0[0,1] = 1e37
self.A1[1,0] = 1e37
self.B0 = np.ones((3,3), dtype=np.float32) * 0.5
self.B1 = np.array( range(9), dtype=np.float32).reshape((3,3))
self.B1 += self.B0
self.B1[1,-1] = self.B0[1,-1]
self.B1[-1, 1] = 1e37
def testDerivative(self):
"Test the derivative function."
result = Derivative.execute(self.A0, self.A1, self.B0, self.B1)
correct = np.array([[1e37, 1e37, 2],
[1e37, 4, 1e37],
[ 6, 1e37, 8]], dtype=np.float32)
if not np.allclose(result, correct):
self.fail("Incorrect answer:" + repr(result))

View file

@ -1,98 +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.
##
import unittest
import numpy as np
import DgeoComps
from constants import bad
import nan
class TestDgeoComps(unittest.TestCase):
""
def failIfArraysDifferent(self, arr, arr_correct, arr_name):
if not np.allclose(arr, arr_correct, 0.01, 0.01):
failMsg = ""
if not arr.shape == arr_correct.shape:
failMsg += "%s.shape = " % (arr_name)
failMsg += arr.shape + "\n"
if not arr.dtype == arr_correct.dtype:
failMsg += "%s.dtype = " % (arr_name)
failMsg += arr.dtype + "\n"
if arr.shape==arr_correct.shape and \
arr.dtype==arr_correct.dtype:
for xidx in range(5):
for yidx in range(5):
if np.abs(arr[xidx,yidx]-arr_correct[xidx,yidx])>0.01:
failMsg += "%s[%d,%d] = %g" % (arr_name,xidx,yidx, arr[xidx,yidx])
failMsg += ", expected %g\n" % arr_correct[xidx,yidx]
self.fail(failMsg)
def setUp(self):
""
self.height = np.array(range(25), dtype=np.float32).reshape((5,5))
self.height[1,1] = 1e37
self.height = nan.nan_greater(self.height, bad, copy=False)
self.dx = np.ones((5,1)) * np.array([1,2,1,1,1], dtype=np.float32)
self.dy = np.ones((5,1)) * np.array([1,2,1,1,1], dtype=np.float32)
self.dy = self.dx.transpose()
pi = 3.1415927
self.coriolis = np.array(range(5), dtype=np.float32).reshape((5,1)) + 40
self.coriolis *= pi/180
self.coriolis = np.sin(self.coriolis) * 3.0 * np.ones((5,))
def testDgeoComps(self):
dugdx, dugdy, dvgdx, dvgdy = DgeoComps.execute(self.height, self.dx, self.dy, self.coriolis)
dugdx = nan.nan_filled(dugdx, 1e37)
dugdy = nan.nan_filled(dugdy, 1e37)
dvgdx = nan.nan_filled(dvgdx, 1e37)
dvgdy = nan.nan_filled(dvgdy, 1e37)
dugdx_correct = np.array([[ 1e37, 1e37, 1e37, 1e37, 1e37],
[ 1e37, -0.00, -0.00, -0.00, 1e37],
[ 1e37, -0.00, 1e37, -0.00, 1e37],
[ 1e37, -0.00, -0.00, -0.00, 1e37],
[ 1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
dugdy_correct = np.array([[ 1e37, 1e37, 1e37, 1e37, 1e37],
[ 1e37, 1e37, 1e37, -0.00, 1e37],
[ 1e37, 0.00, 0.00, -0.00, 1e37],
[ 1e37, -0.00, -0.00, -0.00, 1e37],
[ 1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
dvgdx_correct = np.array([[ 1e37, 1e37, 1e37, 1e37, 1e37],
[ 1e37, 1e37, 0, 0, 1e37],
[ 1e37, 1e37, 0, 0, 1e37],
[ 1e37, 0, 0, 0, 1e37],
[ 1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
dvgdy_correct = np.array([[ 1e37, 1e37, 1e37, 1e37, 1e37],
[ 1e37, 0.00, 0.00, 0.00, 1e37],
[ 1e37, 0.00, 1e37, 0.00, 1e37],
[ 1e37, 0.00, 0.00, 0.00, 1e37],
[ 1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failIfArraysDifferent(dugdx, dugdx_correct, "dugdx")
self.failIfArraysDifferent(dugdy, dugdy_correct, "dugdy")
self.failIfArraysDifferent(dvgdx, dvgdx_correct, "dvgdx")
self.failIfArraysDifferent(dvgdy, dvgdy_correct, "dvgdy")
if '__main__' == __name__:
unittest.main()

View file

@ -1,125 +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.
##
import unittest
import numpy as np
import Divergence
## Unit test for Divergence function.
class TestDivergence(unittest.TestCase):
"""Unit tests for the divergence function."""
def testOuterEdge(self):
"""Make sure Divergence.execute() fills the outer edge with
the "invalid" placeholder value (1e37)."""
U = np.ones((4,4), dtype=np.float32)
V = np.ones_like(U);
Wind = (U,V)
dx = np.ones_like(U)
dy = np.ones_like(U)
dvgnc = Divergence.execute(Wind,dx,dy)
self.assertEquals((4,4), dvgnc.shape, "dvgnc.shape")
self.assertEquals(np.float32, dvgnc.dtype, "dvgnc.dtype")
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37],
[1e37, 0, 0, 1e37],
[1e37, 0, 0, 1e37],
[1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==dvgnc), repr(dvgnc))
def testMiddleMath(self):
"""Confirm that the inner cells are calculated correctly."""
U = np.array([[1,1,1,1,1],
[1,1,5,1,1],
[1,1,1,1,1],
[1,1,1,1,1],
[1,1,1,1,1]], dtype=np.float32)
V = np.array([[1,1,1,1,1],
[1,1,5,1,1],
[1,1,1,1,1],
[1,1,1,1,1],
[1,1,1,1,1]], dtype=np.float32)
Wind = (U,V)
dx = np.ones_like(U);
dy = np.ones_like(U);
dvgnc = Divergence.execute(Wind,dx,dy)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 2, 0, -2, 1e37],
[1e37, 0, -2, 0, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==dvgnc), "Divergence is incorrect.\n" + repr(dvgnc))
def testScalarDxDy(self):
"""Confirm that the inner cells are calculated correctly
when dx and dy are scalars instead of arrays."""
U = np.array([[1,1,1,1,1],
[1,1,5,1,1],
[1,1,1,1,1],
[1,1,1,1,1],
[1,1,1,1,1]], dtype=np.float32)
V = np.array([[1,1,1,1,1],
[1,1,5,1,1],
[1,1,1,1,1],
[1,1,1,1,1],
[1,1,1,1,1]], dtype=np.float32)
Wind = (U,V)
dx = 1
dy = 1
dvgnc = Divergence.execute(Wind,dx,dy)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 2, 0, -2, 1e37],
[1e37, 0, -2, 0, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==dvgnc), "Divergence is incorrect.\n" + repr(dvgnc))
def testWithQ(self):
"""Confirm that the inner cells are calculated correctly when quan is provided."""
U = np.array([[1,1,1,1,1],
[1,1,5,1,1],
[1,1,1,1,1],
[1,1,1,1,1],
[1,1,1,1,1]], dtype=np.float32)
V = np.array([[1,1,1,1,1],
[1,1,5,1,1],
[1,1,1,1,1],
[1,1,1,1,1],
[1,1,1,1,1]], dtype=np.float32)
Wind = (U,V)
dx = np.ones_like(U);
dy = np.ones_like(U);
Q = np.array([[1,1,1,1,1],
[1,1,1,1,1],
[1,1,1,1,1],
[1,1,4,1,1],
[1,1,1,1,1]])
dvgnc = Divergence.execute(Wind,dx,dy,Q)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 2, 0, -2, 1e37],
[1e37, 0, -0.5, 0, 1e37],
[1e37, 1.5, 0, -1.5, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==dvgnc), "Divergence is incorrect.\n" + repr(dvgnc))
if "__main__" == __name__:
unittest.main()

View file

@ -1,59 +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.
##
import unittest
import numpy as np
import GeoWind
import time
class testGeoWind(unittest.TestCase):
def setUp(self):
self.Height = np.array( range(64), dtype=np.float32).reshape((8,8))
self.dx = np.ones((8,8), dtype=np.float32) * 0.5
self.dy = np.ones((8,8), dtype=np.float32) * 0.5
self.coriolis = np.cos( np.arange(0, 3.14159, 3.14159/8, dtype=np.float32))
self.coriolis = np.ones((8,1)) * self.coriolis
def testExecute(self):
result = GeoWind.execute(self.Height, self.dx, self.dy, self.coriolis)
correct_u = np.array([[ 1e37, 1e37, 1e37, 1e37, 1e37, 1e37, 1e37, 1e37],
[ 1e37, -21.23, -27.74, -51.25,-1.54e7, 51.25, 27.74, 1e37],
[ 1e37, -21.23, -27.74, -51.25,-1.54e7, 51.25, 27.74, 1e37],
[ 1e37, -21.23, -27.74, -51.25,-1.54e7, 51.25, 27.74, 1e37],
[ 1e37, -21.23, -27.74, -51.25,-1.54e7, 51.25, 27.74, 1e37],
[ 1e37, -21.23, -27.74, -51.25,-1.54e7, 51.25, 27.74, 1e37],
[ 1e37, -21.23, -27.74, -51.25,-1.54e7, 51.25, 27.74, 1e37],
[ 1e37, 1e37, 1e37, 1e37, 1e37, 1e37, 1e37, 1e37]],
dtype=np.float32)
correct_v = np.array([[ 1e37, 1e37, 1e37, 1e37, 1e37, 1e37, 1e37, 1e37],
[ 1e37, 169.82, 221.88, 409.98, 1.24e8,-409.99,-221.88, 1e37],
[ 1e37, 169.82, 221.88, 409.98, 1.24e8,-409.99,-221.88, 1e37],
[ 1e37, 169.82, 221.88, 409.98, 1.24e8,-409.99,-221.88, 1e37],
[ 1e37, 169.82, 221.88, 409.98, 1.24e8,-409.99,-221.88, 1e37],
[ 1e37, 169.82, 221.88, 409.98, 1.24e8,-409.99,-221.88, 1e37],
[ 1e37, 169.82, 221.88, 409.98, 1.24e8,-409.99,-221.88, 1e37],
[ 1e37, 1e37, 1e37, 1e37, 1e37, 1e37, 1e37, 1e37]],
dtype=np.float32)
if not np.allclose(result[0], correct_u, 0.01, 0.01):
self.fail("Wrong answer for u:" + repr(result[0]))
if not np.allclose(result[1], correct_v, 0.01, 0.01):
self.fail("Wrong answer for v:" + repr(result[1]))

View file

@ -1,64 +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.
##
import unittest
import numpy as np
import Gradient
class TestGradient(unittest.TestCase):
def setUp(self):
self.data = np.ones((5,5), dtype=np.float32) * 2.0
np.cumsum(self.data, axis=0, out=self.data)
np.cumsum(self.data, axis=1, out=self.data)
self.dx = np.ones((5,5), dtype=np.float32) * 0.5
self.dy = np.ones((5,5), dtype=np.float32) * 0.5
def testMath(self):
"Check that simple gradients match expectations."
grd_u, grd_v = Gradient.execute(self.data, self.dx, self.dy)
correct_u = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[ 4.0, 8.0, 12.0, 16.0, 20.0],
[ 4.0, 8.0, 12.0, 16.0, 20.0],
[ 4.0, 8.0, 12.0, 16.0, 20.0],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
correct_v = correct_u.transpose()
if not np.allclose(grd_u, correct_u):
self.fail("" + repr(grd_u));
if not np.allclose(grd_v, correct_v):
self.fail("" + repr(grd_v))
def testClean(self):
"Check that input arrays are not modified."
self.data[1,1] = 1e37
self.dx[1,1] = 1e37
self.dy[1,1] = 1e37
dataCopy = np.copy(self.data)
dxCopy = np.copy(self.dx)
dyCopy = np.copy(self.dy)
dontcare_u, dontcare_v = Gradient.execute(self.data, self.dx, self.dy)
if not np.allclose(self.data, dataCopy):
fail("Data was changed.")
if not np.allclose(self.dx, dxCopy):
fail("dx was changed.")
if not np.allclose(self.dy, dyCopy):
fail("dy was changed.")

View file

@ -1,51 +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.
##
import unittest
import numpy as np
import IsenStability
class TestIsenStability(unittest.TestCase):
"Unit test for IsenStability function."
def setUp(self):
self.p_up = np.array(range(9), dtype=np.float32).reshape((3,3)) + 900
self.p_lo = self.p_up + np.array(range(9), dtype=np.float32).reshape((3,3)) * 10
self.o_up = 2.1
self.o_lo = 0.1
def testMath(self):
"Test that correct answer is obtained."
result = IsenStability.execute(self.p_up, self.p_lo, self.o_up, self.o_lo)
correct = np.array(range(9), dtype=np.float32).reshape((3,3)) * 5
correct[0,0] = 5.0
if not np.allclose(result, correct):
self.fail("Incorrect result:" + repr(result))
def testInvalid(self):
"Test that invalid inputs result in invalid outputs."
self.p_up[2,2] = 1e37
result = IsenStability.execute(self.p_up, self.p_lo, self.o_up, self.o_lo)
correct = np.array([[5, 5, 10],
[15, 20, 25],
[30, 35, 1e37]], dtype=np.float32)
correct[0,0] = 5.0
if not np.allclose(result, correct):
self.fail("Incorrect result:" + repr(result))

View file

@ -1,52 +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.
##
import unittest
import numpy as np
import Laplacian
class TestLaplacian(unittest.TestCase):
def setUp(self):
self.Q = np.ones((5,5), dtype=np.float32) * 1.5
self.Q += np.eye(5, 5, 0, dtype=self.Q.dtype) * 0.25
self.dx = np.ones(np.shape(self.Q), dtype=self.Q.dtype)
self.dy = np.ones(np.shape(self.Q), dtype=self.Q.dtype)
def testMath(self):
"Test basic Laplacian math function."
answer = Laplacian.execute(self.Q, self.dx, self.dy)
correctAnswer = np.array([[1e37,1e37,1e37,1e37,1e37],
[1e37,-1,0.5,0,1e37],
[1e37,0.5,-1,0.5,1e37],
[1e37,0, 0.5, -1,1e37],
[1e37,1e37,1e37,1e37,1e37]], dtype=self.Q.dtype)
self.failUnless(np.all(correctAnswer==answer), "Laplacian was incorrect. " + repr(answer))
def testInvalidCell(self):
"Test whether invalid cells are handled properly."
self.Q[1,1] = 1e37
answer = Laplacian.execute(self.Q, self.dx, self.dy)
correctAnswer = np.array([[1e37,1e37,1e37,1e37,1e37],
[1e37,1e37,1e37,0,1e37],
[1e37,1e37,-1,0.5,1e37],
[1e37,0, 0.5, -1,1e37],
[1e37,1e37,1e37,1e37,1e37]], dtype=self.Q.dtype)
self.failUnless(np.all(correctAnswer==answer), "Laplacian was incorrect. " + repr(answer))

View file

@ -1,64 +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.
##
import unittest
import numpy as np
import LiftedIndex
class TestLiftedIndex(unittest.TestCase):
def setUp(self):
self.P = np.array([600, 700, 800, 900], dtype=np.float32)
self.T = np.array([250, 275, 290, 300], dtype=np.float32)
self.RH = np.array([30, 40, 50, 60], dtype=np.float32)
self.P_500MB = 500.0
self.T_500MB = np.array([290, 280, 270, 260], dtype=np.float32)
def testLiftedIndex(self):
"Test simple operation on 4 data points with P_500MB a scalar."
result = LiftedIndex.execute(self.P, self.T, self.RH, self.T_500MB, self.P_500MB)
correct = np.array([52.701, 27.634, 6.831, -12.093], dtype=np.float32)
if not np.allclose(result, correct, .001, .001):
self.fail("Wrong answer:"+ repr(result))
def testMaskedPValue(self):
self.P[2] = 1e37
result = LiftedIndex.execute(self.P, self.T, self.RH, self.T_500MB, self.P_500MB)
correct = np.array([52.701, 27.634, 1e37, -12.093], dtype=np.float32)
if not np.allclose(result, correct, .001, .001):
self.fail("Wrong answer:"+ repr(result))
def testBadTValue(self):
self.T[2] = 32.0
result = LiftedIndex.execute(self.P, self.T, self.RH, self.T_500MB, self.P_500MB)
correct = np.array([52.701, 27.634, 1e37, -12.093], dtype=np.float32)
if not np.allclose(result, correct, .001, .001):
self.fail("Wrong answer:"+ repr(result))
def testBlackHoleValue(self):
self.P = np.array([1008.18,1013.2], dtype=np.float32)
self.T = np.array([302.02026,299.95776], dtype=np.float32)
self.RH = np.array([88.98621,79.98621], dtype=np.float32)
self.T_500MB = np.array([284.5984,284.3484], dtype=np.float32)
self.P_500MB = 700
result = LiftedIndex.execute(self.P, self.T, self.RH, self.T_500MB, self.P_500MB)
correct = np.array([-3.70840454, 0.28149414], dtype=np.float32)
if not np.allclose(result, correct, .001, .001):
self.fail("Wrong answer:"+ repr(result))

View file

@ -1,74 +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.
##
import unittest
import numpy as np
import PartialDerivative as Partial
class TestPartialDerivative(unittest.TestCase):
""
def failIfArraysDifferent(self, arr, arr_correct, arr_name):
failMsg = ""
if not arr.shape == arr_correct.shape:
failMsg += "%s.shape = " % (arr_name)
failMsg += arr.shape + "\n"
if not arr.dtype == arr_correct.dtype:
failMsg += "%s.dtype = " % (arr_name)
failMsg += arr.dtype + "\n"
if arr.shape==arr_correct.shape and \
arr.dtype==arr_correct.dtype:
for xidx in range(arr.shape[0]):
for yidx in range(arr.shape[1]):
if np.abs(arr[xidx,yidx]-arr_correct[xidx,yidx])<=0.01:
pass
elif np.isnan(arr[xidx,yidx]) and np.isnan(arr_correct[xidx,yidx]):
pass
else:
failMsg += "%s[%d,%d] = %g" % (arr_name,xidx,yidx, np.ma.filled(arr[xidx,yidx], np.NaN ) )
failMsg += ", expected %g\n" % np.ma.filled(arr_correct[xidx,yidx], np.NaN)
if "" != failMsg:
self.fail(failMsg)
def setUp(self):
self.Qarr = np.array( range(25), dtype=np.float32).reshape((5,5))
self.dx = np.ones((5,5), dtype=np.float32)
self.dx[2,:] = 2
self.dy = np.ones((5,5), dtype=np.float32)
self.dy[:,3] = 2
def testExecute(self):
""
dQdx, dQdy = Partial.calculate(self.Qarr, self.dx, self.dy)
dQdx_correct = np.array([[np.NaN, np.NaN, np.NaN, np.NaN, np.NaN],
[np.NaN, 5, 5, 5, np.NaN],
[np.NaN, 2.50, 2.50, 2.50, np.NaN],
[np.NaN, 5, 5, 5, np.NaN],
[np.NaN, np.NaN, np.NaN, np.NaN, np.NaN]],
dtype=np.float32)
self.failIfArraysDifferent(dQdx, dQdx_correct, "dQdx")
dQdy_correct = np.ma.array([[np.NaN, np.NaN, np.NaN, np.NaN, np.NaN],
[np.NaN, 1, 1, 0.5, np.NaN],
[np.NaN, 1, 1, 0.5, np.NaN],
[np.NaN, 1, 1, 0.5, np.NaN],
[np.NaN, np.NaN, np.NaN, np.NaN, np.NaN]],
dtype=np.float32)
self.failIfArraysDifferent(dQdy, dQdy_correct, "dQdy")

View file

@ -1,70 +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.
##
import unittest
import numpy as np
import PotVortK
class TestPotVortK(unittest.TestCase):
"Unit test class for PotVortK function."
def setUp(self):
self.p_lo = np.ones((5,5), dtype=np.float32) * 900.0
self.p_up = self.p_lo + 100.0
self.o_up = 285.0
self.o_lo = 283.0
self.u_lo = np.ones_like(self.p_lo) * 4.0
self.v_lo = np.ones_like(self.p_lo) * 3.0
self.Wind_lo = (self.u_lo, self.v_lo)
self.u_up = self.u_lo + 1.0
self.v_up = self.v_lo + 1.0
self.Wind_up = (self.u_up, self.v_up)
self.dx = np.ones_like(self.p_lo)
self.dy = np.ones_like(self.p_lo)
self.coriolis = np.ones_like(self.p_lo) * np.sqrt(2)
def testMath(self):
"Test basic operation."
result = PotVortK.execute(self.p_up, self.p_lo, self.o_up, self.o_lo,
self.Wind_up, self.Wind_lo,
self.dx, self.dy, self.coriolis)
ansr = 2.82842696e-01 # obtained from early test run
correct = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, ansr, ansr, ansr, 1e37],
[1e37, ansr, ansr, ansr, 1e37],
[1e37, ansr, ansr, ansr, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
if not np.allclose(correct, result):
self.fail("Incorrect value:" + repr(result))
def testMasked(self):
"Send invalid input and make sure output reflects it."
self.p_up[1,1] = 1e37
result = PotVortK.execute(self.p_up, self.p_lo, self.o_up, self.o_lo,
self.Wind_up, self.Wind_lo,
self.dx, self.dy, self.coriolis)
ansr = 2.82842696e-01 # obtained from early test run
correct = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 1e37, ansr, ansr, 1e37],
[1e37, ansr, ansr, ansr, 1e37],
[1e37, ansr, ansr, ansr, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
if not np.allclose(correct, result):
self.fail("Incorrect value:" + repr(result))

View file

@ -1,75 +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.
##
import unittest
import numpy as np
import PotVortMB
class TestPotVortMB(unittest.TestCase):
def setUp(self):
self.t_lo = np.ones((5,5), dtype=np.float32) * 273.15
self.t_up = self.t_lo + 12.5
self.p_lo = np.ones_like(self.t_lo) * 900.0
self.p_up = self.p_lo + 100.0
self.u_lo = np.ones_like(self.t_lo) * 4.0
self.v_lo = np.ones_like(self.t_lo) * 3.0
self.Wind_lo = (self.u_lo, self.v_lo)
self.u_up = self.u_lo + 1.0
self.v_up = self.v_lo + 1.0
self.Wind_up = (self.u_up, self.v_up)
self.dx = np.ones_like(self.t_lo)
self.dy = np.ones_like(self.t_lo)
self.coriolis = np.ones_like(self.t_lo) * np.sqrt(2)
def testMath(self):
"Test simplest operation."
result = PotVortMB.execute(self.t_up, self.t_lo, self.p_up, self.p_lo,
self.Wind_up, self.Wind_lo,
self.dx, self.dy, self.coriolis)
av = 2.82842707634
ansr = -0.5 * (av*12.5 + 1.0*0.0 - 1.0*0.0) / 100
correct = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, ansr, ansr, ansr, 1e37],
[1e37, ansr, ansr, ansr, 1e37],
[1e37, ansr, ansr, ansr, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
if not np.allclose(correct, result):
self.fail("Incorrect result:" + repr(result))
def testMasked(self):
"Test that function doesn't crash when an input cell is ourNaN."
self.t_up[1,1] = 1e37
result = PotVortMB.execute(self.t_up, self.t_lo, self.p_up, self.p_lo,
self.Wind_up, self.Wind_lo,
self.dx, self.dy, self.coriolis)
av = 2.82842707634
ansr = -0.5 * (av*12.5 + 1.0*0.0 - 1.0*0.0) / 100
correct = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 1e37, 1e37, ansr, 1e37],
[1e37, 1e37, ansr, ansr, 1e37],
[1e37, ansr, ansr, ansr, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
if not np.allclose(correct, result):
self.fail("Incorrect result:" + repr(result))

View file

@ -1,50 +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.
##
import unittest
import numpy as np
import TempOfTe
class TestTempOfTe(unittest.TestCase):
def setUp(self):
pass
def testExecute(self):
'Test operation for 2x1 and 1x2 inputs.'
# This test's arrays are small enough to follow easily in the debugger.
temp = np.array( range(260,315,50), dtype=np.float32)
temp.resize((len(temp),1))
pressure = np.array( range(700,800, 50), dtype=np.float32)
result = TempOfTe.execute(temp, pressure)
correct = np.array( [[256.05, 256.26],[281.49, 282.18]], dtype=np.float32)
if not np.allclose(result, correct, 0.01, 0.01):
self.fail("Wrong answer:" + repr(result))
def testOuterLimits(self):
""
temp = np.array([100.0, 192.0, 193.0, 194.0, 332.0, 333.0, 334.0], dtype=np.float32)
pressure = np.array([730, 730, 730, 730, 730, 730, 730], dtype=np.float32)
result = TempOfTe.execute(temp, pressure)
correct = np.array([100.0, 192.0, 193.0, 194.0, 288.0, 288.0, 1e37], dtype=np.float32)
if not np.allclose(result, correct, 0.01, 0.01):
self.fail("Wrong answer:" + repr(result))

View file

@ -1,78 +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.
##
import unittest
import numpy as np
import Vorticity
class TestVorticity(unittest.TestCase):
def setUp(self):
"""Set up arrays for calls to Vorticity.execute()."""
self.U = np.ones((5,5), dtype=np.float32)
self.V = np.ones_like(self.U);
self.Wind = (self.U,self.V)
self.Q = np.ones_like(self.U) * 0.5
self.dx = np.ones_like(self.U)
self.dy = np.ones_like(self.U)
def testOuterEdge(self):
"""Confirm that the outer edge is set to the invalid placeholder (1e37). """
vrtct = Vorticity.execute(self.Wind, 0, self.dx, self.dy)
self.assertEquals((5,5), vrtct.shape, "vrtct.shape")
self.assertEquals(np.float32, vrtct.dtype, "vrtct.dtype")
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==vrtct))
def testMiddleMath(self):
"""Test """
self.U[1,2] = 5
self.V[1,2] = 5
self.Q[3,2] = 0.8
vrtct = Vorticity.execute(self.Wind, self.Q, self.dx, self.dy)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, -1.5, 0.5, 2.5, 1e37],
[1e37, 0.5, -1.5, 0.5, 1e37],
[1e37, 0.5, 0.8, 0.5, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==vrtct), "Vorticity is incorrect.\n" + repr(vrtct))
def testScalarDxDy(self):
"""Test Vorticity calculation when dx and dy are scalars instead of arrays."""
self.U[1,2] = 5
self.V[1,2] = 5
self.Q[3,2] = 0.8
vrtct = Vorticity.execute(self.Wind, self.Q, 0.1, 0.5)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, -3.5, 0.5, 4.5, 1e37],
[1e37, 0.5, -19.5, 0.5, 1e37],
[1e37, 0.5, 0.8, 0.5, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==vrtct), "Vorticity is incorrect.\n" + repr(vrtct))
if "__main__" == __name__:
unittest.main()

View file

@ -1,78 +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.
##
import unittest
import numpy as np
import VorticityAdv
class TestVorticityAdv(unittest.TestCase):
def setUp(self):
"""Set up arrays for calls to Vorticity.execute()."""
self.U = np.ones((5,5), dtype=np.float32)
self.V = np.ones_like(self.U);
self.Wind = (self.U,self.V)
self.Q = np.ones_like(self.U) * 0.5
self.dx = np.ones_like(self.U)
self.dy = np.ones_like(self.U)
def testOuterEdge(self):
"""Confirm that the outer edge is set to the invalid placeholder (1e37). """
vrtcta = VorticityAdv.execute(self.Wind, self.Q, self.dx, self.dy)
self.assertEquals((5,5), vrtcta.shape, "vrtcta.shape")
self.assertEquals(np.float32, vrtcta.dtype, "vrtcta.dtype")
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 0, 0, 0, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==vrtcta))
def testMiddleMath(self):
"""Test """
self.U[1,2] = 5
self.V[1,2] = 5
self.Q[3,2] = 0.8
vrtcta = VorticityAdv.execute(self.Wind, self.Q, self.dx, self.dy)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 4.0, 0, 4.0, 1e37],
[1e37, 0, -4.15, 0, 1e37],
[1e37, -0.15, 0, 0.15, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==vrtcta), "VorticityAdv is incorrect.\n" + repr(vrtcta))
def testScalarDxDy(self):
"""Test Vorticity calculation when dx and dy are scalars instead of arrays."""
self.U[1,2] = 5
self.V[1,2] = 5
self.Q[3,2] = 0.8
vrtcta = VorticityAdv.execute(self.Wind, self.Q, 0.1, 0.5)
correctAnswer = np.array([[1e37, 1e37, 1e37, 1e37, 1e37],
[1e37, 80, 0, 80, 1e37],
[1e37, 0, -81.5, 0, 1e37],
[1e37, -0.3, 0, 0.3, 1e37],
[1e37, 1e37, 1e37, 1e37, 1e37]], dtype=np.float32)
self.failUnless(np.all(correctAnswer==vrtcta), "VorticityAdv is incorrect.\n" + repr(vrtcta))
if "__main__" == __name__:
unittest.main()

View file

@ -27,27 +27,21 @@ from numpy import radians
from numpy import abs from numpy import abs
from numpy import isscalar, empty, float32 from numpy import isscalar, empty, float32
def execute(u, v, legacyOption=None): def execute(u, v, magDir=None):
""" Make a vector from u,v or mag, dir. """ Make a vector from u,v or mag, dir.
@param legacyOption @param magDir
controls how the function operates on the given u and v values. controls how the function operates on the given u and v values.
When the legacyOption is specified and is a constant scalar value When the magDir is specified and is a constant scalar value
the u and v input values are assumed to be speed and direction. the u and v input values are assumed to be speed and direction.
positive :: assume meteorological direction positive :: assume meteorological direction(direction from)
negative :: assume mathematical direction negative :: assume mathematical direction(direction to)
abs(legacyOption) == 1 :: assume degrees abs(legacyOption) == 1 :: assume direction in degrees
abs(legacyOption) != 1 :: assume radians abs(legacyOption) != 1 :: assume direction in radians
abs(legacyOption) == 1 || 2 :: assume first two args are speed and @return: tuple of (u,v)
direction
Otherwise if the legacy option is not a constant, the first two
inputs are components that determine the direction, and the third
is the speed to use.
@return: tuple of (magnitude,direction,u,v)
""" """
# If either u or v is a single number, expand it to match an entire Grid # If either u or v is a single number, expand it to match an entire Grid
@ -61,161 +55,35 @@ def execute(u, v, legacyOption=None):
tmp.fill(v) tmp.fill(v)
v = tmp v = tmp
# These will be parsed by legacy opts if magDir == None:
polar=False return componentsTo(u, v)
mathematicalDirection=False elif magDir == 1:
useRadians=False return magDirDegreesFrom(u, v);
speed = None elif magDir == -1:
return magDirDegreesTo(u, v);
# Handle the crazy legacy options elif magDir >= 0:
if legacyOption != None: return magDirRadiansFrom(u, v);
if type(legacyOption) == float:
mathematicalDirection = legacyOption < 0
useRadians = abs(legacyOption) != 1
polar = abs(legacyOption) == 1 or abs(legacyOption) == 2
elif type(legacyOption) == bool:
polar = legacyOption
else: else:
speed = legacyOption return magDirRadiansTo(u, v);
completeRevolution = 360 if not useRadians else radians(360.0) def componentsTo(u,v):
return (u, v)
if (polar): def magDirRadiansTo(mag, dir):
mag = u u = sin(dir) * mag
dir = v v = cos(dir) * mag
return componentsTo(u,v)
# replace all negative angles with their corresponding positive values def magDirDegreesTo(mag, dir):
negDirMask = dir < 0 return magDirRadiansTo(mag, radians(dir))
dir[negDirMask] = (- dir[negDirMask]) % completeRevolution
dir[negDirMask] = completeRevolution - dir[negDirMask]
dir[dir > completeRevolution] %= completeRevolution def componentsFrom(u,v):
theta = radians(dir) if not useRadians else dir return componentsTo(-u,-v)
u = mag * sin(theta)
v = mag * cos(theta)
else:
u = - u if not mathematicalDirection else u
v = - v if not mathematicalDirection else v
mag = 0 if speed != None else hypot(u, v)
theta = arctan2(u, v)
dir = degrees(theta) if not useRadians else theta
dir[dir < 0] += completeRevolution
u = - u if not mathematicalDirection else u def magDirRadiansFrom(mag, dir):
v = - v if not mathematicalDirection else v u = sin(dir) * mag
v = cos(dir) * mag
return componentFrom(u,v)
dir[dir == completeRevolution] = 0 def magDirDegreesFrom(mag, dir):
return magDirRadiansFrom(mag, radians(dir))
if speed == None:
return (mag, dir, u, v)
else:
return execute(speed,dir,polar=True)
def test():
from numpy import array
angles = array([0., 45., 90., 135., 180., 225., 270., 315., 360., - 675., 405.])
magnitudes = angles.copy()
magnitudes[:] = 2
targetDir = array([0., 45., 90., 135., 180., 225., 270., 315., 0., 45., 45.])
targetU = array([ 0., 1.41, 2., 1.41, 0., - 1.41, - 2., - 1.41, - 0., 1.41, 1.41])
targetV = array([ 2., 1.41, 0., - 1.41, - 2., - 1.41, 0., 1.41, 2., 1.41, 1.41])
# perform regular mathematical vector tests
(mag, dir, u, v) = execute(magnitudes, angles, polar=True, mathematicalDirection=True)
if not (all(dir == targetDir) and all(u.round(2) == targetU) and all(v.round(2) == targetV)):
print dir
print targetDir
print u.round(2)
print targetU
print v.round(2)
print targetV
raise Exception
(mag, dir, u, v) = execute(u, v, mathematicalDirection=True)
if not (all(dir.round(0) == targetDir) and all(mag == magnitudes)):
raise Exception
# perform meteorological vector tests
(mag,dir,u,v) = execute(mag,dir,polar=True)
if not (all(mag == magnitudes) and
all(dir.round(0) == targetDir) and
all(u.round(2) == -targetU) and
all(v.round(2) == -targetV)):
print mag
print magnitudes
print mag == magnitudes
print dir
print targetDir
print dir == targetDir
print -u.round(2)
print targetU
print u.round(2) == -targetU
print -v.round(2)
print targetV
print v.round(2) == -targetV
raise Exception
(mag,dir,u,v) = execute(u,v)
if not (all(mag == magnitudes) and
all(dir.round(0) == targetDir) and
all(u.round(2) == -targetU) and
all(v.round(2) == -targetV)):
print mag
print magnitudes
print mag == magnitudes
print dir
print targetDir
print dir.round(0) == targetDir
print u.round(2)
print -targetU
print u.round(2) == -targetU
print v.round(2)
print -targetV
print v.round(2) == -targetV
raise Exception
# make sure the goofy legacy option works as expected
(mag,dir,u,v) = execute(mag,dir,1.0)
if not(all(u.round(2) == -targetU) and
all(v.round(2) == -targetV) and
all(mag == magnitudes) and
all(dir.round(0) == targetDir)):
raise Exception
(mag,dir,u,v) = execute(mag,dir,-1.0)
if not(all(u.round(2) == targetU) and
all(v.round(2) == targetV) and
all(mag == magnitudes) and
all(dir.round(0) == targetDir)):
print mag,dir,u,v
raise Exception
otherMag = magnitudes.copy()
otherMag[:] = 7
(mag,dir,u,v) = execute(-targetU,-targetV,otherMag)
if not(u.round(2)[0] == 0 and
v.round(2)[0] == -7 and
all(mag == otherMag) and
all(dir.round(0) == targetDir)):
print u.round(2)[0] == 0
print v.round(2)[0] == -7
print mag == otherMag
print dir.round(0)
print targetDir
print dir.round(0) == targetDir
raise Exception
print "Vector Test Complete"

View file

@ -1,75 +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.uf.viz.derivparam.python;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "com.raytheon.uf.viz.derivparam.python";
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
* )
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
* )
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
}

View file

@ -2,30 +2,23 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2 Bundle-ManifestVersion: 2
Bundle-Name: Derived Parameter Plug-in Bundle-Name: Derived Parameter Plug-in
Bundle-SymbolicName: com.raytheon.uf.viz.derivparam;singleton:=true Bundle-SymbolicName: com.raytheon.uf.viz.derivparam;singleton:=true
Bundle-Version: 1.12.1174.qualifier Bundle-Version: 1.14.0.qualifier
Bundle-Activator: com.raytheon.uf.viz.derivparam.Activator
Bundle-Vendor: RAYTHEON Bundle-Vendor: RAYTHEON
Require-Bundle: org.eclipse.core.runtime,
javax.measure,
com.raytheon.uf.viz.core;bundle-version="1.12.1174",
com.raytheon.uf.common.datastorage;bundle-version="1.12.1174",
com.raytheon.uf.common.pointdata;bundle-version="1.12.1174",
com.raytheon.uf.common.dataplugin.level;bundle-version="1.12.1174",
com.raytheon.uf.common.util;bundle-version="1.12.1174"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization Require-Bundle: com.raytheon.uf.common.derivparam,
Import-Package: com.raytheon.uf.common.comm,
com.raytheon.uf.common.dataplugin,
com.raytheon.uf.common.derivparam.tree,
com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.localization,
com.raytheon.uf.common.serialization,
com.raytheon.uf.common.serialization.adapters,
com.raytheon.uf.common.status,
com.raytheon.uf.common.time, com.raytheon.uf.common.time,
com.vividsolutions.jts.geom, com.raytheon.uf.common.dataplugin.level,
org.opengis.referencing.crs com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.dataplugin,
com.raytheon.uf.common.datastorage,
com.raytheon.uf.common.pointdata;bundle-version="1.13.0",
com.raytheon.uf.viz.core;bundle-version="1.13.0",
com.raytheon.uf.common.util,
com.raytheon.uf.common.comm,
org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.ui.workbench;bundle-version="3.8.0",
javax.measure
Export-Package: com.raytheon.uf.viz.derivparam, Export-Package: com.raytheon.uf.viz.derivparam,
com.raytheon.uf.viz.derivparam.data, com.raytheon.uf.viz.derivparam.data,
com.raytheon.uf.viz.derivparam.inv, com.raytheon.uf.viz.derivparam.inv,

View file

@ -18,9 +18,9 @@
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
further_licensing_information. further_licensing_information.
--> -->
<DerivedParameter abbreviation="FeatMot" name="Feature Motion" unit="kt"> <DerivedParameter abbreviation="FeatMot" name="Feature Motion" unit="kn">
<Method name="Vector"> <Method name="Vector">
<Field abbreviation="USTM"/> <Field abbreviation="USTM" unit="kn"/>
<Field abbreviation="VSTM"/> <Field abbreviation="VSTM" unit="kn"/>
</Method> </Method>
</DerivedParameter> </DerivedParameter>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DerivedParameter unit="m/s" name="Wind Gust" abbreviation="Gust" xmlns:ns2="group"> <DerivedParameter unit="m/s" name="Wind Gust" abbreviation="Gust" xmlns:ns2="group">
<Method name="Vector" levels="Surface" models="obs"> <Method name="Vector" levels="Surface" models="obs">
<Field level="Station" abbreviation="windGust"/> <Field level="Station" abbreviation="windGust" unit="m/s"/>
<Field abbreviation="WD" unit="deg"/> <Field abbreviation="WD" unit="deg"/>
<ConstantField value="1.0"/> <ConstantField value="1.0"/>
</Method> </Method>
@ -19,9 +19,4 @@
<Field abbreviation="WD" unit="deg"/> <Field abbreviation="WD" unit="deg"/>
<ConstantField value="1.0"/> <ConstantField value="1.0"/>
</Method> </Method>
<Method name="Vector">
<Field abbreviation="uW"/>
<Field abbreviation="vW"/>
<Field abbreviation="WGS" unit="m/s"/>
</Method>
</DerivedParameter> </DerivedParameter>

View file

@ -23,8 +23,8 @@
<Field abbreviation="DMD"/> <Field abbreviation="DMD"/>
</Method> </Method>
<Method name="Vector"> <Method name="Vector">
<Field abbreviation="USTM"/> <Field abbreviation="USTM" unit="kn"/>
<Field abbreviation="VSTM"/> <Field abbreviation="VSTM" unit="kn"/>
</Method> </Method>
<Method levels="Layer" name="Rotate"> <Method levels="Layer" name="Rotate">
<Field level="0-6kmAgl" abbreviation="Wind"/> <Field level="0-6kmAgl" abbreviation="Wind"/>

View file

@ -23,11 +23,11 @@
<Field abbreviation="Windmean"/> <Field abbreviation="Windmean"/>
</Method> </Method>
<Method name="Vector"> <Method name="Vector">
<Field abbreviation="uW"/> <Field abbreviation="uW" unit="m/s"/>
<Field abbreviation="vW"/> <Field abbreviation="vW" unit="m/s"/>
</Method> </Method>
<Method name="Vector"> <Method name="Vector">
<Field abbreviation="wSp"/> <Field abbreviation="wSp" unit="m/s"/>
<Field abbreviation="WD" unit="deg"/> <Field abbreviation="WD" unit="deg"/>
<ConstantField value="1.0"/> <ConstantField value="1.0"/>
</Method> </Method>

View file

@ -18,13 +18,13 @@
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
further_licensing_information. further_licensing_information.
--> -->
<DerivedParameter abbreviation="Windmean" name="Mean Wind" unit="kt"> <DerivedParameter abbreviation="Windmean" name="Mean Wind" unit="kn">
<Method name="Vector"> <Method name="Vector">
<Field abbreviation="uWmean" unit="kts"/> <Field abbreviation="uWmean" unit="kn"/>
<Field abbreviation="vWmean" unit="kts"/> <Field abbreviation="vWmean" unit="kn"/>
</Method> </Method>
<Method name="Vector"> <Method name="Vector">
<Field abbreviation="WSmean" unit="kts"/> <Field abbreviation="WSmean" unit="kn"/>
<Field abbreviation="WDmean" unit="deg"/> <Field abbreviation="WDmean" unit="deg"/>
<ConstantField value="1.0"/> <ConstantField value="1.0"/>
</Method> </Method>

View file

@ -1,57 +0,0 @@
package com.raytheon.uf.viz.derivparam;
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;
import com.raytheon.uf.viz.derivparam.library.DerivedParameterGenerator;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends Plugin {
// The plug-in ID
public static final String PLUGIN_ID = "com.raytheon.uf.common.derivparam";
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
DerivedParameterGenerator.shutdown();
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
}

View file

@ -39,8 +39,9 @@ import com.raytheon.uf.viz.core.exception.VizException;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Jan 15, 2010 #3965 rjpeter Initial creation * Jan 15, 2010 3965 rjpeter Initial creation
* Jan 14, 2014 2661 bsteffen Make vectors u,v only
* *
* </pre> * </pre>
* *
@ -73,15 +74,12 @@ public class AliasRequestableData extends AbstractRequestableData {
} }
} else if (rval instanceof FloatDataRecord[]) { } else if (rval instanceof FloatDataRecord[]) {
FloatDataRecord[] recs = (FloatDataRecord[]) rval; FloatDataRecord[] recs = (FloatDataRecord[]) rval;
FloatDataRecord[] newRecs = new FloatDataRecord[recs.length]; IDataRecord[] newRecs = new FloatDataRecord[recs.length];
rval = newRecs; rval = newRecs;
for (int i = 0; i < recs.length; i++) { for (int i = 0; i < recs.length; i++) {
if (recs[i] instanceof FloatDataRecord) { newRecs[i] = recs[i].clone();
newRecs[i] = (FloatDataRecord) ((FloatDataRecord) recs[i])
.clone();
if (this.parameter != null) { if (this.parameter != null) {
((FloatDataRecord) newRecs[i]).setName(this.parameter); newRecs[i].setName(this.parameter);
}
} }
} }
} else if (rval instanceof IDataRecord[]) { } else if (rval instanceof IDataRecord[]) {
@ -89,11 +87,9 @@ public class AliasRequestableData extends AbstractRequestableData {
IDataRecord[] newRecs = new IDataRecord[recs.length]; IDataRecord[] newRecs = new IDataRecord[recs.length];
rval = newRecs; rval = newRecs;
for (int i = 0; i < recs.length; i++) { for (int i = 0; i < recs.length; i++) {
if (recs[i] instanceof IDataRecord) { newRecs[i] = recs[i].clone();
newRecs[i] = ((IDataRecord) recs[i]).clone();
if (this.parameter != null) { if (this.parameter != null) {
((IDataRecord) newRecs[i]).setName(this.parameter); newRecs[i].setName(this.parameter);
}
} }
} }
} }
@ -118,17 +114,7 @@ public class AliasRequestableData extends AbstractRequestableData {
FloatDataRecord[] recs = (FloatDataRecord[]) rval; FloatDataRecord[] recs = (FloatDataRecord[]) rval;
if (recs.length != 1 || !unit.equals(NonSI.DEGREE_ANGLE)) { if (recs.length != 1 || !unit.equals(NonSI.DEGREE_ANGLE)) {
for (int i = 0; i < recs.length; i++) { for (int i = 0; i < recs.length; i++) {
// Currently arrays are only used for Vectors, float[] data = recs[i].getFloatData();
// Vectors
// are represented as [Mag,Dir,U,V], If we attempt
// to
// convert Dir it goes badly, so this skips it.
if (i == 1) {
continue;
}
if (recs[i] instanceof FloatDataRecord) {
float[] data = ((FloatDataRecord) recs[i])
.getFloatData();
for (int c = 0; c < data.length; c++) { for (int c = 0; c < data.length; c++) {
if (data[c] > -9999) { if (data[c] > -9999) {
data[c] = (float) converter data[c] = (float) converter
@ -137,25 +123,15 @@ public class AliasRequestableData extends AbstractRequestableData {
} }
} }
} }
}
} else if (rval instanceof IDataRecord[]) { } else if (rval instanceof IDataRecord[]) {
IDataRecord[] recs = (IDataRecord[]) rval; IDataRecord[] recs = (IDataRecord[]) rval;
if (recs.length != 1 || !unit.equals(NonSI.DEGREE_ANGLE)) { if (recs.length != 1 || !unit.equals(NonSI.DEGREE_ANGLE)) {
for (int i = 0; i < recs.length; i++) { for (int i = 0; i < recs.length; i++) {
// Currently arrays are only used for Vectors,
// Vectors
// are represented as [Mag,Dir,U,V], If we attempt
// to
// convert Dir it goes badly, so this skips it.
if (i == 1) {
continue;
}
if (recs[i] instanceof FloatDataRecord) { if (recs[i] instanceof FloatDataRecord) {
float[] data = ((FloatDataRecord) recs[i]) float[] data = ((FloatDataRecord) recs[i])
.getFloatData(); .getFloatData();
for (int c = 0; c < data.length; c++) { for (int c = 0; c < data.length; c++) {
if (data[c] > -9999) { if (data[c] > -9999) {
data[c] = (float) converter data[c] = (float) converter
.convert(data[c]); .convert(data[c]);
} }

View file

@ -42,10 +42,12 @@ import com.raytheon.uf.viz.derivparam.tree.CubeLevel;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Mar 17, 2010 bsteffen Initial creation * Mar 17, 2010 bsteffen Initial creation
* Jun 04, 2013 2041 bsteffen Switch derived parameters to use * Jun 04, 2013 2041 bsteffen Switch derived parameters to use
* concurrent python for threading. * concurrent python for threading.
* Jan 14, 2014 2661 bsteffen Make vectors u,v only
*
* *
* </pre> * </pre>
* *
@ -80,14 +82,14 @@ public class DerivedRequestableData extends AbstractRequestableData {
List<IDataRecord> finalResult = DerivedParameterGenerator List<IDataRecord> finalResult = DerivedParameterGenerator
.calculate(request); .calculate(request);
if (finalResult != null && !finalResult.isEmpty()) { if (finalResult != null && !finalResult.isEmpty()) {
if (finalResult.size() == 4 || finalResult.size() == 1) { if (finalResult.size() == 2 || finalResult.size() == 1) {
for (IDataRecord rec : finalResult) { for (IDataRecord rec : finalResult) {
rec.setName(request.getParameterAbbreviation()); rec.setName(request.getParameterAbbreviation());
} }
return finalResult.toArray(new IDataRecord[0]); return finalResult.toArray(new IDataRecord[0]);
} else { } else {
throw new VizException( throw new VizException(
"Error processing derived parameter, expecting scalar or vector data. Vector data must return speed, dir, u, and v components."); "Error processing derived parameter, expecting scalar or vector data. Vector data must return u and v components.");
} }
} }
} catch (ExecutionException e) { } catch (ExecutionException e) {

View file

@ -24,8 +24,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import com.raytheon.uf.common.serialization.ISerializableObject;
/** /**
* Metadata about a derived parameter field. * Metadata about a derived parameter field.
* *
@ -35,8 +33,10 @@ import com.raytheon.uf.common.serialization.ISerializableObject;
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* 11/21/2009 #3576 rjpeter Initial version * Nov 21, 2009 3576 rjpeter Initial version
* Jan 14, 2014 2661 bsteffen Remove ISerializableObject
*
* </pre> * </pre>
* *
* @author rjpeter * @author rjpeter
@ -44,8 +44,7 @@ import com.raytheon.uf.common.serialization.ISerializableObject;
*/ */
@XmlAccessorType(XmlAccessType.NONE) @XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement @XmlRootElement
public class DerivParamConstantField implements ISerializableObject, public class DerivParamConstantField implements IDerivParamField {
IDerivParamField {
@XmlAttribute(required = true) @XmlAttribute(required = true)
private Float value; private Float value;

View file

@ -30,7 +30,6 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.raytheon.uf.common.serialization.ISerializableObject;
import com.raytheon.uf.common.serialization.adapters.UnitAdapter; import com.raytheon.uf.common.serialization.adapters.UnitAdapter;
import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
@ -45,8 +44,10 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* 11/21/2009 #3576 rjpeter Initial version * Nov 21, 2009 3576 rjpeter Initial version
* Jan 14, 2014 2661 bsteffen Remove ISerializableObject
*
* </pre> * </pre>
* *
* @author rjpeter * @author rjpeter
@ -54,7 +55,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
*/ */
@XmlAccessorType(XmlAccessType.NONE) @XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "DerivedParameter") @XmlRootElement(name = "DerivedParameter")
public class DerivParamDesc implements ISerializableObject { public class DerivParamDesc {
private static final transient IUFStatusHandler statusHandler = UFStatus private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(DerivParamDesc.class); .getHandler(DerivParamDesc.class);

View file

@ -29,7 +29,6 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.raytheon.uf.common.dataplugin.level.mapping.LevelMapping; import com.raytheon.uf.common.dataplugin.level.mapping.LevelMapping;
import com.raytheon.uf.common.dataplugin.level.mapping.LevelMappingFactory; import com.raytheon.uf.common.dataplugin.level.mapping.LevelMappingFactory;
import com.raytheon.uf.common.serialization.ISerializableObject;
import com.raytheon.uf.common.serialization.adapters.UnitAdapter; import com.raytheon.uf.common.serialization.adapters.UnitAdapter;
import com.raytheon.uf.viz.core.exception.VizCommunicationException; import com.raytheon.uf.viz.core.exception.VizCommunicationException;
@ -42,8 +41,10 @@ import com.raytheon.uf.viz.core.exception.VizCommunicationException;
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* 11/21/2009 #3576 rjpeter Initial version * Nov 21, 2009 3576 rjpeter Initial version
* Jan 14, 2014 2661 bsteffen Remove ISerializableObject
*
* </pre> * </pre>
* *
* @author rjpeter * @author rjpeter
@ -51,7 +52,7 @@ import com.raytheon.uf.viz.core.exception.VizCommunicationException;
*/ */
@XmlAccessorType(XmlAccessType.NONE) @XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement @XmlRootElement
public class DerivParamField implements ISerializableObject, IDerivParamField { public class DerivParamField implements IDerivParamField {
@XmlAttribute(name = "abbreviation", required = true) @XmlAttribute(name = "abbreviation", required = true)
private String param; private String param;

View file

@ -34,7 +34,6 @@ import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlTransient;
import com.raytheon.uf.common.dataplugin.level.Level; import com.raytheon.uf.common.dataplugin.level.Level;
import com.raytheon.uf.common.serialization.ISerializableObject;
import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
@ -50,8 +49,10 @@ import com.raytheon.uf.viz.core.exception.VizException;
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* 11/21/2009 #3576 rjpeter Initial version * Nov 21, 2009 3576 rjpeter Initial version
* Jan 14, 2014 2661 bsteffen Remove ISerializableObject
*
* </pre> * </pre>
* *
* @author rjpeter * @author rjpeter
@ -59,7 +60,7 @@ import com.raytheon.uf.viz.core.exception.VizException;
*/ */
@XmlAccessorType(XmlAccessType.NONE) @XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement @XmlRootElement
public class DerivParamMethod implements ISerializableObject { public class DerivParamMethod {
private static final transient IUFStatusHandler statusHandler = UFStatus private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(DerivParamMethod.class); .getHandler(DerivParamMethod.class);

View file

@ -42,6 +42,7 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.ui.services.IDisposable;
import com.raytheon.uf.common.datastorage.records.IDataRecord; import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.localization.FileUpdatedMessage; import com.raytheon.uf.common.localization.FileUpdatedMessage;
@ -55,29 +56,21 @@ import com.raytheon.uf.common.serialization.JAXBManager;
import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.Activator;
import com.raytheon.uf.viz.derivparam.DerivParamFunctionType; import com.raytheon.uf.viz.derivparam.DerivParamFunctionType;
import com.raytheon.uf.viz.derivparam.IDerivParamFunctionAdapter; import com.raytheon.uf.viz.derivparam.IDerivParamFunctionAdapter;
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod.MethodType; import com.raytheon.uf.viz.derivparam.library.DerivParamMethod.MethodType;
/** /**
* A thread that accepts requests for a derived parameter, passes it to JEP and * Primary public interface for derived parameters. Introspection on the derived
* returns the request. It is important to note that this thread performs a * parameters available can be done using {@link #getDerParLibrary()}. For
* sleep instead of a schedule to keep the JEP instance in the same thread. To * actually performing derived parameters calculations the
* properly interact with this thread, it is important to use * {@link #calculate(DerivedParameterRequest)} method can be used.
* <code>DerivedParameterRequest</code> and submit it using the static method
* <code>addTask</code>.<br/>
* <br/>
* <b>IMPORTANT</b> A call to <code>getDerivParamLib</code> should be made
* immediately after an instance of the datacube container is created or after a
* call to <code>requestDerivParamUpdate</code>. The reason for this is the main
* thread will load all derived parameters and then offer them via a synchronous
* queue. Until the queue is polled, the main derived parameter thread will
* hang.
* *
* <pre> * <pre>
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Jul 03, 2008 brockwoo Initial creation * Jul 03, 2008 brockwoo Initial creation
* Nov 16, 2009 3120 rjpeter Removed use of LevelNameMappingFile. * Nov 16, 2009 3120 rjpeter Removed use of LevelNameMappingFile.
* Nov 20, 2009 3387 jelkins Use derived script's variableId instead * Nov 20, 2009 3387 jelkins Use derived script's variableId instead
@ -86,6 +79,8 @@ import com.raytheon.uf.viz.derivparam.library.DerivParamMethod.MethodType;
* Jun 04, 2013 2041 bsteffen Switch derived parameters to use * Jun 04, 2013 2041 bsteffen Switch derived parameters to use
* concurrent python for threading. * concurrent python for threading.
* Nov 19, 2013 2361 njensen Only shutdown if initialized * Nov 19, 2013 2361 njensen Only shutdown if initialized
* Jan 14, 2014 2661 bsteffen Shutdown using uf.viz.core.Activator
*
* </pre> * </pre>
* *
* @author brockwoo * @author brockwoo
@ -201,6 +196,13 @@ public class DerivedParameterGenerator implements ILocalizationFileObserver {
"Error creating derived parameter function type," "Error creating derived parameter function type,"
+ " derived paramters will not be available"); + " derived paramters will not be available");
} }
Activator.getDefault().registerDisposable(new IDisposable() {
@Override
public void dispose() {
shutdown();
}
});
this.adapter = functionTypes[0].getAdapter(); this.adapter = functionTypes[0].getAdapter();
this.extension = functionTypes[0].getExtension(); this.extension = functionTypes[0].getExtension();
notifyJob.setSystem(true); notifyJob.setSystem(true);
@ -251,8 +253,8 @@ public class DerivedParameterGenerator implements ILocalizationFileObserver {
for (LocalizationFile file : xmlFiles) { for (LocalizationFile file : xmlFiles) {
try { try {
DerivParamDesc desc = (DerivParamDesc) jaxbMan DerivParamDesc desc = jaxbMan.unmarshalFromXmlFile(
.unmarshalFromXmlFile(file.getFile()); DerivParamDesc.class, file.getFile());
if (derParLibrary.containsKey(desc.getAbbreviation())) { if (derParLibrary.containsKey(desc.getAbbreviation())) {
DerivParamDesc oldDesc = derParLibrary.get(desc DerivParamDesc oldDesc = derParLibrary.get(desc
.getAbbreviation()); .getAbbreviation());
@ -330,9 +332,10 @@ public class DerivedParameterGenerator implements ILocalizationFileObserver {
initLibrary(); initLibrary();
} }
public static void shutdown() { public static synchronized void shutdown() {
if (instance != null) { if (instance != null) {
getInstance().adapter.shutdown(); getInstance().adapter.shutdown();
instance = null;
} }
} }

View file

@ -50,8 +50,10 @@ import com.raytheon.uf.viz.core.exception.VizCommunicationException;
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* 11/21/2009 #3576 rjpeter Initial version * Nov 21, 2009 3576 rjpeter Initial version
* Jan 14, 2014 2661 bsteffen Remove unnecessary exceptions
*
* *
* &#064;author rjpeter * &#064;author rjpeter
* @version 1.0 * @version 1.0
@ -149,8 +151,7 @@ public class ValidLevelGenerator {
return validLevels; return validLevels;
} }
private void processLevelToken(String token) private void processLevelToken(String token) throws CommunicationException {
throws VizCommunicationException, CommunicationException {
boolean negate = token.charAt(0) == '!'; boolean negate = token.charAt(0) == '!';
int rangeIndex = token.indexOf('>'); int rangeIndex = token.indexOf('>');
@ -341,8 +342,7 @@ public class ValidLevelGenerator {
} }
} }
private Type determineType(String token) throws CommunicationException, private Type determineType(String token) throws CommunicationException {
VizCommunicationException {
Type rval = null; Type rval = null;
LevelMapping mapping = lmf.getLevelMappingForKey(token); LevelMapping mapping = lmf.getLevelMappingForKey(token);

View file

@ -27,6 +27,8 @@ import org.geotools.referencing.GeodeticCalculator;
import com.raytheon.uf.common.geospatial.MapUtil; import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate; import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper;
import com.raytheon.uf.viz.core.IExtent; import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget; import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle;
@ -50,7 +52,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------- -------- ----------- -------------------------- * ------------- -------- ----------- -----------------------------------------
* Jun 22, 2010 bsteffen Initial creation * Jun 22, 2010 bsteffen Initial creation
* Feb 07, 2011 7948 bkowal added a public method to get the * Feb 07, 2011 7948 bkowal added a public method to get the
* direction. * direction.
@ -62,11 +64,14 @@ import com.vividsolutions.jts.geom.Coordinate;
* gridRelative flag to indicate whether * gridRelative flag to indicate whether
* direction data is relative to grid or * direction data is relative to grid or
* true north * true north
* Sep 09, 2013 16257 MPorricelli When setDestinationGeographicPoint fails (which can * Sep 09, 2013 16257 MPorricelli When setDestinationGeographicPoint fails
* happen for global lat/lon grid winds displayed on * (which can happen for global lat/lon grid
* Equidistant Cylindrical map) try again with different * winds displayed on Equidistant
* Cylindrical map) try again with different
* pixel location. * pixel location.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options. * Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* Jan 14, 2014 2661 bsteffen Switch magnitude and direction from
* buffers to DataSource
* *
* </pre> * </pre>
* *
@ -75,9 +80,9 @@ import com.vividsolutions.jts.geom.Coordinate;
*/ */
public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> { public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
private final FloatBuffer magnitude; private final DataSource magnitude;
private final FloatBuffer direction; private final DataSource direction;
private int lineWidth; private int lineWidth;
@ -96,20 +101,26 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
private GeodeticCalculator gc; private GeodeticCalculator gc;
/** /**
*
* @param magnitude * @param magnitude
* a data source for the magnitude of vectors
* @param direction * @param direction
* a data source for the direction of vectors
* @param descriptor * @param descriptor
* the descriptor
* @param gridGeometryOfGrid * @param gridGeometryOfGrid
* @param size * geometry of the data sources
* @param densityFactor * @param densityFactor
* adjustment factor to make density match A1 * adjustment factor to make density match A1
* @param gridRelative * @param gridRelative
* true if direction is grid relative, false if relative to true * true if direction is grid relative, false if relative to true
* north * north
* @param displayType * @param displayType
* @param factory * how to render the vector
* @param config
* custom rendering hints
*/ */
public GriddedVectorDisplay(FloatBuffer magnitude, FloatBuffer direction, public GriddedVectorDisplay(DataSource magnitude, DataSource direction,
IMapDescriptor descriptor, GeneralGridGeometry gridGeometryOfGrid, IMapDescriptor descriptor, GeneralGridGeometry gridGeometryOfGrid,
double densityFactor, boolean gridRelative, double densityFactor, boolean gridRelative,
DisplayType displayType, VectorGraphicsConfig config) { DisplayType displayType, VectorGraphicsConfig config) {
@ -123,6 +134,21 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
this.vectorConfig = config; this.vectorConfig = config;
} }
/**
* Construct using float buffers instead of data sources.
*
* @See {@link #GriddedVectorDisplay(DataSource, DataSource, IMapDescriptor, GeneralGridGeometry, double, boolean, DisplayType, VectorGraphicsConfig)}
*/
public GriddedVectorDisplay(FloatBuffer magnitude, FloatBuffer direction,
IMapDescriptor descriptor, GeneralGridGeometry gridGeometryOfGrid,
double densityFactor, boolean gridRelative,
DisplayType displayType, VectorGraphicsConfig config) {
this(new FloatBufferWrapper(magnitude, gridGeometryOfGrid),
new FloatBufferWrapper(direction, gridGeometryOfGrid),
descriptor, gridGeometryOfGrid, densityFactor, gridRelative,
displayType, config);
}
@Override @Override
public void paint(IGraphicsTarget target, PaintProperties paintProps) public void paint(IGraphicsTarget target, PaintProperties paintProps)
throws VizException { throws VizException {
@ -151,17 +177,18 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
@Override @Override
protected void paint(Coordinate ijcoord, PaintProperties paintProps, protected void paint(Coordinate ijcoord, PaintProperties paintProps,
Coordinate plotLoc, double adjSize) throws VizException { Coordinate plotLoc, double adjSize) throws VizException {
int idx = (int) (ijcoord.x + (ijcoord.y * this.gridDims[0]));
float spd = this.magnitude.get(idx); double spd = this.magnitude.getDataValue((int) ijcoord.x,
float dir = this.direction.get(idx); (int) ijcoord.y);
double dir = this.direction.getDataValue((int) ijcoord.x,
(int) ijcoord.y);
if (dir < -999999 || dir > 9999999) { if (dir < -999999 || dir > 9999999) {
// perhaps this check should limit +/- 180 // perhaps this check should limit +/- 180
return; return;
} }
if (Float.isNaN(spd) || Float.isNaN(dir)) { if (Double.isNaN(spd) || Double.isNaN(dir)) {
return; return;
} }
int tryDiffPixLoc = 0; int tryDiffPixLoc = 0;
@ -269,17 +296,6 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
return false; return false;
} }
/**
* @return the magnitude
*/
public FloatBuffer getMagnitude() {
return magnitude;
}
public FloatBuffer getDirection() {
return direction;
}
@Override @Override
protected void disposeResources() { protected void disposeResources() {
if (vectorRenderable != null) { if (vectorRenderable != null) {

View file

@ -105,7 +105,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------- -------- ----------- -------------------------- * ------------- -------- ----------- -----------------------------------------
* Mar 09, 2011 bsteffen Initial creation * Mar 09, 2011 bsteffen Initial creation
* May 08, 2013 1980 bsteffen Set paint status in GridResources for * May 08, 2013 1980 bsteffen Set paint status in GridResources for
* KML. * KML.
@ -113,8 +113,12 @@ import com.vividsolutions.jts.geom.Coordinate;
* Aug 27, 2013 2287 randerso Added new parameters required by * Aug 27, 2013 2287 randerso Added new parameters required by
* GriddedVectorDisplay and * GriddedVectorDisplay and
* GriddedIconDisplay * GriddedIconDisplay
* Sep 24, 2013 2404 bclement colormap params now created using match criteria * Sep 24, 2013 2404 bclement colormap params now created using match
* criteria
* Sep 23, 2013 2363 bsteffen Add more vector configuration options. * Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* Jan 14, 2014 2594 bsteffen Switch vector mag/dir to use data source
* instead of raw float data.
*
* *
* </pre> * </pre>
* *
@ -525,7 +529,7 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
} }
} }
GriddedVectorDisplay vectorDisplay = new GriddedVectorDisplay( GriddedVectorDisplay vectorDisplay = new GriddedVectorDisplay(
data.getMagnitude(), data.getDirection(), descriptor, data.getMagnitude(), data.getDirectionFrom(), descriptor,
gridGeometry, VECTOR_DENSITY_FACTOR, true, displayType, gridGeometry, VECTOR_DENSITY_FACTOR, true, displayType,
config); config);
vectorDisplay.setColor(getCapability(ColorableCapability.class) vectorDisplay.setColor(getCapability(ColorableCapability.class)
@ -844,8 +848,13 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
"Error transforming coordinate for interrogate", e); "Error transforming coordinate for interrogate", e);
} }
Interpolation interpolation = getInspectInterpolation(data); Interpolation interpolation = getInspectInterpolation(data);
GridSampler sampler = new GridSampler(new FloatBufferWrapper( GridSampler sampler = null;
if (data.isVector()) {
sampler = new GridSampler(data.getMagnitude(), interpolation);
} else {
sampler = new GridSampler(new FloatBufferWrapper(
data.getScalarData(), data.getGridGeometry()), interpolation); data.getScalarData(), data.getGridGeometry()), interpolation);
}
double value = sampler.sample(pixel.x, pixel.y); double value = sampler.sample(pixel.x, pixel.y);
if (Double.isNaN(value)) { if (Double.isNaN(value)) {
return null; return null;
@ -872,8 +881,7 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
result.put(INTERROGATE_UNIT, ""); result.put(INTERROGATE_UNIT, "");
} }
if (data.isVector()) { if (data.isVector()) {
sampler.setSource(new FloatBufferWrapper(data.getDirection(), data sampler.setSource(data.getDirectionFrom());
.getGridGeometry()));
Double dir = sampler.sample(pixel.x, pixel.y); Double dir = sampler.sample(pixel.x, pixel.y);
result.put(INTERROGATE_DIRECTION, dir); result.put(INTERROGATE_DIRECTION, dir);
} }

View file

@ -42,6 +42,7 @@ import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.GridSampler; import com.raytheon.uf.common.geospatial.interpolation.GridSampler;
import com.raytheon.uf.common.geospatial.interpolation.Interpolation; import com.raytheon.uf.common.geospatial.interpolation.Interpolation;
import com.raytheon.uf.common.geospatial.interpolation.PrecomputedGridReprojection; import com.raytheon.uf.common.geospatial.interpolation.PrecomputedGridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper; import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper; import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper;
import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Coordinate;
@ -56,11 +57,14 @@ import com.vividsolutions.jts.geom.Coordinate;
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- -----------------------------------------
* Mar 09, 2011 bsteffen Initial creation * Mar 09, 2011 bsteffen Initial creation
* Jul 17, 2013 2185 bsteffen Cache computed grid reprojections. * Jul 17, 2013 2185 bsteffen Cache computed grid reprojections.
* Aug 27, 2013 2287 randerso Removed 180 degree adjustment required by error * Aug 27, 2013 2287 randerso Removed 180 degree adjustment required by
* in Maputil.rotation * error in Maputil.rotation
* Jan 14, 2014 2661 bsteffen For vectors only keep uComponent and
* vComponent, calculate magnitude and
* direction on demand.
* *
* </pre> * </pre>
* *
@ -71,13 +75,11 @@ public class GeneralGridData {
private GridGeometry2D gridGeometry; private GridGeometry2D gridGeometry;
private FloatBuffer scalarData; private FloatBufferWrapper scalarData;
private FloatBuffer direction = null; private FloatBufferWrapper uComponent = null;
private FloatBuffer uComponent = null; private FloatBufferWrapper vComponent = null;
private FloatBuffer vComponent = null;
private Unit<?> dataUnit; private Unit<?> dataUnit;
@ -100,18 +102,16 @@ public class GeneralGridData {
* used when both these representations are readily available to save time * used when both these representations are readily available to save time
* if one or the other is needed later. * if one or the other is needed later.
* *
* @param magnitude * @deprecated Magnitude and direction are ignored, use
* @param direction * {@link #createVectorDataUV(GeneralGridGeometry, FloatBuffer, FloatBuffer, Unit)}
* @param uComponent
* @param vComponent
* @param dataUnit
* @return
*/ */
@Deprecated
@SuppressWarnings("unused")
public static GeneralGridData createVectorData( public static GeneralGridData createVectorData(
GeneralGridGeometry gridGeometry, FloatBuffer magnitude, GeneralGridGeometry gridGeometry, FloatBuffer magnitude,
FloatBuffer direction, FloatBuffer uComponent, FloatBuffer direction, FloatBuffer uComponent,
FloatBuffer vComponent, Unit<?> dataUnit) { FloatBuffer vComponent, Unit<?> dataUnit) {
return new GeneralGridData(gridGeometry, magnitude, direction, return new GeneralGridData(gridGeometry,
uComponent, vComponent, dataUnit); uComponent, vComponent, dataUnit);
} }
@ -127,8 +127,17 @@ public class GeneralGridData {
public static GeneralGridData createVectorData( public static GeneralGridData createVectorData(
GeneralGridGeometry gridGeometry, FloatBuffer magnitude, GeneralGridGeometry gridGeometry, FloatBuffer magnitude,
FloatBuffer direction, Unit<?> dataUnit) { FloatBuffer direction, Unit<?> dataUnit) {
return new GeneralGridData(gridGeometry, magnitude, direction, null, magnitude.rewind();
null, dataUnit); direction.rewind();
FloatBuffer vComponent = FloatBuffer.allocate(magnitude.capacity());
FloatBuffer uComponent = FloatBuffer.allocate(magnitude.capacity());
while (magnitude.hasRemaining()) {
double angle = Math.toRadians(direction.get());
vComponent.put((float) (Math.cos(angle) * magnitude.get()));
uComponent.put((float) (Math.sin(angle) * magnitude.get()));
}
return new GeneralGridData(gridGeometry, uComponent, vComponent,
dataUnit);
} }
/** /**
@ -143,25 +152,23 @@ public class GeneralGridData {
public static GeneralGridData createVectorDataUV( public static GeneralGridData createVectorDataUV(
GeneralGridGeometry gridGeometry, FloatBuffer uComponent, GeneralGridGeometry gridGeometry, FloatBuffer uComponent,
FloatBuffer vComponent, Unit<?> dataUnit) { FloatBuffer vComponent, Unit<?> dataUnit) {
return new GeneralGridData(gridGeometry, null, null, uComponent, return new GeneralGridData(gridGeometry, uComponent,
vComponent, dataUnit); vComponent, dataUnit);
} }
private GeneralGridData(GeneralGridGeometry gridGeometry, private GeneralGridData(GeneralGridGeometry gridGeometry,
FloatBuffer scalarData, Unit<?> dataUnit) { FloatBuffer scalarData, Unit<?> dataUnit) {
this.gridGeometry = GridGeometry2D.wrap(gridGeometry); this.gridGeometry = GridGeometry2D.wrap(gridGeometry);
this.scalarData = scalarData; this.scalarData = new FloatBufferWrapper(scalarData, this.gridGeometry);
;
this.dataUnit = dataUnit; this.dataUnit = dataUnit;
} }
private GeneralGridData(GeneralGridGeometry gridGeometry, private GeneralGridData(GeneralGridGeometry gridGeometry,
FloatBuffer magnitude, FloatBuffer direction,
FloatBuffer uComponent, FloatBuffer vComponent, Unit<?> dataUnit) { FloatBuffer uComponent, FloatBuffer vComponent, Unit<?> dataUnit) {
this.gridGeometry = GridGeometry2D.wrap(gridGeometry); this.gridGeometry = GridGeometry2D.wrap(gridGeometry);
this.scalarData = magnitude; this.uComponent = new FloatBufferWrapper(uComponent, this.gridGeometry);
this.direction = direction; this.vComponent = new FloatBufferWrapper(vComponent, this.gridGeometry);
this.uComponent = uComponent;
this.vComponent = vComponent;
this.dataUnit = dataUnit; this.dataUnit = dataUnit;
} }
@ -187,31 +194,34 @@ public class GeneralGridData {
return true; return true;
} }
if (scalarData != null) { if (scalarData != null) {
scalarData.rewind(); FloatBuffer oldData = scalarData.getBuffer();
FloatBuffer newData = FloatBuffer.allocate(scalarData.capacity()); oldData.rewind();
while (scalarData.hasRemaining()) { FloatBuffer newData = FloatBuffer.allocate(oldData.capacity());
newData.put((float) converter.convert(scalarData.get())); while (oldData.hasRemaining()) {
newData.put((float) converter.convert(oldData.get()));
} }
newData.rewind(); newData.rewind();
scalarData = newData; scalarData = new FloatBufferWrapper(newData, gridGeometry);
} }
if (uComponent != null) { if (uComponent != null) {
uComponent.rewind(); FloatBuffer oldData = uComponent.getBuffer();
FloatBuffer newData = FloatBuffer.allocate(uComponent.capacity()); oldData.rewind();
while (uComponent.hasRemaining()) { FloatBuffer newData = FloatBuffer.allocate(oldData.capacity());
newData.put((float) converter.convert(uComponent.get())); while (oldData.hasRemaining()) {
newData.put((float) converter.convert(oldData.get()));
} }
newData.rewind(); newData.rewind();
uComponent = newData; uComponent = new FloatBufferWrapper(newData, gridGeometry);
} }
if (vComponent != null) { if (vComponent != null) {
vComponent.rewind(); FloatBuffer oldData = vComponent.getBuffer();
FloatBuffer newData = FloatBuffer.allocate(vComponent.capacity()); oldData.rewind();
while (vComponent.hasRemaining()) { FloatBuffer newData = FloatBuffer.allocate(oldData.capacity());
newData.put((float) converter.convert(vComponent.get())); while (oldData.hasRemaining()) {
newData.put((float) converter.convert(oldData.get()));
} }
newData.rewind(); newData.rewind();
vComponent = newData; vComponent = new FloatBufferWrapper(newData, gridGeometry);
} }
dataUnit = unit; dataUnit = unit;
return true; return true;
@ -278,76 +288,56 @@ public class GeneralGridData {
} }
public boolean isVector() { public boolean isVector() {
return (scalarData != null && direction != null) return (uComponent != null && vComponent != null);
|| (uComponent != null && vComponent != null);
} }
public FloatBuffer getMagnitude() { public DataSource getMagnitude() {
if (scalarData == null && uComponent != null && vComponent != null) { return new MagnitudeDataSource(uComponent, vComponent);
uComponent.rewind();
vComponent.rewind();
scalarData = FloatBuffer.allocate(uComponent.capacity());
while (vComponent.hasRemaining()) {
scalarData.put((float) Math.hypot(uComponent.get(),
vComponent.get()));
}
uComponent.rewind();
vComponent.rewind();
scalarData.rewind();
}
return scalarData;
} }
public FloatBuffer getScalarData() { public FloatBuffer getScalarData() {
return getMagnitude(); if (isVector()) {
FloatBufferWrapper tmp = new FloatBufferWrapper(gridGeometry);
DataSource mag = getMagnitude();
int w = gridGeometry.getGridRange2D().width;
int h = gridGeometry.getGridRange2D().height;
for (int i = 0; i < w; i += 1) {
for (int j = 0; j < h; j += 1) {
tmp.setDataValue(mag.getDataValue(i, j), i, j);
}
}
return tmp.getBuffer();
} else {
return scalarData.getBuffer();
}
} }
public FloatBuffer getDirection() { /**
if (direction == null && uComponent != null && vComponent != null) { * @return the direction from which the vector originates. This is commonly
uComponent.rewind(); * used in meteorology, espesially for winds. For example if a
vComponent.rewind(); * meteorologist says "The wind direction is North" it means the
direction = FloatBuffer.allocate(uComponent.capacity()); * wind is coming from the north and moving to the south.
while (vComponent.hasRemaining()) { * @see #getDirectionTo()
direction.put((float) Math.toDegrees(Math.atan2( */
uComponent.get(), vComponent.get()))); public DataSource getDirectionFrom() {
return new DirectionFromDataSource(uComponent, vComponent);
} }
uComponent.rewind();
vComponent.rewind(); /**
direction.rewind(); * @return the direction a vector is going towards. This is the common
} * mathematical deffinition of a vector.
return direction; * @see #getDirectionFrom()
*/
public DataSource getDirectionTo() {
return new DirectionToDataSource(uComponent, vComponent);
} }
public FloatBuffer getUComponent() { public FloatBuffer getUComponent() {
if (uComponent == null && scalarData != null && direction != null) { return uComponent.getBuffer();
scalarData.rewind();
direction.rewind();
uComponent = FloatBuffer.allocate(scalarData.capacity());
while (scalarData.hasRemaining()) {
double angle = Math.toRadians(direction.get());
uComponent.put((float) (Math.sin(angle) * scalarData.get()));
}
scalarData.rewind();
direction.rewind();
uComponent.rewind();
}
return uComponent;
} }
public FloatBuffer getVComponent() { public FloatBuffer getVComponent() {
if (vComponent == null && scalarData != null && direction != null) { return vComponent.getBuffer();
scalarData.rewind();
direction.rewind();
vComponent = FloatBuffer.allocate(scalarData.capacity());
while (scalarData.hasRemaining()) {
double angle = Math.toRadians(direction.get());
vComponent.put((float) (Math.cos(angle) * scalarData.get()));
}
scalarData.rewind();
direction.rewind();
vComponent.rewind();
}
return vComponent;
} }
public Unit<?> getDataUnit() { public Unit<?> getDataUnit() {
@ -470,4 +460,58 @@ public class GeneralGridData {
} }
} }
} }
private static abstract class VectorDataSource implements DataSource {
protected final DataSource uComponent;
protected final DataSource vComponent;
public VectorDataSource(DataSource uComponent, DataSource vComponent) {
this.uComponent = uComponent;
this.vComponent = vComponent;
}
}
private static final class MagnitudeDataSource extends VectorDataSource {
public MagnitudeDataSource(DataSource uComponent, DataSource vComponent) {
super(uComponent, vComponent);
}
@Override
public double getDataValue(int x, int y) {
return Math.hypot(uComponent.getDataValue(x, y),
vComponent.getDataValue(x, y));
}
}
private static final class DirectionFromDataSource extends VectorDataSource {
public DirectionFromDataSource(DataSource uComponent, DataSource vComponent) {
super(uComponent, vComponent);
}
@Override
public double getDataValue(int x, int y) {
return Math.toDegrees(Math.atan2(-uComponent.getDataValue(x, y),
-vComponent.getDataValue(x, y)));
}
}
private static final class DirectionToDataSource extends
VectorDataSource {
public DirectionToDataSource(DataSource uComponent,
DataSource vComponent) {
super(uComponent, vComponent);
}
@Override
public double getDataValue(int x, int y) {
return Math.toDegrees(Math.atan2(uComponent.getDataValue(x, y),
vComponent.getDataValue(x, y)));
}
}
} }

View file

@ -49,9 +49,10 @@ import com.raytheon.uf.viz.core.rsc.LoadProperties;
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- ----------------------------------------
* Mar 9, 2011 bsteffen Initial creation * Mar 09, 2011 bsteffen Initial creation
* Sep 24, 2013 2404 bclement match criteria built using GridStyleUtil * Sep 24, 2013 2404 bclement match criteria built using GridStyleUtil
* Jan 14, 2014 2661 bsteffen Switch vectors to u,v only.
* *
* </pre> * </pre>
* *
@ -104,15 +105,8 @@ public class GridResource<T extends AbstractResourceData> extends
} else if (dataRecs.length == 2) { } else if (dataRecs.length == 2) {
FloatBuffer mag = wrapDataRecord(dataRecs[0]); FloatBuffer mag = wrapDataRecord(dataRecs[0]);
FloatBuffer dir = wrapDataRecord(dataRecs[1]); FloatBuffer dir = wrapDataRecord(dataRecs[1]);
return GeneralGridData.createVectorData(gridGeometry, mag, dir, return GeneralGridData.createVectorDataUV(gridGeometry, mag, dir,
dataUnit); dataUnit);
} else if (dataRecs.length == 4) {
FloatBuffer mag = wrapDataRecord(dataRecs[0]);
FloatBuffer dir = wrapDataRecord(dataRecs[1]);
FloatBuffer u = wrapDataRecord(dataRecs[2]);
FloatBuffer v = wrapDataRecord(dataRecs[3]);
return GeneralGridData.createVectorData(gridGeometry, mag, dir, u,
v, dataUnit);
} }
return null; return null;
} }

View file

@ -33,22 +33,30 @@ import org.opengis.referencing.operation.TransformException;
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* 06/19/2012 14988 D. Friedman Initial revision * Jun 19, 2012 14988 D. Friedman Initial revision
* 09/24/2013 DR 15972 D. Friedman Do not require contiguous mapping. * Sep 24, 2013 15972 D. Friedman Do not require contiguous mapping.
* Jan 15, 2014 2661 bsteffen Disable output
* *
* </pre> * </pre>
*/ */
public class ConformalityUtil { public class ConformalityUtil {
private static final boolean DEBUG = false;
public static boolean testConformality(GeneralGridGeometry sourceGG, GeneralGridGeometry destGG) { public static boolean testConformality(GeneralGridGeometry sourceGG, GeneralGridGeometry destGG) {
ConformalityUtil test = new ConformalityUtil(sourceGG, destGG); ConformalityUtil test = new ConformalityUtil(sourceGG, destGG);
return test.testConformality(); return test.testConformality();
} }
GeneralGridGeometry sourceGG; GeneralGridGeometry sourceGG;
GeneralGridGeometry destGG; GeneralGridGeometry destGG;
double minRatio; double minRatio;
double maxRatio; double maxRatio;
MathTransform lastMT; MathTransform lastMT;
private ConformalityUtil(GeneralGridGeometry sourceGG, GeneralGridGeometry destGG) { private ConformalityUtil(GeneralGridGeometry sourceGG, GeneralGridGeometry destGG) {
@ -87,15 +95,20 @@ public class ConformalityUtil {
double rr = maxRatio / minRatio; double rr = maxRatio / minRatio;
if (! evaluated || maxRatio / minRatio > maxRatioRatio) { if (! evaluated || maxRatio / minRatio > maxRatioRatio) {
if (DEBUG) {
System.out.format("%s -> %s : not conformal enough (%f)\n", System.out.format("%s -> %s : not conformal enough (%f)\n",
sourceGG, destGG, maxRatio / minRatio); sourceGG, destGG, maxRatio / minRatio);
}
return false; return false;
} }
resetRatios(); resetRatios();
if (! evaluateNonContig(evaluatedDomain)) { if (! evaluateNonContig(evaluatedDomain)) {
System.out.format("%s -> %s : not contiguous?\n", sourceGG, destGG); if (DEBUG) {
System.out.format("%s -> %s : not contiguous?\n", sourceGG,
destGG);
}
return false; return false;
/* /*
* This test is not necessary for AWIPS II because it can cope * This test is not necessary for AWIPS II because it can cope
@ -109,8 +122,10 @@ public class ConformalityUtil {
return false; return false;
*/ */
} else { } else {
if (DEBUG) {
System.out.format("%s -> %s : conformal enough (%f, %f)\n", System.out.format("%s -> %s : conformal enough (%f, %f)\n",
sourceGG, destGG, rr, maxRatio/minRatio); sourceGG, destGG, rr, maxRatio / minRatio);
}
return true; return true;
} }
} }