Smart Tools Answers to Exercises

Answer to Exercise Tool-1

ToolType = "numeric"
WeatherElementEdited = "SnowAmt"
from numpy import *
import SmartScript
class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
      SmartScript.SmartScript.__init__(self, dbss)
    def execute(self, QPF):
        "Tool to return QPF multiplied by 10"
        # Determine new value
        SnowAmt = QPF * 10
        # Return the new value
        return SnowAmt

Answer to Exercise Tool-2

ToolType = "numeric"
WeatherElementEdited = "SnowAmt"
from numpy import *
import SmartScript

class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)

    def execute(self, QPF, T):
        "Tool to calculate SnowAmt"

        SnowAmt = where(less(T, 20), QPF * 18,
                               where(less(T, 25), QPF * 14,
                               QPF * 10))
        # Return the new value
        return SnowAmt
 

Answer to Exercise Tool-3

ToolType = "numeric"
WeatherElementEdited = "SnowAmt"
from numpy import *
import SmartScript

VariableList = [
        ("Enter elevation" , 5000, "numeric"),
       ]
class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)

    def execute(self, QPF, T, Topo, varDict):
        "Tool to calculate SnowAmt"

        # Set up Variables from the varDict
        elevation = varDict["Enter elevation"]

        SnowAmt = where(less(T, 20), QPF * 18,
                               where(less(T, 25), QPF * 14,
                               QPF * 10))
        SnowAmt = where(less(Topo, elevation), 0, SnowAmt)
        # Return the new value
        return SnowAmt

Answer to Exercise SmartScript-1

ToolType = "numeric"
WeatherElementEdited = "QPF"
from numpy import *
import SmartScript

class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)

    def execute(self, GridTimeRange, varDict):
        "This tool accesses QPF and tp  grids directly"

        #  Get QPF and tp values
        qpf = self.getGrids("Fcst", "QPF", "SFC", GridTimeRange)
        tp = self.getGrids("BOU_D2D_NAM12", "tp","SFC", GridTimeRange)

        qpf = where(equal(qpf,0.0), tp, qpf)
        return qpf

Answer to Exercise SmartScript-2

ToolType = "numeric"
WeatherElementEdited = "QPF"
from numpy import *
import SmartScript

VariableList = [("Model:" , "", "model")]
class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)

    def execute(self, GridTimeRange, varDict):
        "This tool accesses QPF and tp  grids directly"

        model = varDict["Model:"]

        #  Get QPF and tp values
        qpf = self.getGrids("Fcst", "QPF", "SFC", GridTimeRange)
        tp = self.getGrids(model, "tp","SFC", GridTimeRange)

        qpf = where(equal(qpf,0.0), tp, qpf)
        return qpf

Answer to Exercise SmartScript-3

ToolType = "numeric"
WeatherElementEdited = "T"
from numpy import *
import SmartScript

VariableList = [("Model:" , "", "D2D_model")]
class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)

    def execute(self, GridTimeRange, Topo, varDict):
        "This tool accesses QPF and tp  grids directly"

        model = varDict["Model:"]

        # Convert Topo to meters
        topo_M = self.convertFtToM(Topo)

        # Make a sounding cubes for T
        # Height will increase in the sounding and be the
        # first dimension
        levels = ["MB1000","MB950","MB900","MB850","MB800",
        "MB750","MB700","MB650","MB600"]
        gh_Cube, t_Cube = self.makeNumericSounding(
            model, "t", levels, GridTimeRange)

        print "Cube shapes ", gh_Cube.shape, t_Cube.shape

        # Make an initial T grid with values of -200
        # This is an out-of-range value to help us identify values that
        # have already been set.
        T = (Topo * 0) - 200

        # Work "upward" in the cubes to assign T
        # We will only set the value once, i.e. the first time the
        # gh height is greater than the Topo
        # For each level
        for i in xrange(gh_Cube.shape[0]):
                # where ( gh > topo and T == -200),
                #       set to t_Cube value, otherwise keep value already set))
                T = where(logical_and(greater(gh_Cube[i], topo_M), equal(T,-200)), t_Cube[i], T)

        # Convert from K to F
        T_F = self.convertKtoF(T)

        return T_F

Answer to Exercise SmartScript-4

ToolType = "numeric"
WeatherElementEdited = "T"
from numpy import *
import SmartScript

VariableList = [("Model:" , "", "D2D_model")]
class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)

    def execute(self, GridTimeRange, Topo, varDict):
        "This tool accesses QPF and tp  grids directly"

        model = varDict["Model:"]

        # Convert Topo to meters
        topo_M = self.convertFtToM(Topo)

        # Make a sounding cubes for T
        # Height will increase in the sounding and be the
        # first dimension
        levels = ["MB1000","MB950","MB900","MB850","MB800",
        "MB750","MB700","MB650","MB600"]
        gh_Cube, t_Cube = self.makeNumericSounding(
             model, "t", levels, GridTimeRange)

        print "Cube shapes ", gh_Cube.shape, t_Cube.shape

        # Make an initial T grid with values of -200
        # This is an out-of-range value to help us identify values that
        # have already been set.
        T = (Topo * 0) - 200

        # Work "upward" in the cubes to assign T
        # We will only set the value once, i.e. the first time the
        # gh height is greater than the Topo
        # For each level
        for i in xrange(gh_Cube.shape[0]):
                # where ( gh > topo and T == -200 ),
                #       set to t_Cube value, otherwise keep value already set))
                notSet = equal(T, -200)
                aboveGround = greater(gh_Cube[i], topo_M)
                readyToSet = logical_and(notSet, aboveGround)
                T = where(readyToSet, t_Cube[i], T)

        # Convert from K to F
        T_F = self.convertKtoF(T)

        return T_F

Answer to Exercise SmartScript-5

ToolType = "numeric"
WeatherElementEdited = "None"
from numpy import *

ScreenList = ["T","Td"]

import SmartScript

class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)

    def execute(self, T, Td, GridTimeRange):
        "Creates a temporary element, TempRH"

        # Determine new value
        Tc = .556 * (T - 32.0)
        Tdc = .556 * (Td - 32.0)
        Vt = 6.11 * pow(10,(Tc * 7.5 / (Tc + 237.3)))
        Vd = 6.11 * pow(10,(Tdc * 7.5 / (Tdc + 237.3)))
        RH = (Vd / Vt) * 100.0

        # clip
        RH = clip(RH, 0.0, 100.0)

        # Create Element and add Grid
        self.createGrid("TempModel", "TempRH", "SCALAR", RH, GridTimeRange,
          descriptiveName="TempRH",
          timeConstraints=(0, 3600,3600), minAllowedValue = 0.0,
          maxAllowedValue = 100.0, units="%")

Answer to Exercise SmartScript-6

ToolType = "numeric"
WeatherElementEdited = "Wx"
from numpy import *

import SmartScript

class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)

    def execute(self, PoP, Wx):
        # Assign Wx based on PoP

        # Separate Wx into components
        wxValues = Wx[0]
        keys = Wx[1]

        wxValues = where( less(PoP, 20), self.getIndex("<NoCov>:<NoWx>:<NoInten>:<NoVis>:",keys), wxValues)
        wxValues = where(logical_and( greater_equal(PoP, 20), less(PoP, 35)),  self.getIndex("Chc:R:-:<NoVis>:" ,keys), wxValues)
        wxValues = where(logical_and( greater_equal(PoP, 35), less(PoP, 55)),  self.getIndex("Sct:RW:m:<NoVis>:" ,keys), wxValues)
        wxValues = where(greater_equal(PoP, 55),  self.getIndex("Wide:R:+:<NoVis>:" ,keys), wxValues)

        return (wxValues, keys)

Answer to Exercise SmartScript-7

ToolType = "numeric"
WeatherElementEdited = "PoP"
from numpy import *

import SmartScript

class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)

    def execute(self, PoP, Wx):
         # Assign PoP based on Wx

          PoP = where(self.wxMask(Wx, "<NoCov>:"),  0,   PoP)

          # Here we need to require a regular expression to avoid confusion between "Chc" and "SChc" and "Sct" and "WSct"
          PoP = where(self.wxMask(Wx, "^Chc:", 1),  25,   PoP)
          PoP = where(self.wxMask(Wx, "^Sct:", 1),  55,   PoP)

          PoP = where(self.wxMask(Wx, "Wide:"),  80,   PoP)

          return PoP

Answer to Exercise Procedure-1

MenuItems = ["Edit"]
ToolList = [
            ("AdjustValue_Up", "variableElement"),
            ("Smooth", "variableElement"),
          ]
import SmartScript
class Procedure (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)
    def execute(self, editArea, timeRange, varDict):
        # Calls each Smart Tool: T_Tool, PoP_Tool, Wind_Tool
        for toolName, elementName in ToolList:
              error = self.callSmartTool(toolName, elementName,
                              editArea, timeRange, varDict)
              if error is not None:
                  break

Answer to Exercise Procedure-2

import SmartScript
VariableList = [("Model:" , "", "D2D_model")]
class Procedure (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)
 
    def execute(self, editArea, varDict):
        """Copy from model, create grids, run smart tool."""
        model = varDict["Model:"]
        databaseID = self.getDatabase(model)
        timeRange = self.createTimeRange(0, 12, "Database", databaseID)
        elements = ['T', 'Wind','Wx']
        self.copyCmd(elements, databaseID, timeRange)
        self.createFromScratchCmd(['T'], timeRange, repeat=3, duration=1)
        self.callSmartTool("ExSS4","T", editArea, timeRange, varDict,
               missingDataMode="Create")

Answer to Exercise Procedure-3

**Running Revised Exercise Procedure-1 using runProcedure:

   ./runProcedure -n Proc1 -u hansen -c gfeConfig -a CO_Boulder -t Tonight

**Revised Procedure-1  (does not use variableElement)

MenuItems = ["Edit"]
ToolList = [
            ("AdjustValue_Up", "T"),
            ("Smooth", "T"),
          ]
import SmartScript
class Procedure (SmartScript.SmartScript):
    def __init__(self, dbss):
        SmartScript.SmartScript.__init__(self, dbss)
    def execute(self, editArea, timeRange, varDict):
        # Calls each Smart Tool: T_Tool, PoP_Tool, Wind_Tool
        for toolName, elementName in ToolList:
              error = self.callSmartTool(toolName, elementName,
                              editArea, timeRange, varDict)
              if error is not None:
                  break

Answer to Exercise Utility-1

New Utility named:  Common

import SmartScript

class Common(SmartScript.SmartScript):
    def __init__(self, dbss, eaMgr, mdMode=None, toolType="numeric"):
        SmartScript.SmartScript.__init__(self, dbss)
        self.setUp(eaMgr, mdMode, toolType)

    # Include your utility methods here
    def _convertFtToM(self, value):
        return value/3.28084

Smart Tool:

ToolType = "numeric"
WeatherElementEdited = "T"
from Numeric import *

import SmartScript
import Common

VariableList = [("Model:" , "", "D2D_model")]

class Tool (SmartScript.SmartScript):
    def __init__(self, dbss):
        self._dbss = dbss
        SmartScript.SmartScript.__init__(self, dbss)

    def execute(self, GridTimeRange, Topo, varDict):
        "This tool accesses QPF and tp  grids directly"
        self._common = Common.Common(self._dbss, self.eaMgr())

        # Convert Topo to meters
        topo_M = self._common._convertFtToM(Topo)

        # Make a sounding cubes for T
        # Height will increase in the sounding and be the
        # first dimension
        levels = ["MB1000","MB950","MB900","MB850","MB800",
        "MB750","MB700","MB650","MB600"]
        gh_Cube, t_Cube = self.makeNumericSounding(
            model, "t", levels, GridTimeRange)

        print "Cube shapes ", gh_Cube.shape, t_Cube.shape

        # Make an initial T grid with values of -200
        # This is an out-of-range value to help us identify values that
        # have already been set.
        T = (Topo * 0) - 200

        # Work "upward" in the cubes to assign T
        # We will only set the value once, i.e. the first time the
        # gh height is greater than the Topo
        # For each level
        for i in xrange(gh_Cube.shape[0]):
                # where ( gh > topo and T == -200),
                #       set to t_Cube value, otherwise keep value already set))
                T = where(logical_and(greater(gh_Cube[i], topo_M), equal(T,-200)), t_Cube[i], T)

        # Convert from K to F
        T_F = self.convertKtoF(T)

        return T_F