Merge "Issue #2661 Use only u,v to represent vector grids in derived parameters and D2D. Change-Id: I7ea007f0f919017e8212716cc15712c7ed611e69" into development
Former-commit-id:518a3165e4
[formerlya71ef7b581
[formerly 56fd57c3e00926c95ab05297772161e960586e8f]] Former-commit-id:a71ef7b581
Former-commit-id:65306a503e
This commit is contained in:
commit
1d1f4175d0
58 changed files with 447 additions and 2203 deletions
|
@ -2,22 +2,16 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Derived Parameter Python Plug-in
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.derivparam.python;singleton:=true
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Activator: com.raytheon.uf.viz.derivparam.python.Activator
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: com.raytheon.uf.common.status;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.python;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.viz.core;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.viz.derivparam;bundle-version="1.12.1174",
|
||||
com.raytheon.uf.common.datastorage;bundle-version="1.12.1174",
|
||||
org.jep;bundle-version="1.0.0",
|
||||
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
|
||||
Require-Bundle: com.raytheon.uf.common.python,
|
||||
com.raytheon.uf.common.python.concurrent,
|
||||
com.raytheon.uf.viz.derivparam;bundle-version="1.14.0",
|
||||
com.raytheon.uf.viz.core;bundle-version="1.13.0",
|
||||
com.raytheon.uf.common.wxmath,
|
||||
com.raytheon.uf.common.util,
|
||||
com.raytheon.uf.common.datastorage
|
||||
Export-Package: com.raytheon.uf.viz.derivparam.python,
|
||||
com.raytheon.uf.viz.derivparam.python.function
|
||||
|
|
|
@ -18,10 +18,9 @@
|
|||
# further licensing information.
|
||||
##
|
||||
|
||||
from numpy import add
|
||||
from numpy import array
|
||||
from numpy import add,array,zeros_like
|
||||
|
||||
from Vector import execute as Vector
|
||||
import Vector
|
||||
|
||||
def execute(*args):
|
||||
""" Perform scalar or vector addition
|
||||
|
@ -38,33 +37,11 @@ def scalarAddition(args):
|
|||
return reduce(add, args)
|
||||
|
||||
def vectorAddition(args):
|
||||
|
||||
from numpy import zeros
|
||||
uResult = zeros_like(args[0][0])
|
||||
vResult = zeros_like(args[0][0])
|
||||
|
||||
targetShape = args[0][2].shape
|
||||
targetType = args[0][2].dtype
|
||||
for u, v in args:
|
||||
uResult += u
|
||||
vResult += v
|
||||
|
||||
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"
|
||||
return Vector.componentsTo(uResult, vResult)
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
## @file CompBy.py
|
||||
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.
|
||||
|
@ -50,8 +50,8 @@ def execute(Vecs, ThGrd, Angle=0):
|
|||
# pi/180 for degrees to radians conversion
|
||||
dgtord = 0.01745329252
|
||||
|
||||
Vecs_U, Vecs_V = Vecs[2], Vecs[3]
|
||||
ThGrd_U, ThGrd_V = ThGrd[2], ThGrd[3]
|
||||
Vecs_U, Vecs_V = Vecs
|
||||
ThGrd_U, ThGrd_V = ThGrd
|
||||
|
||||
if Angle != 0:
|
||||
# Strip off any 1000s from angle.
|
||||
|
@ -85,7 +85,7 @@ def execute(Vecs, ThGrd, Angle=0):
|
|||
comp = rotated_u * mag
|
||||
comp2 = rotated_v * mag
|
||||
|
||||
return Vector(comp, comp2)
|
||||
return Vector.componentsTo(comp, comp2)
|
||||
else:
|
||||
# initialize to u and v from ThGrd
|
||||
rotated_u = ThGrd_U
|
||||
|
|
|
@ -49,7 +49,7 @@ def execute(A0, A1, B0, B1):
|
|||
v1 = A1[3]
|
||||
uDeriv = execute(u0, u1, B0, B1)
|
||||
vDeriv = execute(v0, v1, B0, B1)
|
||||
return Vector.execute(uDeriv, vDeriv)
|
||||
return Vector.componentsTo(uDeriv, vDeriv)
|
||||
|
||||
Adiff = A1-A0
|
||||
Bdiff = B1-B0
|
||||
|
|
|
@ -28,34 +28,11 @@ def execute(*args):
|
|||
|
||||
if type(diffArgs[0]) == tuple:
|
||||
for i in range(1, len(diffArgs)):
|
||||
diffVectorArg = list(diffArgs[i])
|
||||
diffVectorArg[2] = -diffVectorArg[2]
|
||||
diffVectorArg[3] = -diffVectorArg[3]
|
||||
diffArgs[i] = tuple(diffVectorArg)
|
||||
diffArgs[i] = (-diffArgs[i][0], -diffArgs[i][1])
|
||||
return apply(Add, diffArgs)
|
||||
else:
|
||||
result = 0
|
||||
result += diffArgs[0]
|
||||
for i in range(1, len(diffArgs)):
|
||||
result -= diffArgs[i]
|
||||
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"
|
||||
return result
|
|
@ -43,8 +43,7 @@ def execute(vec, dx, dy, quan=1.0):
|
|||
dvdy = diff_v/dy[i,j] \n
|
||||
diverg[i,j] = (dudx + dvdy)/2 \n
|
||||
"""
|
||||
vec_U = vec[2]
|
||||
vec_V = vec[3]
|
||||
vec_U,vec_V = vec
|
||||
|
||||
vshape = shape(vec_U)
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
|
||||
## @file Geowind.py
|
||||
|
||||
from numpy import isscalar
|
||||
from numpy import NaN
|
||||
from numpy import isscalar,NaN
|
||||
import Vector
|
||||
|
||||
g = 9.806 # Gravitational acceleration (m/s^2)
|
||||
|
@ -79,5 +78,5 @@ def execute(Height, dx, dy, coriolis):
|
|||
result_U = result_U
|
||||
result_V = result_V
|
||||
|
||||
result = Vector.execute(result_U, result_V)
|
||||
result = Vector.componentsTo(result_U, result_V)
|
||||
return result
|
||||
|
|
|
@ -66,5 +66,5 @@ def execute(scalar, dx, dy):
|
|||
|
||||
result_u[:,1:-1] = ans_u
|
||||
result_v[1:-1,:] = ans_v
|
||||
return Vector.execute(result_u, result_v)
|
||||
return Vector.componentsTo(result_u, result_v)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
from Add import execute as Add
|
||||
from Multiply import execute as Multiply
|
||||
from numpy import zeros, ndarray
|
||||
from numpy import zeros_like, ndarray
|
||||
|
||||
def execute(*args):
|
||||
"""Perform a linear transform
|
||||
|
@ -35,17 +35,14 @@ def execute(*args):
|
|||
|
||||
|
||||
if type(args[0]) == tuple:
|
||||
targetShape = args[0][0].shape
|
||||
targetType = args[0][0].dtype
|
||||
zeroArray = zeros(shape=(targetShape), dtype=targetType)
|
||||
result = (zeroArray, zeroArray.copy(), zeroArray.copy(), zeroArray.copy())
|
||||
zeroArray = zeros_like(args[0][0])
|
||||
result = (zeroArray, zeroArray.copy())
|
||||
else:
|
||||
for arg in args:
|
||||
if (type(arg) == ndarray):
|
||||
targetShape = arg.shape
|
||||
targetType = arg.dtype
|
||||
result = zeros(shape=targetShape, dtype=targetType)
|
||||
|
||||
result = zeros_like(arg)
|
||||
break
|
||||
|
||||
termLength = 2
|
||||
|
||||
terms = len(args) / termLength
|
||||
|
@ -58,23 +55,3 @@ def execute(*args):
|
|||
result = Add(result, Multiply(coefficient, variable))
|
||||
|
||||
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"
|
||||
|
|
|
@ -21,9 +21,8 @@
|
|||
from numpy import log, exp
|
||||
|
||||
import PartialDerivative as Partial
|
||||
import DgeoComps as DgeoComps
|
||||
from Vector import execute as Vector
|
||||
|
||||
import DgeoComps
|
||||
import Vector
|
||||
##
|
||||
# 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):
|
||||
result_u, result_v, dtdx, dtdy = calculate(GHxSM, TxSM, P, dx, dy, coriolis)
|
||||
# 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.
|
||||
|
|
|
@ -22,7 +22,7 @@ from numpy import log, exp
|
|||
|
||||
import PartialDerivative as Partial
|
||||
import DgeoComps as DgeoComps
|
||||
from Vector import execute as Vector
|
||||
import Vector
|
||||
|
||||
##
|
||||
# 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)
|
||||
# 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.
|
||||
|
|
|
@ -29,34 +29,6 @@ def execute(*args):
|
|||
"""
|
||||
|
||||
if type(args[0]) == tuple:
|
||||
return vectorMagnitude(args[0])
|
||||
return hypot(args[0][0], args[0][1])
|
||||
else:
|
||||
return componentMagnitude(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"
|
||||
return hypot(args[0], args[1])
|
|
@ -19,7 +19,7 @@
|
|||
##
|
||||
|
||||
from numpy import multiply
|
||||
from Vector import execute as Vector
|
||||
import Vector
|
||||
|
||||
def execute(*args):
|
||||
""" Perform multiplication of any number of scalars or of a vector and a scalar.
|
||||
|
@ -32,27 +32,8 @@ def execute(*args):
|
|||
return scalarMultiply(args)
|
||||
|
||||
def scalarMultiply(args):
|
||||
|
||||
return reduce(multiply, args)
|
||||
|
||||
def vectorMultiply(args):
|
||||
|
||||
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"
|
||||
return Vector.componentsTo(scalarMultiply((args[0][0], args[1])), scalarMultiply((args[0][1], args[1])))
|
||||
|
|
@ -21,10 +21,9 @@
|
|||
#import sys
|
||||
#sys.path.append("..")
|
||||
|
||||
from numpy import ndarray,NaN
|
||||
from numpy import float32
|
||||
from Vector import execute as Vector
|
||||
from numpy import ndarray,NaN, float32
|
||||
from Multiply import execute as Multiply
|
||||
import Vector
|
||||
|
||||
##
|
||||
# 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
|
||||
dadydt[1:-1,1:-1] = -0.5 * (dudy*dadx + dvdy*dady)
|
||||
|
||||
return Vector(-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()
|
||||
return Vector.componentsTo(-dadxdt, dadydt)
|
||||
|
|
|
@ -19,15 +19,12 @@
|
|||
###
|
||||
|
||||
## @file Negate.py
|
||||
import numpy
|
||||
from Vector import execute as Vector
|
||||
import Vector
|
||||
|
||||
##
|
||||
# Negates input
|
||||
def execute(input):
|
||||
if type(input) == tuple:
|
||||
u = -input[2]
|
||||
v = -input[3]
|
||||
return Vector(u,v)
|
||||
return Vector.componentTo(-input[0], -input[1])
|
||||
else:
|
||||
return -input
|
|
@ -50,8 +50,8 @@ import Vorticity
|
|||
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."
|
||||
|
||||
u_up, v_up = vector_up[2], vector_up[3]
|
||||
u_lo, v_lo = vector_lo[2], vector_lo[3]
|
||||
u_up, v_up = vector_up
|
||||
u_lo, v_lo = vector_lo
|
||||
|
||||
|
||||
# Calculate the absolute vorticity at each isentropic surface.
|
||||
|
|
|
@ -60,8 +60,8 @@ import Vorticity
|
|||
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_lo, v_lo = vector_lo[2], vector_lo[3]
|
||||
u_up, v_up = vector_up
|
||||
u_lo, v_lo = vector_lo
|
||||
|
||||
# Calculate the absolute vorticity at each isobaric surface.
|
||||
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.
|
||||
grad_lo = Gradient.execute(t_lo, dx, dy)
|
||||
grad_up = Gradient.execute(t_up, dx, dy)
|
||||
dtdx1, dtdy1 = grad_lo[2], grad_lo[3]
|
||||
dtdx2, dtdy2 = grad_up[2], grad_up[3]
|
||||
dtdx1, dtdy1 = grad_lo
|
||||
dtdx2, dtdy2 = grad_up
|
||||
# Calculate difference arrays.
|
||||
dp = p_up - p_lo
|
||||
dt = t_up - t_lo
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
##
|
||||
|
||||
from Add import execute as Add
|
||||
from Vector import execute as Vector
|
||||
from numpy import array
|
||||
from numpy import dot
|
||||
from math import radians,cos,sin
|
||||
from numpy import array,dot
|
||||
import Vector
|
||||
|
||||
def execute(*args):
|
||||
"""Rotate a vector
|
||||
|
@ -39,54 +39,31 @@ def execute(*args):
|
|||
return vectorTransformMatrix(args)
|
||||
|
||||
def rotateDegrees(args):
|
||||
|
||||
magnitude = args[0][0]
|
||||
direction = Add(args[0][1], args[1]) % 360
|
||||
|
||||
return Vector(magnitude, direction, True)
|
||||
v = args[0]
|
||||
r = radians(args[1])
|
||||
s = sin(r)
|
||||
c = cos(r)
|
||||
return vectorTransformMatrix(v,c,-s,s,c)
|
||||
|
||||
def vectorTransformMatrix(args):
|
||||
|
||||
uComponent = args[0][2]
|
||||
vComponent = args[0][3]
|
||||
uComponent,vComponent = args[0]
|
||||
|
||||
uComponentShape = uComponent.shape
|
||||
vComponentShape = vComponent.shape
|
||||
|
||||
# in-place flatten the arrays
|
||||
uComponent.resize((uComponent.size,))
|
||||
vComponent.resize((vComponent.size,))
|
||||
uComponent = uComponent.reshape((uComponent.size,))
|
||||
vComponent = vComponent.reshape((vComponent.size,))
|
||||
|
||||
vector = array([uComponent, vComponent])
|
||||
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
|
||||
u.resize(uComponentShape)
|
||||
v.resize(vComponentShape)
|
||||
|
||||
return Vector(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"
|
||||
|
||||
return Vector.componentsTo(u, v)
|
||||
|
|
@ -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))
|
|
@ -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()
|
|
@ -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))
|
|
@ -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))
|
|
@ -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))
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
|
@ -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]))
|
|
@ -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.")
|
|
@ -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))
|
|
@ -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))
|
||||
|
|
@ -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))
|
|
@ -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")
|
|
@ -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))
|
|
@ -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))
|
||||
|
||||
|
|
@ -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))
|
||||
|
|
@ -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()
|
|
@ -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()
|
|
@ -27,27 +27,21 @@ from numpy import radians
|
|||
from numpy import abs
|
||||
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.
|
||||
|
||||
@param legacyOption
|
||||
@param magDir
|
||||
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.
|
||||
|
||||
positive :: assume meteorological direction
|
||||
negative :: assume mathematical direction
|
||||
positive :: assume meteorological direction(direction from)
|
||||
negative :: assume mathematical direction(direction to)
|
||||
|
||||
abs(legacyOption) == 1 :: assume degrees
|
||||
abs(legacyOption) != 1 :: assume radians
|
||||
|
||||
abs(legacyOption) == 1 || 2 :: assume first two args are speed and
|
||||
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)
|
||||
abs(legacyOption) == 1 :: assume direction in degrees
|
||||
abs(legacyOption) != 1 :: assume direction in radians
|
||||
|
||||
@return: tuple of (u,v)
|
||||
|
||||
"""
|
||||
# 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)
|
||||
v = tmp
|
||||
|
||||
# These will be parsed by legacy opts
|
||||
polar=False
|
||||
mathematicalDirection=False
|
||||
useRadians=False
|
||||
speed = None
|
||||
|
||||
# Handle the crazy legacy options
|
||||
if legacyOption != None:
|
||||
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:
|
||||
speed = legacyOption
|
||||
|
||||
completeRevolution = 360 if not useRadians else radians(360.0)
|
||||
|
||||
if (polar):
|
||||
mag = u
|
||||
dir = v
|
||||
|
||||
# replace all negative angles with their corresponding positive values
|
||||
negDirMask = dir < 0
|
||||
dir[negDirMask] = (- dir[negDirMask]) % completeRevolution
|
||||
dir[negDirMask] = completeRevolution - dir[negDirMask]
|
||||
|
||||
dir[dir > completeRevolution] %= completeRevolution
|
||||
theta = radians(dir) if not useRadians else dir
|
||||
u = mag * sin(theta)
|
||||
v = mag * cos(theta)
|
||||
if magDir == None:
|
||||
return componentsTo(u, v)
|
||||
elif magDir == 1:
|
||||
return magDirDegreesFrom(u, v);
|
||||
elif magDir == -1:
|
||||
return magDirDegreesTo(u, v);
|
||||
elif magDir >= 0:
|
||||
return magDirRadiansFrom(u, v);
|
||||
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
|
||||
v = - v if not mathematicalDirection else v
|
||||
|
||||
dir[dir == completeRevolution] = 0
|
||||
|
||||
if speed == None:
|
||||
return (mag, dir, u, v)
|
||||
else:
|
||||
return execute(speed,dir,polar=True)
|
||||
return magDirRadiansTo(u, v);
|
||||
|
||||
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"
|
||||
def componentsTo(u,v):
|
||||
return (u, v)
|
||||
|
||||
def magDirRadiansTo(mag, dir):
|
||||
u = sin(dir) * mag
|
||||
v = cos(dir) * mag
|
||||
return componentsTo(u,v)
|
||||
|
||||
def magDirDegreesTo(mag, dir):
|
||||
return magDirRadiansTo(mag, radians(dir))
|
||||
|
||||
def componentsFrom(u,v):
|
||||
return componentsTo(-u,-v)
|
||||
|
||||
def magDirRadiansFrom(mag, dir):
|
||||
u = sin(dir) * mag
|
||||
v = cos(dir) * mag
|
||||
return componentFrom(u,v)
|
||||
|
||||
def magDirDegreesFrom(mag, dir):
|
||||
return magDirRadiansFrom(mag, radians(dir))
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,30 +2,23 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Derived Parameter Plug-in
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.derivparam;singleton:=true
|
||||
Bundle-Version: 1.12.1174.qualifier
|
||||
Bundle-Activator: com.raytheon.uf.viz.derivparam.Activator
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
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-ActivationPolicy: lazy
|
||||
Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization
|
||||
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,
|
||||
Require-Bundle: com.raytheon.uf.common.derivparam,
|
||||
com.raytheon.uf.common.time,
|
||||
com.vividsolutions.jts.geom,
|
||||
org.opengis.referencing.crs
|
||||
com.raytheon.uf.common.dataplugin.level,
|
||||
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,
|
||||
com.raytheon.uf.viz.derivparam.data,
|
||||
com.raytheon.uf.viz.derivparam.inv,
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
|
||||
further_licensing_information.
|
||||
-->
|
||||
<DerivedParameter abbreviation="FeatMot" name="Feature Motion" unit="kt">
|
||||
<DerivedParameter abbreviation="FeatMot" name="Feature Motion" unit="kn">
|
||||
<Method name="Vector">
|
||||
<Field abbreviation="USTM"/>
|
||||
<Field abbreviation="VSTM"/>
|
||||
<Field abbreviation="USTM" unit="kn"/>
|
||||
<Field abbreviation="VSTM" unit="kn"/>
|
||||
</Method>
|
||||
</DerivedParameter>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<DerivedParameter unit="m/s" name="Wind Gust" abbreviation="Gust" xmlns:ns2="group">
|
||||
<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"/>
|
||||
<ConstantField value="1.0"/>
|
||||
</Method>
|
||||
|
@ -19,9 +19,4 @@
|
|||
<Field abbreviation="WD" unit="deg"/>
|
||||
<ConstantField value="1.0"/>
|
||||
</Method>
|
||||
<Method name="Vector">
|
||||
<Field abbreviation="uW"/>
|
||||
<Field abbreviation="vW"/>
|
||||
<Field abbreviation="WGS" unit="m/s"/>
|
||||
</Method>
|
||||
</DerivedParameter>
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<Field abbreviation="DMD"/>
|
||||
</Method>
|
||||
<Method name="Vector">
|
||||
<Field abbreviation="USTM"/>
|
||||
<Field abbreviation="VSTM"/>
|
||||
<Field abbreviation="USTM" unit="kn"/>
|
||||
<Field abbreviation="VSTM" unit="kn"/>
|
||||
</Method>
|
||||
<Method levels="Layer" name="Rotate">
|
||||
<Field level="0-6kmAgl" abbreviation="Wind"/>
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
<Field abbreviation="Windmean"/>
|
||||
</Method>
|
||||
<Method name="Vector">
|
||||
<Field abbreviation="uW"/>
|
||||
<Field abbreviation="vW"/>
|
||||
<Field abbreviation="uW" unit="m/s"/>
|
||||
<Field abbreviation="vW" unit="m/s"/>
|
||||
</Method>
|
||||
<Method name="Vector">
|
||||
<Field abbreviation="wSp"/>
|
||||
<Field abbreviation="wSp" unit="m/s"/>
|
||||
<Field abbreviation="WD" unit="deg"/>
|
||||
<ConstantField value="1.0"/>
|
||||
</Method>
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
|
||||
further_licensing_information.
|
||||
-->
|
||||
<DerivedParameter abbreviation="Windmean" name="Mean Wind" unit="kt">
|
||||
<DerivedParameter abbreviation="Windmean" name="Mean Wind" unit="kn">
|
||||
<Method name="Vector">
|
||||
<Field abbreviation="uWmean" unit="kts"/>
|
||||
<Field abbreviation="vWmean" unit="kts"/>
|
||||
<Field abbreviation="uWmean" unit="kn"/>
|
||||
<Field abbreviation="vWmean" unit="kn"/>
|
||||
</Method>
|
||||
<Method name="Vector">
|
||||
<Field abbreviation="WSmean" unit="kts"/>
|
||||
<Field abbreviation="WSmean" unit="kn"/>
|
||||
<Field abbreviation="WDmean" unit="deg"/>
|
||||
<ConstantField value="1.0"/>
|
||||
</Method>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -38,9 +38,10 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 15, 2010 #3965 rjpeter Initial creation
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 15, 2010 3965 rjpeter Initial creation
|
||||
* Jan 14, 2014 2661 bsteffen Make vectors u,v only
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -73,15 +74,12 @@ public class AliasRequestableData extends AbstractRequestableData {
|
|||
}
|
||||
} else if (rval instanceof FloatDataRecord[]) {
|
||||
FloatDataRecord[] recs = (FloatDataRecord[]) rval;
|
||||
FloatDataRecord[] newRecs = new FloatDataRecord[recs.length];
|
||||
IDataRecord[] newRecs = new FloatDataRecord[recs.length];
|
||||
rval = newRecs;
|
||||
for (int i = 0; i < recs.length; i++) {
|
||||
if (recs[i] instanceof FloatDataRecord) {
|
||||
newRecs[i] = (FloatDataRecord) ((FloatDataRecord) recs[i])
|
||||
.clone();
|
||||
if (this.parameter != null) {
|
||||
((FloatDataRecord) newRecs[i]).setName(this.parameter);
|
||||
}
|
||||
newRecs[i] = recs[i].clone();
|
||||
if (this.parameter != null) {
|
||||
newRecs[i].setName(this.parameter);
|
||||
}
|
||||
}
|
||||
} else if (rval instanceof IDataRecord[]) {
|
||||
|
@ -89,11 +87,9 @@ public class AliasRequestableData extends AbstractRequestableData {
|
|||
IDataRecord[] newRecs = new IDataRecord[recs.length];
|
||||
rval = newRecs;
|
||||
for (int i = 0; i < recs.length; i++) {
|
||||
if (recs[i] instanceof IDataRecord) {
|
||||
newRecs[i] = ((IDataRecord) recs[i]).clone();
|
||||
if (this.parameter != null) {
|
||||
((IDataRecord) newRecs[i]).setName(this.parameter);
|
||||
}
|
||||
newRecs[i] = recs[i].clone();
|
||||
if (this.parameter != null) {
|
||||
newRecs[i].setName(this.parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,22 +114,11 @@ public class AliasRequestableData extends AbstractRequestableData {
|
|||
FloatDataRecord[] recs = (FloatDataRecord[]) rval;
|
||||
if (recs.length != 1 || !unit.equals(NonSI.DEGREE_ANGLE)) {
|
||||
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) {
|
||||
float[] data = ((FloatDataRecord) recs[i])
|
||||
.getFloatData();
|
||||
for (int c = 0; c < data.length; c++) {
|
||||
if (data[c] > -9999) {
|
||||
data[c] = (float) converter
|
||||
.convert(data[c]);
|
||||
}
|
||||
float[] data = recs[i].getFloatData();
|
||||
for (int c = 0; c < data.length; c++) {
|
||||
if (data[c] > -9999) {
|
||||
data[c] = (float) converter
|
||||
.convert(data[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,20 +127,11 @@ public class AliasRequestableData extends AbstractRequestableData {
|
|||
IDataRecord[] recs = (IDataRecord[]) rval;
|
||||
if (recs.length != 1 || !unit.equals(NonSI.DEGREE_ANGLE)) {
|
||||
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) {
|
||||
float[] data = ((FloatDataRecord) recs[i])
|
||||
.getFloatData();
|
||||
for (int c = 0; c < data.length; c++) {
|
||||
if (data[c] > -9999) {
|
||||
|
||||
data[c] = (float) converter
|
||||
.convert(data[c]);
|
||||
}
|
||||
|
|
|
@ -41,11 +41,13 @@ import com.raytheon.uf.viz.derivparam.tree.CubeLevel;
|
|||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 17, 2010 bsteffen Initial creation
|
||||
* Jun 04, 2013 2041 bsteffen Switch derived parameters to use
|
||||
* concurrent python for threading.
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Mar 17, 2010 bsteffen Initial creation
|
||||
* Jun 04, 2013 2041 bsteffen Switch derived parameters to use
|
||||
* concurrent python for threading.
|
||||
* Jan 14, 2014 2661 bsteffen Make vectors u,v only
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -80,14 +82,14 @@ public class DerivedRequestableData extends AbstractRequestableData {
|
|||
List<IDataRecord> finalResult = DerivedParameterGenerator
|
||||
.calculate(request);
|
||||
if (finalResult != null && !finalResult.isEmpty()) {
|
||||
if (finalResult.size() == 4 || finalResult.size() == 1) {
|
||||
if (finalResult.size() == 2 || finalResult.size() == 1) {
|
||||
for (IDataRecord rec : finalResult) {
|
||||
rec.setName(request.getParameterAbbreviation());
|
||||
}
|
||||
return finalResult.toArray(new IDataRecord[0]);
|
||||
} else {
|
||||
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) {
|
||||
|
|
|
@ -24,8 +24,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
|||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.raytheon.uf.common.serialization.ISerializableObject;
|
||||
|
||||
/**
|
||||
* Metadata about a derived parameter field.
|
||||
*
|
||||
|
@ -34,9 +32,11 @@ import com.raytheon.uf.common.serialization.ISerializableObject;
|
|||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 11/21/2009 #3576 rjpeter Initial version
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Nov 21, 2009 3576 rjpeter Initial version
|
||||
* Jan 14, 2014 2661 bsteffen Remove ISerializableObject
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rjpeter
|
||||
|
@ -44,8 +44,7 @@ import com.raytheon.uf.common.serialization.ISerializableObject;
|
|||
*/
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
@XmlRootElement
|
||||
public class DerivParamConstantField implements ISerializableObject,
|
||||
IDerivParamField {
|
||||
public class DerivParamConstantField implements IDerivParamField {
|
||||
|
||||
@XmlAttribute(required = true)
|
||||
private Float value;
|
||||
|
|
|
@ -30,7 +30,6 @@ import javax.xml.bind.annotation.XmlElement;
|
|||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
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.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
|
@ -44,9 +43,11 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
|||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 11/21/2009 #3576 rjpeter Initial version
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Nov 21, 2009 3576 rjpeter Initial version
|
||||
* Jan 14, 2014 2661 bsteffen Remove ISerializableObject
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rjpeter
|
||||
|
@ -54,7 +55,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
|||
*/
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
@XmlRootElement(name = "DerivedParameter")
|
||||
public class DerivParamDesc implements ISerializableObject {
|
||||
public class DerivParamDesc {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(DerivParamDesc.class);
|
||||
|
||||
|
|
|
@ -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.LevelMappingFactory;
|
||||
import com.raytheon.uf.common.serialization.ISerializableObject;
|
||||
import com.raytheon.uf.common.serialization.adapters.UnitAdapter;
|
||||
import com.raytheon.uf.viz.core.exception.VizCommunicationException;
|
||||
|
||||
|
@ -41,9 +40,11 @@ import com.raytheon.uf.viz.core.exception.VizCommunicationException;
|
|||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 11/21/2009 #3576 rjpeter Initial version
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Nov 21, 2009 3576 rjpeter Initial version
|
||||
* Jan 14, 2014 2661 bsteffen Remove ISerializableObject
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rjpeter
|
||||
|
@ -51,7 +52,7 @@ import com.raytheon.uf.viz.core.exception.VizCommunicationException;
|
|||
*/
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
@XmlRootElement
|
||||
public class DerivParamField implements ISerializableObject, IDerivParamField {
|
||||
public class DerivParamField implements IDerivParamField {
|
||||
|
||||
@XmlAttribute(name = "abbreviation", required = true)
|
||||
private String param;
|
||||
|
|
|
@ -34,7 +34,6 @@ import javax.xml.bind.annotation.XmlRootElement;
|
|||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
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.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
|
@ -49,9 +48,11 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 11/21/2009 #3576 rjpeter Initial version
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Nov 21, 2009 3576 rjpeter Initial version
|
||||
* Jan 14, 2014 2661 bsteffen Remove ISerializableObject
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rjpeter
|
||||
|
@ -59,7 +60,7 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
*/
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
@XmlRootElement
|
||||
public class DerivParamMethod implements ISerializableObject {
|
||||
public class DerivParamMethod {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(DerivParamMethod.class);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.eclipse.core.runtime.IStatus;
|
|||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
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.localization.FileUpdatedMessage;
|
||||
|
@ -55,37 +56,31 @@ import com.raytheon.uf.common.serialization.JAXBManager;
|
|||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
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.IDerivParamFunctionAdapter;
|
||||
import com.raytheon.uf.viz.derivparam.library.DerivParamMethod.MethodType;
|
||||
|
||||
/**
|
||||
* A thread that accepts requests for a derived parameter, passes it to JEP and
|
||||
* returns the request. It is important to note that this thread performs a
|
||||
* sleep instead of a schedule to keep the JEP instance in the same thread. To
|
||||
* properly interact with this thread, it is important to use
|
||||
* <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.
|
||||
* Primary public interface for derived parameters. Introspection on the derived
|
||||
* parameters available can be done using {@link #getDerParLibrary()}. For
|
||||
* actually performing derived parameters calculations the
|
||||
* {@link #calculate(DerivedParameterRequest)} method can be used.
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 03, 2008 brockwoo Initial creation
|
||||
* Nov 16, 2009 3120 rjpeter Removed use of LevelNameMappingFile.
|
||||
* Nov 20, 2009 3387 jelkins Use derived script's variableId instead
|
||||
* of filename
|
||||
* Nov 21, 2009 3576 rjpeter Refactored DerivParamDesc.
|
||||
* Jun 04, 2013 2041 bsteffen Switch derived parameters to use
|
||||
* concurrent python for threading.
|
||||
* Nov 19, 2013 2361 njensen Only shutdown if initialized
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jul 03, 2008 brockwoo Initial creation
|
||||
* Nov 16, 2009 3120 rjpeter Removed use of LevelNameMappingFile.
|
||||
* Nov 20, 2009 3387 jelkins Use derived script's variableId instead
|
||||
* of filename
|
||||
* Nov 21, 2009 3576 rjpeter Refactored DerivParamDesc.
|
||||
* Jun 04, 2013 2041 bsteffen Switch derived parameters to use
|
||||
* concurrent python for threading.
|
||||
* Nov 19, 2013 2361 njensen Only shutdown if initialized
|
||||
* Jan 14, 2014 2661 bsteffen Shutdown using uf.viz.core.Activator
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author brockwoo
|
||||
|
@ -201,6 +196,13 @@ public class DerivedParameterGenerator implements ILocalizationFileObserver {
|
|||
"Error creating derived parameter function type,"
|
||||
+ " derived paramters will not be available");
|
||||
}
|
||||
Activator.getDefault().registerDisposable(new IDisposable() {
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
shutdown();
|
||||
}
|
||||
});
|
||||
this.adapter = functionTypes[0].getAdapter();
|
||||
this.extension = functionTypes[0].getExtension();
|
||||
notifyJob.setSystem(true);
|
||||
|
@ -251,8 +253,8 @@ public class DerivedParameterGenerator implements ILocalizationFileObserver {
|
|||
|
||||
for (LocalizationFile file : xmlFiles) {
|
||||
try {
|
||||
DerivParamDesc desc = (DerivParamDesc) jaxbMan
|
||||
.unmarshalFromXmlFile(file.getFile());
|
||||
DerivParamDesc desc = jaxbMan.unmarshalFromXmlFile(
|
||||
DerivParamDesc.class, file.getFile());
|
||||
if (derParLibrary.containsKey(desc.getAbbreviation())) {
|
||||
DerivParamDesc oldDesc = derParLibrary.get(desc
|
||||
.getAbbreviation());
|
||||
|
@ -330,9 +332,10 @@ public class DerivedParameterGenerator implements ILocalizationFileObserver {
|
|||
initLibrary();
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
public static synchronized void shutdown() {
|
||||
if (instance != null) {
|
||||
getInstance().adapter.shutdown();
|
||||
instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,9 +49,11 @@ import com.raytheon.uf.viz.core.exception.VizCommunicationException;
|
|||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 11/21/2009 #3576 rjpeter Initial version
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Nov 21, 2009 3576 rjpeter Initial version
|
||||
* Jan 14, 2014 2661 bsteffen Remove unnecessary exceptions
|
||||
*
|
||||
*
|
||||
* @author rjpeter
|
||||
* @version 1.0
|
||||
|
@ -149,8 +151,7 @@ public class ValidLevelGenerator {
|
|||
return validLevels;
|
||||
}
|
||||
|
||||
private void processLevelToken(String token)
|
||||
throws VizCommunicationException, CommunicationException {
|
||||
private void processLevelToken(String token) throws CommunicationException {
|
||||
boolean negate = token.charAt(0) == '!';
|
||||
int rangeIndex = token.indexOf('>');
|
||||
|
||||
|
@ -341,8 +342,7 @@ public class ValidLevelGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
private Type determineType(String token) throws CommunicationException,
|
||||
VizCommunicationException {
|
||||
private Type determineType(String token) throws CommunicationException {
|
||||
Type rval = null;
|
||||
LevelMapping mapping = lmf.getLevelMappingForKey(token);
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ import org.geotools.referencing.GeodeticCalculator;
|
|||
|
||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||
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.IGraphicsTarget;
|
||||
import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle;
|
||||
|
@ -50,7 +52,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* ------------- -------- ----------- -----------------------------------------
|
||||
* Jun 22, 2010 bsteffen Initial creation
|
||||
* Feb 07, 2011 7948 bkowal added a public method to get the
|
||||
* direction.
|
||||
|
@ -62,11 +64,14 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* gridRelative flag to indicate whether
|
||||
* direction data is relative to grid or
|
||||
* true north
|
||||
* Sep 09, 2013 16257 MPorricelli When setDestinationGeographicPoint fails (which can
|
||||
* happen for global lat/lon grid winds displayed on
|
||||
* Equidistant Cylindrical map) try again with different
|
||||
* Sep 09, 2013 16257 MPorricelli When setDestinationGeographicPoint fails
|
||||
* (which can happen for global lat/lon grid
|
||||
* winds displayed on Equidistant
|
||||
* Cylindrical map) try again with different
|
||||
* pixel location.
|
||||
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
|
||||
* Jan 14, 2014 2661 bsteffen Switch magnitude and direction from
|
||||
* buffers to DataSource
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -75,9 +80,9 @@ import com.vividsolutions.jts.geom.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;
|
||||
|
||||
|
@ -96,20 +101,26 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
|
|||
private GeodeticCalculator gc;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param magnitude
|
||||
* a data source for the magnitude of vectors
|
||||
* @param direction
|
||||
* a data source for the direction of vectors
|
||||
* @param descriptor
|
||||
* the descriptor
|
||||
* @param gridGeometryOfGrid
|
||||
* @param size
|
||||
* geometry of the data sources
|
||||
* @param densityFactor
|
||||
* adjustment factor to make density match A1
|
||||
* @param gridRelative
|
||||
* true if direction is grid relative, false if relative to true
|
||||
* north
|
||||
* @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,
|
||||
double densityFactor, boolean gridRelative,
|
||||
DisplayType displayType, VectorGraphicsConfig config) {
|
||||
|
@ -123,6 +134,21 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
|
|||
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
|
||||
public void paint(IGraphicsTarget target, PaintProperties paintProps)
|
||||
throws VizException {
|
||||
|
@ -151,17 +177,18 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
|
|||
@Override
|
||||
protected void paint(Coordinate ijcoord, PaintProperties paintProps,
|
||||
Coordinate plotLoc, double adjSize) throws VizException {
|
||||
int idx = (int) (ijcoord.x + (ijcoord.y * this.gridDims[0]));
|
||||
|
||||
float spd = this.magnitude.get(idx);
|
||||
float dir = this.direction.get(idx);
|
||||
double spd = this.magnitude.getDataValue((int) ijcoord.x,
|
||||
(int) ijcoord.y);
|
||||
double dir = this.direction.getDataValue((int) ijcoord.x,
|
||||
(int) ijcoord.y);
|
||||
|
||||
if (dir < -999999 || dir > 9999999) {
|
||||
// perhaps this check should limit +/- 180
|
||||
return;
|
||||
}
|
||||
|
||||
if (Float.isNaN(spd) || Float.isNaN(dir)) {
|
||||
if (Double.isNaN(spd) || Double.isNaN(dir)) {
|
||||
return;
|
||||
}
|
||||
int tryDiffPixLoc = 0;
|
||||
|
@ -269,17 +296,6 @@ public class GriddedVectorDisplay extends AbstractGriddedDisplay<Coordinate> {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the magnitude
|
||||
*/
|
||||
public FloatBuffer getMagnitude() {
|
||||
return magnitude;
|
||||
}
|
||||
|
||||
public FloatBuffer getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disposeResources() {
|
||||
if (vectorRenderable != null) {
|
||||
|
|
|
@ -105,7 +105,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* ------------- -------- ----------- -----------------------------------------
|
||||
* Mar 09, 2011 bsteffen Initial creation
|
||||
* May 08, 2013 1980 bsteffen Set paint status in GridResources for
|
||||
* KML.
|
||||
|
@ -113,8 +113,12 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* Aug 27, 2013 2287 randerso Added new parameters required by
|
||||
* GriddedVectorDisplay and
|
||||
* 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.
|
||||
* Jan 14, 2014 2594 bsteffen Switch vector mag/dir to use data source
|
||||
* instead of raw float data.
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -525,7 +529,7 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
|
|||
}
|
||||
}
|
||||
GriddedVectorDisplay vectorDisplay = new GriddedVectorDisplay(
|
||||
data.getMagnitude(), data.getDirection(), descriptor,
|
||||
data.getMagnitude(), data.getDirectionFrom(), descriptor,
|
||||
gridGeometry, VECTOR_DENSITY_FACTOR, true, displayType,
|
||||
config);
|
||||
vectorDisplay.setColor(getCapability(ColorableCapability.class)
|
||||
|
@ -844,8 +848,13 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
|
|||
"Error transforming coordinate for interrogate", e);
|
||||
}
|
||||
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);
|
||||
}
|
||||
double value = sampler.sample(pixel.x, pixel.y);
|
||||
if (Double.isNaN(value)) {
|
||||
return null;
|
||||
|
@ -872,8 +881,7 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
|
|||
result.put(INTERROGATE_UNIT, "");
|
||||
}
|
||||
if (data.isVector()) {
|
||||
sampler.setSource(new FloatBufferWrapper(data.getDirection(), data
|
||||
.getGridGeometry()));
|
||||
sampler.setSource(data.getDirectionFrom());
|
||||
Double dir = sampler.sample(pixel.x, pixel.y);
|
||||
result.put(INTERROGATE_DIRECTION, dir);
|
||||
}
|
||||
|
|
|
@ -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.Interpolation;
|
||||
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.FloatBufferWrapper;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
|
@ -55,12 +56,15 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 09, 2011 bsteffen Initial creation
|
||||
* Jul 17, 2013 2185 bsteffen Cache computed grid reprojections.
|
||||
* Aug 27, 2013 2287 randerso Removed 180 degree adjustment required by error
|
||||
* in Maputil.rotation
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- -----------------------------------------
|
||||
* Mar 09, 2011 bsteffen Initial creation
|
||||
* Jul 17, 2013 2185 bsteffen Cache computed grid reprojections.
|
||||
* Aug 27, 2013 2287 randerso Removed 180 degree adjustment required by
|
||||
* error in Maputil.rotation
|
||||
* Jan 14, 2014 2661 bsteffen For vectors only keep uComponent and
|
||||
* vComponent, calculate magnitude and
|
||||
* direction on demand.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -71,13 +75,11 @@ public class GeneralGridData {
|
|||
|
||||
private GridGeometry2D gridGeometry;
|
||||
|
||||
private FloatBuffer scalarData;
|
||||
private FloatBufferWrapper scalarData;
|
||||
|
||||
private FloatBuffer direction = null;
|
||||
private FloatBufferWrapper uComponent = null;
|
||||
|
||||
private FloatBuffer uComponent = null;
|
||||
|
||||
private FloatBuffer vComponent = null;
|
||||
private FloatBufferWrapper vComponent = null;
|
||||
|
||||
private Unit<?> dataUnit;
|
||||
|
||||
|
@ -100,18 +102,16 @@ public class GeneralGridData {
|
|||
* used when both these representations are readily available to save time
|
||||
* if one or the other is needed later.
|
||||
*
|
||||
* @param magnitude
|
||||
* @param direction
|
||||
* @param uComponent
|
||||
* @param vComponent
|
||||
* @param dataUnit
|
||||
* @return
|
||||
* @deprecated Magnitude and direction are ignored, use
|
||||
* {@link #createVectorDataUV(GeneralGridGeometry, FloatBuffer, FloatBuffer, Unit)}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("unused")
|
||||
public static GeneralGridData createVectorData(
|
||||
GeneralGridGeometry gridGeometry, FloatBuffer magnitude,
|
||||
FloatBuffer direction, FloatBuffer uComponent,
|
||||
FloatBuffer vComponent, Unit<?> dataUnit) {
|
||||
return new GeneralGridData(gridGeometry, magnitude, direction,
|
||||
return new GeneralGridData(gridGeometry,
|
||||
uComponent, vComponent, dataUnit);
|
||||
}
|
||||
|
||||
|
@ -127,8 +127,17 @@ public class GeneralGridData {
|
|||
public static GeneralGridData createVectorData(
|
||||
GeneralGridGeometry gridGeometry, FloatBuffer magnitude,
|
||||
FloatBuffer direction, Unit<?> dataUnit) {
|
||||
return new GeneralGridData(gridGeometry, magnitude, direction, null,
|
||||
null, dataUnit);
|
||||
magnitude.rewind();
|
||||
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(
|
||||
GeneralGridGeometry gridGeometry, FloatBuffer uComponent,
|
||||
FloatBuffer vComponent, Unit<?> dataUnit) {
|
||||
return new GeneralGridData(gridGeometry, null, null, uComponent,
|
||||
return new GeneralGridData(gridGeometry, uComponent,
|
||||
vComponent, dataUnit);
|
||||
}
|
||||
|
||||
private GeneralGridData(GeneralGridGeometry gridGeometry,
|
||||
FloatBuffer scalarData, Unit<?> dataUnit) {
|
||||
this.gridGeometry = GridGeometry2D.wrap(gridGeometry);
|
||||
this.scalarData = scalarData;
|
||||
this.scalarData = new FloatBufferWrapper(scalarData, this.gridGeometry);
|
||||
;
|
||||
this.dataUnit = dataUnit;
|
||||
}
|
||||
|
||||
private GeneralGridData(GeneralGridGeometry gridGeometry,
|
||||
FloatBuffer magnitude, FloatBuffer direction,
|
||||
FloatBuffer uComponent, FloatBuffer vComponent, Unit<?> dataUnit) {
|
||||
this.gridGeometry = GridGeometry2D.wrap(gridGeometry);
|
||||
this.scalarData = magnitude;
|
||||
this.direction = direction;
|
||||
this.uComponent = uComponent;
|
||||
this.vComponent = vComponent;
|
||||
this.uComponent = new FloatBufferWrapper(uComponent, this.gridGeometry);
|
||||
this.vComponent = new FloatBufferWrapper(vComponent, this.gridGeometry);
|
||||
this.dataUnit = dataUnit;
|
||||
}
|
||||
|
||||
|
@ -187,31 +194,34 @@ public class GeneralGridData {
|
|||
return true;
|
||||
}
|
||||
if (scalarData != null) {
|
||||
scalarData.rewind();
|
||||
FloatBuffer newData = FloatBuffer.allocate(scalarData.capacity());
|
||||
while (scalarData.hasRemaining()) {
|
||||
newData.put((float) converter.convert(scalarData.get()));
|
||||
FloatBuffer oldData = scalarData.getBuffer();
|
||||
oldData.rewind();
|
||||
FloatBuffer newData = FloatBuffer.allocate(oldData.capacity());
|
||||
while (oldData.hasRemaining()) {
|
||||
newData.put((float) converter.convert(oldData.get()));
|
||||
}
|
||||
newData.rewind();
|
||||
scalarData = newData;
|
||||
scalarData = new FloatBufferWrapper(newData, gridGeometry);
|
||||
}
|
||||
if (uComponent != null) {
|
||||
uComponent.rewind();
|
||||
FloatBuffer newData = FloatBuffer.allocate(uComponent.capacity());
|
||||
while (uComponent.hasRemaining()) {
|
||||
newData.put((float) converter.convert(uComponent.get()));
|
||||
FloatBuffer oldData = uComponent.getBuffer();
|
||||
oldData.rewind();
|
||||
FloatBuffer newData = FloatBuffer.allocate(oldData.capacity());
|
||||
while (oldData.hasRemaining()) {
|
||||
newData.put((float) converter.convert(oldData.get()));
|
||||
}
|
||||
newData.rewind();
|
||||
uComponent = newData;
|
||||
uComponent = new FloatBufferWrapper(newData, gridGeometry);
|
||||
}
|
||||
if (vComponent != null) {
|
||||
vComponent.rewind();
|
||||
FloatBuffer newData = FloatBuffer.allocate(vComponent.capacity());
|
||||
while (vComponent.hasRemaining()) {
|
||||
newData.put((float) converter.convert(vComponent.get()));
|
||||
FloatBuffer oldData = vComponent.getBuffer();
|
||||
oldData.rewind();
|
||||
FloatBuffer newData = FloatBuffer.allocate(oldData.capacity());
|
||||
while (oldData.hasRemaining()) {
|
||||
newData.put((float) converter.convert(oldData.get()));
|
||||
}
|
||||
newData.rewind();
|
||||
vComponent = newData;
|
||||
vComponent = new FloatBufferWrapper(newData, gridGeometry);
|
||||
}
|
||||
dataUnit = unit;
|
||||
return true;
|
||||
|
@ -278,76 +288,56 @@ public class GeneralGridData {
|
|||
}
|
||||
|
||||
public boolean isVector() {
|
||||
return (scalarData != null && direction != null)
|
||||
|| (uComponent != null && vComponent != null);
|
||||
return (uComponent != null && vComponent != null);
|
||||
}
|
||||
|
||||
public FloatBuffer getMagnitude() {
|
||||
if (scalarData == null && uComponent != null && vComponent != null) {
|
||||
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 DataSource getMagnitude() {
|
||||
return new MagnitudeDataSource(uComponent, vComponent);
|
||||
}
|
||||
|
||||
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) {
|
||||
uComponent.rewind();
|
||||
vComponent.rewind();
|
||||
direction = FloatBuffer.allocate(uComponent.capacity());
|
||||
while (vComponent.hasRemaining()) {
|
||||
direction.put((float) Math.toDegrees(Math.atan2(
|
||||
uComponent.get(), vComponent.get())));
|
||||
}
|
||||
uComponent.rewind();
|
||||
vComponent.rewind();
|
||||
direction.rewind();
|
||||
}
|
||||
return direction;
|
||||
/**
|
||||
* @return the direction from which the vector originates. This is commonly
|
||||
* used in meteorology, espesially for winds. For example if a
|
||||
* meteorologist says "The wind direction is North" it means the
|
||||
* wind is coming from the north and moving to the south.
|
||||
* @see #getDirectionTo()
|
||||
*/
|
||||
public DataSource getDirectionFrom() {
|
||||
return new DirectionFromDataSource(uComponent, vComponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the direction a vector is going towards. This is the common
|
||||
* mathematical deffinition of a vector.
|
||||
* @see #getDirectionFrom()
|
||||
*/
|
||||
public DataSource getDirectionTo() {
|
||||
return new DirectionToDataSource(uComponent, vComponent);
|
||||
}
|
||||
|
||||
public FloatBuffer getUComponent() {
|
||||
if (uComponent == null && scalarData != null && direction != null) {
|
||||
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;
|
||||
return uComponent.getBuffer();
|
||||
}
|
||||
|
||||
public FloatBuffer getVComponent() {
|
||||
if (vComponent == null && scalarData != null && direction != null) {
|
||||
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;
|
||||
return vComponent.getBuffer();
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,10 +48,11 @@ import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
|||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 9, 2011 bsteffen Initial creation
|
||||
* Sep 24, 2013 2404 bclement match criteria built using GridStyleUtil
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- ----------------------------------------
|
||||
* Mar 09, 2011 bsteffen Initial creation
|
||||
* Sep 24, 2013 2404 bclement match criteria built using GridStyleUtil
|
||||
* Jan 14, 2014 2661 bsteffen Switch vectors to u,v only.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -104,15 +105,8 @@ public class GridResource<T extends AbstractResourceData> extends
|
|||
} else if (dataRecs.length == 2) {
|
||||
FloatBuffer mag = wrapDataRecord(dataRecs[0]);
|
||||
FloatBuffer dir = wrapDataRecord(dataRecs[1]);
|
||||
return GeneralGridData.createVectorData(gridGeometry, mag, dir,
|
||||
return GeneralGridData.createVectorDataUV(gridGeometry, mag, dir,
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -24,31 +24,39 @@ import org.opengis.referencing.operation.TransformException;
|
|||
/**
|
||||
* From AWIPS 1 GridPVDepict.C:
|
||||
*
|
||||
* This method determines whether the mapping between gridded data and the
|
||||
* display space is severe enough to require the gridded data to be remapped
|
||||
* before display.
|
||||
* This method determines whether the mapping between gridded data and the
|
||||
* display space is severe enough to require the gridded data to be remapped
|
||||
* before display.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 06/19/2012 14988 D. Friedman Initial revision
|
||||
* 09/24/2013 DR 15972 D. Friedman Do not require contiguous mapping.
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jun 19, 2012 14988 D. Friedman Initial revision
|
||||
* Sep 24, 2013 15972 D. Friedman Do not require contiguous mapping.
|
||||
* Jan 15, 2014 2661 bsteffen Disable output
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public class ConformalityUtil {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
public static boolean testConformality(GeneralGridGeometry sourceGG, GeneralGridGeometry destGG) {
|
||||
ConformalityUtil test = new ConformalityUtil(sourceGG, destGG);
|
||||
return test.testConformality();
|
||||
}
|
||||
|
||||
GeneralGridGeometry sourceGG;
|
||||
|
||||
GeneralGridGeometry destGG;
|
||||
|
||||
double minRatio;
|
||||
|
||||
double maxRatio;
|
||||
|
||||
MathTransform lastMT;
|
||||
|
||||
private ConformalityUtil(GeneralGridGeometry sourceGG, GeneralGridGeometry destGG) {
|
||||
|
@ -87,15 +95,20 @@ public class ConformalityUtil {
|
|||
double rr = maxRatio / minRatio;
|
||||
|
||||
if (! evaluated || maxRatio / minRatio > maxRatioRatio) {
|
||||
System.out.format("%s -> %s : not conformal enough (%f)\n",
|
||||
sourceGG, destGG, maxRatio / minRatio);
|
||||
if (DEBUG) {
|
||||
System.out.format("%s -> %s : not conformal enough (%f)\n",
|
||||
sourceGG, destGG, maxRatio / minRatio);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
resetRatios();
|
||||
|
||||
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;
|
||||
/*
|
||||
* This test is not necessary for AWIPS II because it can cope
|
||||
|
@ -109,8 +122,10 @@ public class ConformalityUtil {
|
|||
return false;
|
||||
*/
|
||||
} else {
|
||||
System.out.format("%s -> %s : conformal enough (%f, %f)\n",
|
||||
sourceGG, destGG, rr, maxRatio/minRatio);
|
||||
if (DEBUG) {
|
||||
System.out.format("%s -> %s : conformal enough (%f, %f)\n",
|
||||
sourceGG, destGG, rr, maxRatio / minRatio);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue