awips2/cave/com.raytheon.viz.gfe/localization/gfe/userPython/smartTools/Adjust.py
2022-05-05 12:34:50 -05:00

209 lines
8.7 KiB
Python

##
# 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.
##
# ----------------------------------------------------------------------------
# This software is in the public domain, furnished "as is", without technical
# support, and with no warranty, express or implied, as to its usefulness for
# any purpose.
#
# Adjust - Version 1.2
#
# A single dialog providing a combination of many simple mathematical
# operations (add, subtract, multiply, divide) optionally with
# elevation effects (most adjustment at mountains (highest elevation)
# or valleys (lowest elevation) or a specific elevation), optionally
# with edge effects (edge (ramp up over edge thickness) or taper
# (ramp up to middle)) and providing a single place to specify delta
# value, edge thickness and vector edit mode. When multiple effects
# are combined (except a constant change)- the tool carefully
# re-scales the adjustment so that at least one gridpoint gets the
# "delta value" adjustment and one gridpoint gets no adjustment.
#
# Makes many old single-use tools obsolete (Up, UpMtn, UpVly, Down,
# DownMtn, DownVly, UpwEdge, UpwTaper, DownwEdge, DownwTaper, Back,
# BackwEdge, BackwTaper, Veer, VeerwEdge, VeerwTaper, MultiplyDivide),
# and also adds some new combinations (Multiply Mountain with Taper,
# for example)
#
# Originally the idea of Greg Martin at SGX to combine all these
# tools into a single dialog - Thanks Greg!
#
# Author: Tim Barker - SOO Boise, ID
# History: 06/03/03 - Original Version
# 10/07/03 - More graceful handling of Query edit areas
# 02/23/04 - Version 1.1. Fix error when first tool run after GFE
# startup and no edit area specified (implying run over
# entire grid).
# 08/27/04 - Version 1.2. Fix handling of Query edit areas
# 07/21/10 - Ajust only magnitude when vector mode is set to BOTH
# ----------------------------------------------------------------------------
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------- -------- --------- ---------------------------------------------
# Feb 06, 2017 5959 randerso Removed Java .toString() calls
#
##
##
# This is an absolute override file, indicating that a higher priority version
# of the file will completely replace a lower priority version of the file.
##
ToolType = "numeric"
WeatherElementEdited = "variableElement"
ScreenList=["SCALAR","VECTOR"]
import numpy
from numpy import *
import SmartScript
VariableList=[]
VariableList.append(("Value:",1,"numeric"))
VariableList.append(("Action:","Add","radio",["Add","Subtract","Multiply","Divide"]))
VariableList.append(("Elevation:","None","radio",["None","Mountain","Valley","Specific"]))
VariableList.append(("Vectors:","Magnitude","radio",["Magnitude","Direction"]))
VariableList.append(("Edge:","Flat","radio",["Flat","Edge","Taper"]))
VariableList.append(("Edge Width:",5,"scale",[1,30],1))
VariableList.append(("Specific Elevation:",5000,"numeric"))
class Tool (SmartScript.SmartScript):
def __init__(self, dbss):
SmartScript.SmartScript.__init__(self, dbss)
def preProcessTool(self):
self.savemode=self.getVectorEditMode()
self.setVectorEditMode("Magnitude")
def postProcessTool(self):
self.setVectorEditMode(self.savemode)
def preProcessGrid(self,Topo,editArea,varDict):
#if type(editArea) is types.StringType:
# editArea=self.getEditArea(editArea)
ea=self.encodeEditArea(editArea)
#
# if no editArea is specified GFE will pass in an editArea that
# covers the whole grid. However, if this is the first tool
# called after GFE starts up - the edit area is None - so in that
# case just make ea one at all gridpoints
#
if ea is None:
ea=numpy.ones(Topo.shape, "int8")
elev=varDict["Elevation:"]
edge=varDict["Edge:"]
edgewidth=varDict["Edge Width:"]
elevmid=varDict["Specific Elevation:"]
#
# Make elevgrid 0-1 across edit area
#
if (elev=="None"):
elevgrid=ea.astype("float32")
else:
editAreaMask=ea
topoMask=editAreaMask*Topo
topoMaskMin = where(equal(topoMask, 0), float32(100000), topoMask)
maxtopo = amax(topoMask)
mintopo = amin(topoMaskMin)
topodiff=(maxtopo-mintopo)+0.0001
if (elev=="Mountain"):
elevgrid=editAreaMask*((Topo-mintopo)/topodiff)
elif (elev=="Valley"):
elevgrid=editAreaMask*((maxtopo-Topo)/topodiff)
else:
elevgrid=Topo*0.0
if maxtopo>elevmid:
abovediff=(maxtopo-elevmid)+0.0001
elevgrid=where(greater_equal(Topo,elevmid),(maxtopo-Topo)/abovediff,elevgrid)
if mintopo<elevmid:
belowdiff=(elevmid-mintopo)+0.0001
elevgrid=where(less(Topo,elevmid),(Topo-mintopo)/belowdiff,elevgrid)
elevgrid*=editAreaMask
#
# Make edgegrid 0-1 across edit area
#
if (edge=="Flat"):
edgegrid=ea
elif (edge=="Edge"):
edgegrid=self.taperGrid(editArea,int(edgewidth))
else:
wval=0
edgegrid=self.taperGrid(editArea,int(wval))
#
# combine elevgrid and edgegrid
#
self.deltagrid=elevgrid*edgegrid
#
# combined factor may not equal 1 anywhere - stretch it so it does
#
maxdelta=maximum.reduce(maximum.reduce(self.deltagrid))
if (maxdelta<1.0):
#
# If there is no change at all - set change to
# constant everywhere in edit area
#
if (maxdelta<0.01):
self.deltagrid=ea
else:
self.deltagrid*=(1.0/maxdelta)
def execute(self, variableElement, variableElement_GridInfo, varDict):
"Various Adjustments"
deltavalue=varDict["Value:"]
vect=varDict["Vectors:"]
action=varDict["Action:"]
if str(variableElement_GridInfo.getGridType()) != 'VECTOR':
if (action=="Add"):
newval=variableElement+(self.deltagrid*deltavalue)
elif (action=="Subtract"):
newval=variableElement-(self.deltagrid*deltavalue)
elif (action=="Multiply"):
newval=variableElement*(((deltavalue-1.0)*self.deltagrid)+1.0)
elif (action=="Divide"):
newval=variableElement/(((deltavalue-1.0)*self.deltagrid)+1.0)
newval = newval.astype(variableElement[0].dtype)
else:
mag=variableElement[0]
dir=variableElement[1]
if (vect=="Magnitude"):
if (action=="Add"):
newmag=mag+(self.deltagrid*deltavalue)
elif (action=="Subtract"):
newmag=mag-(self.deltagrid*deltavalue)
elif (action=="Multiply"):
newmag=mag*(((deltavalue-1.0)*self.deltagrid)+1.0)
elif (action=="Divide"):
newmag=mag/(((deltavalue-1.0)*self.deltagrid)+1.0)
else:
newmag=mag
if (vect=="Direction"):
if (action=="Add"):
newdir=dir+(self.deltagrid*deltavalue)
elif (action=="Subtract"):
newdir=dir-(self.deltagrid*deltavalue)
elif (action=="Multiply"):
newdir=dir*(((deltavalue-1.0)*self.deltagrid)+1.0)
elif (action=="Divide"):
newdir=dir*(((deltavalue-1.0)*self.deltagrid)+1.0)
else:
newdir=dir
newmag = newmag.astype(mag.dtype)
newdir = newdir.astype(dir.dtype)
newval=(newmag,newdir)
return newval