Example #1
0
    def plot_windbarb(self, u, v, P=None, template=None, type="uv", bg=0):
        if type == "uv":
            n = numpy.ma.sqrt(u * u + v * v)
            d = numpy.ma.arccos(u / n)
            d = numpy.ma.where(numpy.ma.less(v, 0.0), -d, d)

        if P is None:
            P = u.getLevel()
            if P is None:
                P = u.getAxis(-1)
            P = P.clone()
            try:  # tries to convert to Pa
                for i in range(len(P)):
                    uni = unidata.udunits(P[i], P.units)
                    P[i] = uni.to("Pa").value
            except Exception:
                pass
            P = P[:]

        n1 = n / self.windbarbsscales[0]
        n1 = n1.astype("i")
        n2 = (n - n1 * self.windbarbsscales[0]) / self.windbarbsscales[1]
        n2 = n2.astype("i")
        n3 = (n - n1 * self.windbarbsscales[0] - n2 * self.windbarbsscales[1]) / self.windbarbsscales[2]
        n3 = n3.astype("i")

        # print 'n1:',n1
        # print 'n2:',n2
        # print 'n3:',n3

        nitems = len(P)
        for i in range(nitems):
            if not (MV2.isMA(n[i])):
                p = P[i]
                # Figure out the altitude to plot it (y coord) !
                dum, Y = self.TP2XY(273, p)
                lin = self.x.createline()
                lin.viewport = [template.data.x1, template.data.x2, template.data.y1, template.data.y2]
                lin.worldcoordinate = [-1, 1, -1, 1]
                lin.x = [0, 0]
                lin.y = [-1, 1]
                self.displays.append(self.x.plot(lin, bg=bg))
                lin = self.x.createline()
                lin.viewport = [template.data.x1, template.data.x2, template.data.y1, template.data.y2]
                lin.worldcoordinate = [-1, 1, self.ymin, self.ymax]
                # Set everything correctly y wise
                rw = 2 / (self.ymax - self.ymin)
                if self.x.islandscape():
                    r = 1.375
                else:
                    r = 0.72727272
                rv = (template.data.x2 - template.data.x1) / (template.data.y2 - template.data.y1)
                rw = 1.0 / rw
                x, y = self.make_barb(n[i], d[i], n1[i], n2[i], n3[i], rw * r * rv, Y)
                lin.x = x
                lin.y = y
                lin.linetype = ["solid"]
                self.displays.append(self.x.plot(lin, bg=bg))
Example #2
0
class Gth(object):
    def TP2XY(self, T, P):
        x, y = self._TP2XY(T, P)
        try:
            x = float(x)
            y = float(y)
        except:
            pass
        return x, y

    def XY2TP(self, X, Y):
        t, p = self._XY2TP(X, Y)
        try:
            t = float(t)
            p = float(p)
        except:
            pass
        return t, p

    def setdiagramdefs(self):
        # Figures out which kind of diagram we're drawing
        if self.type[:2] == 'sk':
            self._TP2XY = self.TP2XYskewT
            self._XY2TP = self.XY2TPskewT
        elif self.type[:2] == 'em':
            self._TP2XY = self.TP2XYemagram
            self._XY2TP = self.XY2TPemagram
        elif self.type[:2] == 'te':
            self._TP2XY = self.TP2XYtephigram
            self._XY2TP = self.XY2TPtephigram
        elif self.type[:2] == 'st':
            self._TP2XY = self.TP2XYstuve
            self._XY2TP = self.XY2TPstuve
        elif self.type[:2] == 'cu':
            # user defined diagram
            pass
        else:
            raise ValueError, 'Error type: ' + repr(
                self.type) + ' is not a valid diagram type'

        ## Gets the xs for each corner
        dwx1 = self.datawc_x1 + 273.16
        dwx2 = self.datawc_x2 + 273.16
        dwy1 = self.datawc_y1 * 100.
        dwy2 = self.datawc_y2 * 100.
        self.xmin, self.ymin = self.TP2XY(dwx1, dwy1)
        self.xmax, dum = self.TP2XY(dwx2, dwy1)
        dum, self.ymax = self.TP2XY(dwx2, dwy2)

    def __del__(self):
        self.x.removeobject(self._isotherms)
        self.x.removeobject(self._isothermsfilled)
        self.x.removeobject(self._isobars)
        self.x.removeobject(self._dryadiabats)
        self.x.removeobject(self._pseudoadiabats)
        self.x.removeobject(self._mixingratio)
        self.x.removeobject(self_line)

    def __init__(self, x=None, type='skewT', name='default'):
        self.displays = []
        if x is None:
            self.x = vcs.init()
        else:
            self.x = x

##         if name in thermo_objects:
##             raise Exception,"Error thermo object %s already exists" % name
##         thermo_objects.append(name)
        self.gname = 'Gth'
        self._name = name
        ## Set some constants
        self.k = 0.286
        self.R = 287.04
        self.cp = 1004.
        ##         self.L=2.5E3

        ## World coordiantes in C/hPa
        self._datawc_x1 = -25.
        self._datawc_x2 = 50.
        self._datawc_y1 = 1000.
        self._datawc_y2 = 100.

        ## Skewness (for skewT)
        self._skewness = -35.

        ## Sets the diagram type
        self._type = type
        self.setdiagramdefs()

        ## Level of detail
        self._detail = 25

        ## Draw mixing ratio and pseudoadiabats up to
        self._Pmaxmixingratio = 200

        ## Do we draw all the lines on the diagram ? (default, yes)
        self._drawisothermsfilled = 1
        self._drawisotherms = 1
        self._drawisobars = 1
        self._drawdryadiabats = 1
        self._drawpseudoadiabats = 1
        self._drawmixingratio = 1

        # Creates the isolines
        self._isotherms = self.x.createisoline()
        self._isobars = self.x.createisoline()
        self._dryadiabats = self.x.createisoline()
        self._pseudoadiabats = self.x.createisoline()
        self._mixingratio = self.x.createisoline()
        self._isothermsfilled = self.x.createisofill()

        # Isofill stuff for temperatures
        self._isothermsfilled.levels = [[-200, -190], [-180,
                                                       -170], [-160, -150],
                                        [-140, -130], [-120, -110],
                                        [-100, -90], [-80, -70], [-60, -50],
                                        [-40, -30], [-20, -10], [0, 10],
                                        [20, 30], [40, 50], [60, 70], [80, 90],
                                        [100, 110], [120, 130], [140, 150],
                                        [160, 170], [180, 190], [200, 210]]
        ##         self.isothermsfilled.levels=([-240.0, -200.0], [-160.0, -120.0], [-80.0, -40.0], [0.0, 40.0], [80.0, 120.0])
        self._isothermsfilled.fillareacolors = [
            253,
        ] * 50
        self._isothermsfilled.xticlabels1 = {}
        self._isothermsfilled.yticlabels1 = {}

        # Isotherms
        self._isotherms.level = list(range(-200, 200, 10))
        self._isotherms.linecolors = [
            249,
        ]
        self._isotherms.line = ['solid']
        self._isotherms.label = 'y'

        # Isobars default settings
        self._isobars.linecolors = [249]
        self._isobars.line = ['solid']
        self._isobars.label = 'n'

        # Dry adiabatics
        self._dryadiabats.label = 'y'
        self._dryadiabats.linecolors = [
            249,
        ]
        self._dryadiabats.line = ['solid']
        ##         self._dryadiabats.level=range(-40,170,10)

        # Pseudoadiabatics
        self._pseudoadiabats.linecolors = [
            243,
        ]
        self._pseudoadiabats.line = ['solid']
        self._pseudoadiabats.label = 'y'
        ##         self._pseudoadiabats.level=vcs.mkevenlevels(-40,40,40)

        # Mixing ratio
        self._mixingratio.line = ['long-dash']
        self._mixingratio.linecolors = [
            243,
        ]
        self._mixingratio.level = [
            .1, .2, .4, .6, .8, 1., 1.5, 2., 2.5, 3, 4, 5, 6, 7, 8, 9, 10, 12,
            14, 16, 18, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 68
        ]
        self._mixingratio.label = 'y'

        # Windbarb
        self._windbarbsscales = [25., 10., 5.]

        # Lines for plot
        self._line = self.x.createline()

    def list(self):
        print '----------ThermodynamicDiagrma (Gth) member (attribute) listings----------'
        print 'graphic method = Gth'
        print 'name =', self.name
        print 'type =', self.type
        if self.type[:2] == 'sk':
            print 'skewness:', self.skewness
        print 'detail =', self.detail
        print 'datawc_x1 =', self.datawc_x1
        print 'datawc_x2 =', self.datawc_x2
        print 'datawc_y1 =', self.datawc_y1
        print 'datawc_y2 =', self.datawc_y2
        print 'Pmaxmixingratio =', self.Pmaxmixingratio
        print 'isotherms =', self.isotherms.name
        print 'drawisotherms =', self.drawisotherms
        print 'isothermsfilled =', self.isothermsfilled.name
        print 'drawisothermsfilled =', self.drawisothermsfilled
        print 'isobars =', self.isobars.name
        print 'drawisobars =', self.drawisobars
        print 'dryadiabats =', self.dryadiabats.name
        print 'drawdryadiabats =', self.drawdryadiabats
        print 'pseudoadiabats =', self.pseudoadiabats.name
        print 'drawpseudoadiabats =', self.drawpseudoadiabats
        print 'mixingratio =', self.mixingratio.name
        print 'drawmixingratio =', self.drawmixingratio
        ##         print 'windbarbs =',self.windbarbs.name
        print 'windbarbsscales =', self.windbarbsscales
        print 'linecolor', self.line.color[0]
        print 'linewidth', self.line.width[0]
        print 'linetype', self.line.type[0]

    __slots__ = [
        '_TP2XY',
        '_XY2TP',
        ##        'TP2XYskewT',
        ##        'TP2XYemagram',
        ##        'TP2XYtephigram',
        ##        'TP2XYstuve',
        'gname',
        'name',
        '_name',
        'displays',
        '_displays',
        'detail',
        '_detail',
        'R',
        'cp',
        'k',
        'datawc_x1',
        'datawc_x2',
        'datawc_y1',
        'datawc_y2',
        '_datawc_x1',
        '_datawc_x2',
        '_datawc_y1',
        '_datawc_y2',
        'type',
        '_type',
        'xmin',
        'xmax',
        'ymin',
        'ymax',
        'x',
        'Pmaxmixingratio',
        'isotherms',
        'drawisotherms',
        'isothermsfilled',
        'drawisothermsfilled',
        'isobars',
        'drawisobars',
        'dryadiabats',
        'drawdryadiabats',
        'pseudoadiabats',
        'drawpseudoadiabats',
        'mixingratio',
        'drawmixingratio',
        'windbarbs',
        'windbarbsscales',
        'skewness',
        'linecolor',
        'linewidth',
        'linetype',
        'line',
        'linecolor',
        'linewidth',
        'linetype',
        '_Pmaxmixingratio',
        '_isotherms',
        '_drawisotherms',
        '_isothermsfilled',
        '_drawisothermsfilled',
        '_isobars',
        '_drawisobars',
        '_dryadiabats',
        '_drawdryadiabats',
        '_pseudoadiabats',
        '_drawpseudoadiabats',
        '_mixingratio',
        '_drawmixingratio',
        '_windbarbs',
        '_windbarbsscales',
        '_skewness',
        '_line',
        '_linecolor',
        '_linewidth',
        '_linetype',
    ]

    def _getskewness(self):
        return self._skewness

    def _setskewness(self, value):
        VCS_validation_functions.checkName(self, 'skewness', value)
        if self.type[:2] != 'sk':
            raise ValueError, 'skewness can only be set for skewT type diagrams'
        value = VCS_validation_functions.checkIntFloat(self, 'skewness', value)
        self._skewness = value
        self.setdiagramdefs()

    skewness = property(_getskewness, _setskewness, None,
                        'Skewness of skewT diagram')

    def _getwindbarbsscales(self):
        return self._windbarbsscales

    def _setwindbarbsscales(self, value):
        value = VCS_validation_functions.checkListOfNumbers(self,
                                                            'windbarbsscales',
                                                            value,
                                                            minelements=3,
                                                            maxelements=3)
        self._windbarbsscales = value

    windbarbsscales = property(
        _getwindbarbsscales, _setwindbarbsscales, None,
        'WindBarbs scaless: Triangles, Full Barbs, Half Barb\ndefault is [25,10,5]'
    )

    def _getdrawpseudoadiabats(self):
        return self._drawpseudoadiabats

    def _setdrawpseudoadiabats(self, value):
        value = VCS_validation_functions.checkOnOff(self, 'drawpseudoadiabats',
                                                    value)
        self._drawpseudoadiabats = value

    drawpseudoadiabats = property(
        _getdrawpseudoadiabats, _setdrawpseudoadiabats, None,
        'Draw the pseudo-adiabats ? (1/0) or (y/n)\nAlso called moist-adiabats'
    )

    def _getdrawmixingratio(self):
        return self._drawmixingratio

    def _setdrawmixingratio(self, value):
        value = VCS_validation_functions.checkOnOff(self, 'drawmixingratio',
                                                    value)
        self._drawmixingratio = value

    drawmixingratio = property(
        _getdrawmixingratio, _setdrawmixingratio, None,
        'Draw the pseudo-adiabats ? (1/0) or (y/n)\nAlso called moist-adiabats'
    )

    def _getdrawdryadiabats(self):
        return self._drawdryadiabats

    def _setdrawdryadiabats(self, value):
        value = VCS_validation_functions.checkOnOff(self, 'drawdryadiabats',
                                                    value)
        self._drawdryadiabats = value

    drawdryadiabats = property(_getdrawdryadiabats, _setdrawdryadiabats, None,
                               'Draw the dryadiabats ? (1/0) or (y/n)')

    def _getdrawisobars(self):
        return self._drawisobars

    def _setdrawisobars(self, value):
        value = VCS_validation_functions.checkOnOff(self, 'drawisobars', value)
        self._drawisobars = value

    drawisobars = property(_getdrawisobars, _setdrawisobars, None,
                           'Draw the isobars ? (1/0) or (y/n)')

    def _getdrawisothermsfilled(self):
        return self._drawisothermsfilled

    def _setdrawisothermsfilled(self, value):
        value = VCS_validation_functions.checkOnOff(self,
                                                    'drawisothermsfilled',
                                                    value)
        self._drawisothermsfilled = value

    drawisothermsfilled = property(
        _getdrawisothermsfilled, _setdrawisothermsfilled, None,
        'Draw the isothermsfilled ? (1/0) or (y/n)')

    def _getdrawisotherms(self):
        return self._drawisotherms

    def _setdrawisotherms(self, value):
        value = VCS_validation_functions.checkOnOff(self, 'drawisotherms',
                                                    value)
        self._drawisotherms = value

    drawisotherms = property(_getdrawisotherms, _setdrawisotherms, None,
                             'Draw the isotherms ? (1/0) or (y/n)')

    def _getline(self):
        return self._line

    def _setline(self, value):
        value = VCS_validation_functions.checkLine(self, 'line', value)
        if isinstance(value, str):
            self._line = self.x.getline(value)
        else:
            self._line = value

    line = property(
        _getline, _setline, None,
        'Line graphic method to use to draw the profile\nUse line.list() to see attributes'
    )

    def _getlinecolor(self):
        return self._line.color

    def _setlinecolor(self, value):
        value = VCS_validation_functions.checkColor(self, 'linecolor', value)
        self._line.color = [value]

    linecolor = property(
        _getlinecolor, _setlinecolor, None,
        'Color Line graphic method to use to draw the profile\nUse line.list() to see attributes'
    )

    def _getlinewidth(self):
        return self._line.width

    def _setlinewidth(self, value):
        if not isinstance(value, (int, float, long)):
            raise 'Error width must be a number'
        if not 1 < value < 300:
            raise 'Error width must be between 1 and 300'
        self._line.width = [value]

    linewidth = property(
        _getlinewidth, _setlinewidth, None,
        'Width Line graphic method to use to draw the profile\nUse line.list() to see attributes'
    )

    def _getlinetype(self):
        return self._line.type

    def _setlinetype(self, value):
        self._line.type = [value]

    linetype = property(
        _getlinetype, _setlinetype, None,
        'Type Line graphic method to use to draw the profile\nUse line.list() to see attributes'
    )

    def _getwindbarbs(self):
        return self._windbarbs

    def _setwindbarbs(self, value):
        value = VCS_validation_functions.checkLine(self, 'windbarbs', value)
        self._windbarbs = value

    windbarbs = property(
        _getwindbarbs, _setwindbarbs, None,
        'Line graphic method to use to draw the windbarbs\nUse windbarbs.list() to see attributes'
    )

    def _getdryadiabats(self):
        return self._dryadiabats

    def _setdryadiabats(self, value):
        value = VCS_validation_functions.checkIsoline(self, 'dryadiabats',
                                                      value)
        self._dryadiabats = value

    dryadiabats = property(
        _getdryadiabats, _setdryadiabats, None,
        'Isoline graphic method to use to draw the dryadiabats\nUse dryadiabats.list() to see attributes'
    )

    def _getpseudoadiabats(self):
        return self._pseudoadiabats

    def _setpseudoadiabats(self, value):
        value = VCS_validation_functions.checkIsoline(self, 'pseudoadiabats',
                                                      value)
        self._pseudoadiabats = value

    pseudoadiabats = property(
        _getpseudoadiabats, _setpseudoadiabats, None,
        'Isoline graphic method to use to draw the pseudoadiabats\nUse pseudoadiabats.list() to see attributes'
    )

    def _getmixingratio(self):
        return self._mixingratio

    def _setmixingratio(self, value):
        value = VCS_validation_functions.checkIsoline(self, 'mixingratio',
                                                      value)
        self._mixingratio = value

    mixingratio = property(
        _getmixingratio, _setmixingratio, None,
        'Isoline graphic method to use to draw the mixingratio\nUse mixingratio.list() to see attributes'
    )

    def _getisobars(self):
        return self._isobars

    def _setisobars(self, value):
        value = VCS_validation_functions.checkIsoline(self, 'isobars', value)
        self._isobars = value

    isobars = property(
        _getisobars, _setisobars, None,
        'Isoline graphic method to use to draw the isobars\nUse isobars.list() to see attributes'
    )

    def _getisothermsfilled(self):
        return self._isothermsfilled

    def _setisothermsfilled(self, value):
        value = VCS_validation_functions.checkIsofill(self, 'isothermsfilled',
                                                      value)
        self._isothermsfilled = value

    isothermsfilled = property(
        _getisothermsfilled, _setisothermsfilled, None,
        'Isofill graphic method to use to draw the isothermsfilled\nUse isothermsfilled.list() to see attributes'
    )

    def _getisotherms(self):
        return self._isotherms

    def _setisotherms(self, value):
        value = VCS_validation_functions.checkIsoline(value)
        self._isotherms = value

    isotherms = property(
        _getisotherms, _setisotherms, None,
        'Isoline graphic method to use to draw the isotherms\nUse isotherms.list() to see attributes'
    )

    def _getPmaxmixingratio(self):
        return self._Pmaxmixingratio

    def _setPmaxmixingratio(self, value):
        value = VCS_validation_functions.checkIntFloat(self, 'Pmaxmixingratio',
                                                       value)
        self._Pmaxmixingratio = value

    Pmaxmixingratio = property(
        _getPmaxmixingratio, _setPmaxmixingratio, None,
        'Pressure after which mixing ratio and pseudoadiats curves are not drawn anymore (hPa)'
    )

    def _getdetail(self):
        return self._detail

    def _setdetail(self, value):
        value = VCS_validation_functions.checkIntFloat(self, 'detail', value)
        self._detail = value

    detail = property(
        _getdetail, _setdetail, None,
        'Smoothness of contours/graphics\nhigher value means smoother (and slower) plots'
    )

    def _gettype(self):
        return self._type

    def _settype(self, value):
        VCS_validation_functions.checkName(self, 'type', value)
        if not isinstance(value, str):
            raise ValueError, 'Type should be a string'
        value = value.lower()
        if not value[:2] in ['sk', 'te', 'st', 'cu', 'em']:
            raise ValueError, 'Error Thermodynamic Diagram type must skewT, Tephigram, Emmagram, Stuve or Custom'
        self._type = value
        self.setdiagramdefs()

    type = property(
        _gettype, _settype, None,
        'Thermodynamic Diagram type, one of: skewT, Tephigram, Emmagram, Stuve or Custom'
    )

    def _getname(self):
        return self._name

    def _setname(self, value):
        value = VCS_validation_functions.checkname(self, 'name', value)
        self._name = value

    name = property(_getname, _setname, None, 'Name of the Graphic method')

    def _getdatawc_x1(self):
        return self._datawc_x1

    def _setdatawc_x1(self, value):
        value = VCS_validation_functions.checkIntFloat(self, 'datawc_x1',
                                                       value)
        self._datawc_x1 = value
        self.setdiagramdefs()

    datawc_x1 = property(_getdatawc_x1, _setdatawc_x1, None,
                         'Temperature of lower left corner (in C)')

    def _getdatawc_x2(self):
        return self._datawc_x2

    def _setdatawc_x2(self, value):
        value = VCS_validation_functions.checkIntFloat(self, 'datawc_x2',
                                                       value)
        self._datawc_x2 = value
        self.setdiagramdefs()

    datawc_x2 = property(_getdatawc_x2, _setdatawc_x2, None,
                         'Temperature of lower right corner (in C)')

    def _getdatawc_y1(self):
        return self._datawc_y1

    def _setdatawc_y1(self, value):
        value = VCS_validation_functions.checkIntFloat(self, 'datawc_y1',
                                                       value)
        self._datawc_y1 = value
        self.setdiagramdefs()

    datawc_y1 = property(_getdatawc_y1, _setdatawc_y1, None,
                         'Minimum Pressure (in hPa)')

    def _getdatawc_y2(self):
        return self._datawc_y2

    def _setdatawc_y2(self, value):
        value = VCS_validation_functions.checkIntFloat(self, 'datawc_y2',
                                                       value)
        self._datawc_y2 = value
        self.setdiagramdefs()

    datawc_y2 = property(_getdatawc_y2, _setdatawc_y2, None,
                         'Maximum Pressure (in hPa)')

    def _getdisplays(self):
        return self._displays

    def _setdisplays(self, value):
        if not isinstance(value, list):
            raise Exception, "displays must be a list of displays"
        for v in value:
            if not isinstance(v, vcs.displayplot.Dp):
                raise Exception, "displays must be a list of displays"
        self._displays = value

    displays = property(_getdisplays, _setdisplays, None, "List of displays")

    def plot_pseudo(self, template, bg):
        """
        ## Ok this is pathetic but i can't get it to work any other way!!!
        ## We'll have to do the integration for each levels
        """
        levs = self.pseudoadiabats.level
        levels = []
        for l in levs:
            levels.append(l[0])
        ## Ok we now have the required levels
        xs = []
        ys = []
        xstxt = []
        ystxt = []
        txt = []
        for il in range(len(levels)):
            l = levels[il]
            tmpxs = []
            tmpys = []
            t, p = LiftWet(l + 273.15, self.datawc_y1 * 100.,
                           self.Pmaxmixingratio * 100., 25000. / self.detail)
            nt = len(t)
            if il % 3 == 0:
                crit1 = .05
                crit2 = .95
            elif il % 3 == 1:
                crit1 = .2
                crit2 = .9
            elif il % 3 == 2:
                crit1 = .32
                crit2 = .85
            for i in range(nt):
                tx, ty = self.TP2XY(t[i], p[i])
                tmpxs.append(tx)
                tmpys.append(ty)
                if ((i - 1.) / nt < crit1 < i / float(nt)) or (
                    (i - 1.) / nt < crit2 < i / float(nt)):
                    xstxt.append(tx)
                    ystxt.append(ty)
                    txt.append(str(l))
            xs.append(tmpxs)
            ys.append(tmpys)
        l = self.x.createline()
        l.color = self.pseudoadiabats.linecolors[0]
        l.viewport = [
            template.data.x1, template.data.x2, template.data.y1,
            template.data.y2
        ]
        l.worldcoordinate = [self.xmin, self.xmax, self.ymin, self.ymax]
        l.x = xs
        l.y = ys
        self.displays.append(self.x.plot(l, bg=bg))
        t = self.x.createtext()
        t.viewport = [
            template.data.x1, template.data.x2, template.data.y1,
            template.data.y2
        ]
        t.worldcoordinate = [self.xmin, self.xmax, self.ymin, self.ymax]
        t.color = l.color[0]
        t.x = xstxt
        t.y = ystxt
        t.string = txt
        t.height = 10
        self.displays.append(self.x.plot(t, bg=bg))

    def clear(self):
        self.displays = []
        self.x.clear()

    def plot_TP(self, T, P=None, template=None, bg=0):
        if template is None:
            template = 'thdiags_template'
        elif not isinstance(template, str):
            template = template.name
        try:
            isotemplate = self.x.createtemplate(template)
        except:
            isotemplate = self.x.gettemplate(template)
        self.plotIsos(template, bg=bg)
        if P is None:
            P = getPvalues(T)

        while T.rank() > 1:
            T = T[0]
        xs = []
        ys = []
        for i in range(len(T)):
            t = T[i]
            p = P[i]
            tx, ty = self.TP2XY(t, p)
            try:
                tx = float(tx)
                ty = float(ty)
                if numpy.ma.is_masked(tx) or numpy.ma.is_masked(
                        ty) or numpy.isnan(tx) or numpy.isnan(
                            ty) or numpy.isinf(tx) or numpy.isinf(ty):
                    raise ValueError
                xs.append(tx)
                ys.append(ty)
            except:
                pass
##             if not(MV2.isMA(tx) or MV2.isMA(ty)):
##                 xs.append(tx)
##                 ys.append(ty)
##             else:
##                 print tx,ty,t,p
##                 xs.append(tx)
##                 ys.append(ty)
        if xs == [] and ys == []:
            for d in self.displays:
                d.off = 1
                self.x.remove_display_name(d.name)
            for i in range(len(self.displays)):
                self.displays.pop(-1)

            raise Exception, "Error: data are all out of range!"
        ierr = 1
        iso = self.x.createline()
        iso.type = self.line.type
        iso.width = self.line.width
        iso.color = self.line.color

        iso.worldcoordinate = [self.xmin, self.xmax, self.ymin, self.ymax]
        iso.viewport = [
            isotemplate.data.x1, isotemplate.data.x2, isotemplate.data.y1,
            isotemplate.data.y2
        ]
        iso.x = xs
        iso.y = ys
        iso.priority = 3
        self.displays.append(self.x.plot(iso, bg=bg))
        return

    def setIso(self, iso, values=None):
        iso.datawc_x1 = self.xmin
        iso.datawc_x2 = self.xmax
        iso.datawc_y1 = self.ymin
        iso.datawc_y2 = self.ymax
        if not values is None:
            if iso.g_name == 'Gi':
                iso.level = values
                col = [
                    iso.linecolors[0],
                ] * len(values)
                iso.linecolors = col
                iso.line = [
                    iso.line[0],
                ] * len(values)
                if iso.text is None:
                    iso.text = [
                        1,
                    ] * len(values)
                else:
                    iso.text = [
                        iso.text[0],
                    ] * len(values)
                iso.textcolors = col
            else:
                col = [
                    iso.fillareacolors[0],
                ] * len(values)
                iso.fillareacolors = col
                iso.levels = values
        return

    def plotIsos(self, template=None, bg=0):
        if template is None:
            template = 'thdiags_template'
        elif type(template) != type(''):
            template = template.name
        try:
            isotemplate = self.x.createtemplate(template)
        except:
            isotemplate = self.x.gettemplate(template)

        att = dir(isotemplate)
        for a in att:
            try:
                b = getattr(isotemplate, a)
                setattr(b, 'priority', 0)
            except:
                pass

        isotemplate.data.priority = 1
        isotemplate.box1.priority = 1
        isotemplate.box1.x1 = isotemplate.data.x1
        isotemplate.box1.x2 = isotemplate.data.x2
        isotemplate.box1.y1 = isotemplate.data.y1
        isotemplate.box1.y2 = isotemplate.data.y2

        dX = self.xmax - self.xmin
        dY = self.ymax - self.ymin
        X = numpy.ma.arange(self.detail, dtype=MV2.float)
        X = X * dX / (self.detail - 1) + self.xmin
        Xaxis = cdms2.createAxis(X)
        X = numpy.ma.resize(X, (self.detail, self.detail))
        Y = numpy.ma.arange(self.detail, dtype=MV2.float)
        Y = Y * dY / (self.detail - 1) + self.ymin
        Yaxis = cdms2.createAxis(Y)
        Y = numpy.ma.resize(Y, (self.detail, self.detail))
        Y = numpy.ma.transpose(Y)

        # Computes T,P on this grid
        T, P = self.XY2TP(X, Y)
        T = MV2.array(T)

        # Potential Temperature
        Tp = T / numpy.ma.power(P / 100000., self.k)

        ws = Ws(T, P)
        # Seems like we need not ws after 600mb
        ws = numpy.ma.masked_where(
            numpy.ma.less(P, self.Pmaxmixingratio * 100.), ws)

        T = T - 273.16
        Tmin, Tmax = vcs.minmax(T)

        Tvalues = self.isotherms.level
        if Tvalues == [[0.0, 1.0000000200408773e+20]]:
            Tvalues = vcs.mkscale(Tmin, Tmax)
            ## Now sets the isothermsfilled
            Tvalues2 = []
            for i in range(len(Tvalues) / 2 - 1):
                t1, t2 = Tvalues[2 * i], Tvalues[2 * i + 1]
                if isinstance(t1, (list, tuple)):
                    t1, t2 = t1[0], t2[0]
                Tvalues2.append([t1, t2])
        else:
            Tvalues2 = self.isothermsfilled.levels
        self.setIso(self.isotherms, Tvalues)
        ##         self.setIso(self.isothermsfilled,Tvalues2)

        P = P / 100.
        Pvalues = vcs.mkscale(self.datawc_y2, self.datawc_y1)
        self.setIso(self.isobars, Pvalues)

        Tp = Tp - 273.16
        Tpvalues = self.dryadiabats.level
        if Tpvalues == [[0.0, 1.0000000200408773e+20]]:
            min, max = vcs.minmax(Tp)
            Tpvalues = vcs.mkscale(min, max)
        self.setIso(self.dryadiabats, Tpvalues)

        ## Pseudoadiabats
        Thevalues = self.pseudoadiabats.level
        if Thevalues == [[0.0, 1.0000000200408773e+20]]:
            Thevalues = vcs.mkevenlevels(-40, 40, 40)
        self.setIso(self.pseudoadiabats, Thevalues)

        ## Mixing Ratio
        ws = ws * 1000.
        wsvalues = self.mixingratio.level
        if wsvalues == [[0.0, 1.0000000200408773e+20]]:
            min, max = vcs.minmax(ws)
            wsvalues = vcs.mkscale(min, max)
        self.setIso(self.mixingratio, wsvalues)

        # Figures out where to plot the P labels
        dicP = {}
        dicPl = vcs.mklabels(Pvalues)
        for p in Pvalues:
            X, Y = self.TP2XY(self.datawc_x1 + 273.15, p * 100)
            if not numpy.ma.isMA(X):
                dicP[Y] = dicPl[p]
        try:
            ttp = self.x.createtexttable('Plabels')
        except:
            ttp = self.x.gettexttable('Plabels')
        ttp.color = self.isobars.linecolors[0]
        isotemplate.ylabel1.texttable = ttp
        dicT = {}
        Tvalues = list(numpy.ma.array(Tvalues).filled().ravel())
        dicTl = vcs.mklabels(Tvalues)
        for t in Tvalues:
            X, Y = self.TP2XY(t + 273.15, self.datawc_y1 * 100)
            dicT[X] = dicTl[t]
        try:
            ttp = self.x.createtexttable('Tlabels')
        except:
            ttp = self.x.gettexttable('Tlabels')
        ttp.color = self.isotherms.linecolors[0]
        isotemplate.xlabel1.texttable = ttp
        isotemplate.ylabel1.priority = 1
        isotemplate.xlabel1.priority = 1
        isotemplate.data.x1 = isotemplate.data.x1
        isotemplate.data.x2 = isotemplate.data.x2
        isotemplate.data.y1 = isotemplate.data.y1
        isotemplate.data.y2 = isotemplate.data.y2
        self.isotherms.yticlabels1 = dicP
        self.isotherms.xticlabels1 = dicT
        self.isobars.yticlabels1 = {}
        self.isobars.xticlabels1 = {}
        self.dryadiabats.yticlabels1 = {}
        self.dryadiabats.xticlabels1 = {}
        self.pseudoadiabats.yticlabels1 = {}
        self.pseudoadiabats.xticlabels1 = {}
        self.mixingratio.yticlabels1 = {}
        self.mixingratio.xticlabels1 = {}
        self.isothermsfilled.datawc_x1 = self.isothermsfilled.datawc_x1
        self.isothermsfilled.datawc_x2 = self.isothermsfilled.datawc_x2
        self.isothermsfilled.datawc_y1 = self.isothermsfilled.datawc_y1
        self.isothermsfilled.datawc_x2 = self.isothermsfilled.datawc_y2
        # Puts the dims on it
        T.id = 'T'
        T.setAxis(0, Yaxis)
        T.setAxis(1, Xaxis)
        P = MV2.array(P)
        P.id = 'P'
        P.setAxis(0, Yaxis)
        P.setAxis(1, Xaxis)
        Tp = MV2.array(Tp)
        Tp.setAxis(0, Yaxis)
        Tp.setAxis(1, Xaxis)
        ws = MV2.array(ws)
        ws.setAxis(0, Yaxis)
        ws.setAxis(1, Xaxis)

        # plot if self.drawisothermsfilled:
        if self.drawisothermsfilled:
            self.displays.append(
                self.x.plot(T, isotemplate, self.isothermsfilled, bg=bg))
        if self.drawisotherms:
            self.displays.append(
                self.x.plot(T, isotemplate, self.isotherms, bg=bg))
        if self.drawisobars:
            self.displays.append(
                self.x.plot(P, isotemplate, self.isobars, bg=bg))
        if self.drawdryadiabats:
            self.displays.append(
                self.x.plot(Tp, isotemplate, self.dryadiabats, bg=bg))
        if self.drawpseudoadiabats:
            self.plot_pseudo(isotemplate, bg=bg)
        if self.drawmixingratio:
            self.displays.append(
                self.x.plot(ws, isotemplate, self.mixingratio, bg=bg))
        return

    ## All take args with T in K and P in Pa
    # SkewT-LogP diagram defs
    def TP2XYskewT(self, T, P):
        X = T + self.skewness * numpy.ma.log(P)
        Y = -self.R * numpy.ma.log(P)
        return X, Y

    def XY2TPskewT(self, X, Y):
        P = numpy.ma.exp(-Y / self.R)
        T = X - self.skewness * numpy.ma.log(P)
        return T, P

    # Emagram defs
    def TP2XYemagram(self, T, P):
        X = T
        Y = -self.R * numpy.ma.log(P)
        return X, Y

    def XY2TPemagram(self, X, Y):
        T = X
        P = numpy.ma.exp(-Y / self.R)
        return T, P

    #Tephigram defs
    def TP2XYtephigram(self, T, P):
        X = T
        Tp = T / numpy.ma.power(P / 100000., self.k)
        Y = self.cp * numpy.ma.log(Tp)
        return X, Y

    def XY2TPtephigram(self, X, Y):
        T = X
        Tp = numpy.ma.exp(Y / self.cp)
        P = 100000. * numpy.ma.power(T / Tp, 1. / self.k)
        return T, P

    #Stuve diagram defs
    def TP2XYstuve(self, T, P):
        X = T
        Y = numpy.ma.power(P, self.k)
        return X, Y

    def XY2TPstuve(self, X, Y):
        T = X
        P = numpy.ma.power(Y, 1. / self.k)
        return T, P

    def plot_windbarb(self, u, v, P=None, template=None, type='uv', bg=0):
        if type == 'uv':
            n = numpy.ma.sqrt(u * u + v * v)
            d = numpy.ma.arccos(u / n)
            d = numpy.ma.where(numpy.ma.less(v, 0.), -d, d)

        if P is None:
            P = u.getLevel()
            if P is None:
                P = u.getAxis(-1)
            P = P.clone()
            try:  # tries to convert to Pa
                for i in range(len(P)):
                    uni = unidata.udunits(P[i], P.units)
                    P[i] = uni.to("Pa").value
            except Exception, err:
                pass
            P = P[:]

        n1 = n / self.windbarbsscales[0]
        n1 = n1.astype('i')
        n2 = (n - n1 * self.windbarbsscales[0]) / self.windbarbsscales[1]
        n2 = n2.astype('i')
        n3 = (n - n1 * self.windbarbsscales[0] -
              n2 * self.windbarbsscales[1]) / self.windbarbsscales[2]
        n3 = n3.astype('i')

        ##         print 'n1:',n1
        ##         print 'n2:',n2
        ##         print 'n3:',n3

        nitems = len(P)
        for i in range(nitems):
            if not (MV2.isMA(n[i])):
                p = P[i]
                ## Figure out the altitude to plot it (y coord) !
                dum, Y = self.TP2XY(273, p)
                lin = self.x.createline()
                lin.viewport = [
                    template.data.x1, template.data.x2, template.data.y1,
                    template.data.y2
                ]
                lin.worldcoordinate = [-1, 1, -1, 1]
                lin.x = [0, 0]
                lin.y = [-1, 1]
                self.displays.append(self.x.plot(lin, bg=bg))
                lin = self.x.createline()
                lin.viewport = [
                    template.data.x1, template.data.x2, template.data.y1,
                    template.data.y2
                ]
                lin.worldcoordinate = [-1, 1, self.ymin, self.ymax]
                ## Set everything correctly y wise
                rw = 2 / (self.ymax - self.ymin)
                if self.x.islandscape():
                    r = 1.375
                else:
                    r = .72727272
                rv = (template.data.x2 -
                      template.data.x1) / (template.data.y2 - template.data.y1)
                rw = 1. / rw
                x, y = self.make_barb(n[i], d[i], n1[i], n2[i], n3[i],
                                      rw * r * rv, Y)
                lin.x = x
                lin.y = y
                linetype = ['solid']
                self.displays.append(self.x.plot(lin, bg=bg))
Example #3
0
    def plot_windbarb(self, u, v, P=None, template=None, type='uv', bg=0):
        if type == 'uv':
            n = numpy.ma.sqrt(u * u + v * v)
            d = numpy.ma.arccos(u / n)
            d = numpy.ma.where(numpy.ma.less(v, 0.), -d, d)

        if P is None:
            P = u.getLevel()
            if P is None:
                P = u.getAxis(-1)
            P = P.clone()
            try:  # tries to convert to Pa
                for i in range(len(P)):
                    uni = unidata.udunits(P[i], P.units)
                    P[i] = uni.to("Pa").value
            except Exception:
                pass
            P = P[:]

        n1 = n / self.windbarbsscales[0]
        n1 = n1.astype('i')
        n2 = (n - n1 * self.windbarbsscales[0]) / self.windbarbsscales[1]
        n2 = n2.astype('i')
        n3 = (n - n1 * self.windbarbsscales[0] -
              n2 * self.windbarbsscales[1]) / self.windbarbsscales[2]
        n3 = n3.astype('i')

        # print 'n1:',n1
        # print 'n2:',n2
        # print 'n3:',n3

        nitems = len(P)
        for i in range(nitems):
            if not (MV2.isMA(n[i])):
                p = P[i]
                # Figure out the altitude to plot it (y coord) !
                dum, Y = self.TP2XY(273, p)
                lin = self.x.createline()
                lin.viewport = [
                    template.data.x1, template.data.x2, template.data.y1,
                    template.data.y2
                ]
                lin.worldcoordinate = [-1, 1, -1, 1]
                lin.x = [0, 0]
                lin.y = [-1, 1]
                self.displays.append(self.x.plot(lin, bg=bg))
                lin = self.x.createline()
                lin.viewport = [
                    template.data.x1, template.data.x2, template.data.y1,
                    template.data.y2
                ]
                lin.worldcoordinate = [-1, 1, self.ymin, self.ymax]
                # Set everything correctly y wise
                rw = 2 / (self.ymax - self.ymin)
                if self.x.islandscape():
                    r = 1.375
                else:
                    r = .72727272
                rv = (template.data.x2 -
                      template.data.x1) / (template.data.y2 - template.data.y1)
                rw = 1. / rw
                x, y = self.make_barb(n[i], d[i], n1[i], n2[i], n3[i],
                                      rw * r * rv, Y)
                lin.x = x
                lin.y = y
                lin.type = ['solid']
                self.displays.append(self.x.plot(lin, bg=bg))