Ejemplo n.º 1
0
 def test_2d_w_missing(self):
     # Test cov on 2D variable w/ missing value
     x = self.data
     x[-1] = masked
     x = x.reshape(3, 4)
     valid = np.logical_not(getmaskarray(x)).astype(int)
     frac = np.dot(valid, valid.T)
     xf = (x - x.mean(1)[:, None]).filled(0)
     assert_almost_equal(cov(x), np.cov(xf) * (x.shape[1] - 1) / (frac - 1.0))
     assert_almost_equal(cov(x, bias=True), np.cov(xf, bias=True) * x.shape[1] / frac)
     frac = np.dot(valid.T, valid)
     xf = (x - x.mean(0)).filled(0)
     assert_almost_equal(cov(x, rowvar=False), (np.cov(xf, rowvar=False) * (x.shape[0] - 1) / (frac - 1.0)))
     assert_almost_equal(cov(x, rowvar=False, bias=True), (np.cov(xf, rowvar=False, bias=True) * x.shape[0] / frac))
Ejemplo n.º 2
0
 def test_2d_w_missing(self):
     # Test cov on 2D variable w/ missing value
     x = self.data
     x[-1] = masked
     x = x.reshape(3, 4)
     valid = np.logical_not(getmaskarray(x)).astype(int)
     frac = np.dot(valid, valid.T)
     xf = (x - x.mean(1)[:, None]).filled(0)
     assert_almost_equal(cov(x),
                         np.cov(xf) * (x.shape[1] - 1) / (frac - 1.))
     assert_almost_equal(cov(x, bias=True),
                         np.cov(xf, bias=True) * x.shape[1] / frac)
     frac = np.dot(valid.T, valid)
     xf = (x - x.mean(0)).filled(0)
     assert_almost_equal(cov(x, rowvar=False),
                         (np.cov(xf, rowvar=False) * (x.shape[0] - 1) /
                          (frac - 1.)))
     assert_almost_equal(
         cov(x, rowvar=False, bias=True),
         (np.cov(xf, rowvar=False, bias=True) * x.shape[0] / frac))
Ejemplo n.º 3
0
def virtualTemp3(T, Td, p):
    """Virtual Temperature, but using vapor mixing ratio instead the vapor pressure

    Parameters
    ---------    
    T: float
        Temperature in Celsius degrees
    
    Td: float
        Dew Point Temperature un Celsius Degrees
    
    p: float
        Atmospheric pressure (Pa)

    Returns
    -------
    Virtual temperature : float32
        In Celsius degrees
    """

    T = masked_invalid(T)
    Td = masked_where(numpy.array(Td) < -degCtoK, Td)
    Td = masked_invalid(Td)
    _vaporMixingRatio = vaporMixingRatio(VaporPressure(Td), p)

    T.filled(-99999)
    #print(_vaporMixingRatio)
    Tc = (T + degCtoK)
    factor = (1. +
              (_vaporMixingRatio.data / Epsilon)) / (1. +
                                                     _vaporMixingRatio.data)

    _virtualTemp = (Tc * factor) - degCtoK

    noTDMask = getmaskarray(_vaporMixingRatio)
    _virtualTemp.data[noTDMask] = T[noTDMask]
    _virtualTemp.mask = getmask(T)

    return _virtualTemp
Ejemplo n.º 4
0
    def getCleanSounding(self):
        """  
        Clean the sounding, when Temperature or pressure has a missing values,
        removing that pressure level.
        
        It returns the pressure in Pa and temperatures in Celsius
        """

        pressure = self['pressure']
        temperature = self['temperature']

        dewPointTemperature = self['dewPointTemperature']
        dewPointTemperature[getmaskarray(
            dewPointTemperature)] = self.missingValue

        if pressure.units is not None:
            if pressure.units.lower() == 'hpa':
                hPa = True
            elif pressure.units.lower() == 'pa':
                hPa = False
            else:
                raise fatalError(
                    "Error getting clean sounding plot",
                    "Pressure units not supported:%s" % pressure.units,
                    "Supported: hPa or Pa ")
        else:
            hPa = True

        if temperature.units is not None:

            if dewPointTemperature.units is not None:
                if temperature.units.lower(
                ) != dewPointTemperature.units.lower():
                    raise fatalError(
                        "Error getting clean sounding plot",
                        "Temperature units: %s" % temperature.units,
                        "Dew Point Temp: %s" % dewPointTemperature.units)

            if temperature.units.lower() == 'c':
                celsius = True
            elif temperature.units.lower() == 'k':
                celsius = False
            else:
                raise fatalError(
                    "Error getting clean sounding plot",
                    "Temperature units not supported:%s" % temperature.units,
                    "Supported: C or K ")
        else:
            celsius = True

        mask = ~mask_or(
            getmaskarray(pressure), getmaskarray(temperature), shrink=False)

        if hPa:
            _pressure = pressure.data[mask]
        else:
            _pressure = pressure.data[mask] / 100

        if celsius:
            _temperature = temperature.data[mask]
            _dewPointTemperature = masked_values(
                dewPointTemperature.data[mask], self.missingValue)

        else:
            _temperature = temperature.data[mask] - 273.15
            _dewPointTemperature = masked_values(
                dewPointTemperature.data[mask], self.missingValue) - 273.15

        return (_pressure, _temperature, _dewPointTemperature)
Ejemplo n.º 5
0
    def addProfile(self,
                   pressure,
                   temperature,
                   dewPointTemperature,
                   hPa=True,
                   celsius=True,
                   method=0,
                   initialLevel=0,
                   parcel=True,
                   label=None,
                   diagnostics=False,
                   markers=True,
                   useVirtual=True,
                   **kwargs):
        """
        Add a profile to the Skew-T axis
        
        .. _`matplotlib.legend`: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.legend
        
        .. _ndarray: https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html
        
        .. _MaskedArray: https://docs.scipy.org/doc/numpy/reference/maskedarray.html
        
        The input data can  be ndarray_ or MaskedArray_.
        If MaskedArray_ are used, the pressure levels with masked or invalid entries 
        in the pressure and temperature arrays are removed. 
        Masked values in the dewPointTemperature are not plotted.
        
        Parameters
        ----------
        
        pressure : ndarray_ or MaskedArray_
            Pressure levels of the sounding
        
        temperature : ndarray_ or MaskedArray_
            Temperature profile at pressure levels
        
        dewPointTemperature : : ndarray_ or MaskedArray_
            Dew point temperature at pressure levels
        
        
        hPa: bool, optional
            If is True, the pressure levels are in hPa. Otherwise Pascals is
            assumed
            
        celsius : bool, optional
            If is True, the temperatures units correspond to celsius degrees.
            Otherwise Kelvin degrees units are assumed
            
        parcel : bool, optional
            If True, the parcel analysis is carried out.
            
        method : int, optional
            Parcel analysis method used. Supported:
        
            * Most Unstable  : method=0
            * Single Parcel: method=1
            * Mixed Layer  : method=2 (Not supported yet)

        initialLevel : int, optional
            Initial level (index) used to compute the parcel analysis.
            Levels below this value are ignored.
            
            For the Single Parcel analysis, this level correspond to the parcel used.
            By default, the initial level is 0 (surface).
            
            For the Most Unstable method, this value is ignored.
        label : str, optional
            Label assigned to the profile lines. If None, no label is used.
            When a line is labeled, the legend is added automatically to the plot.
            use keyword **loc** to control the position.
        diagnostics : bool, optional
            If True a text box is added to the upper right corner with some diagnostics
            from the parcel analysis.
        
        markers: bool, optional
            If True, the LCL, LFC and EL are marked in the plot with markers.
            
        useVirtual : bool, optional
            If True, in the parcel analysis, CAPE and CIN are computed used
            the virtual temperature. The temperatures plotted in the SkewT diagram
            will correspond to virtual temperature instead of temperature. 
            If False, virtual temperatures corrections are neglected and the
            original temperature is plotted.
            
        Other Parameters
        ----------------
        
        loc : str
            Legend location. See `matplotlib.legend`_ for more details.
            
        kwargs : extra
            The remaining extra keyword arguments are passed to the plot function
            when plotting the temperature profiles.
        """

        mask = numpy.zeros_like(pressure, dtype=bool)

        if isinstance(pressure, masked_array):
            pressure[pressure.mask] = numpy.nan
            mask = logical_or(mask, getmaskarray(pressure))
        if isinstance(temperature, masked_array):
            temperature[temperature.mask] = numpy.nan
            mask = logical_or(mask, getmaskarray(temperature))
        if isinstance(dewPointTemperature, masked_array):
            dewPointMask = getmaskarray(dewPointTemperature)
            dewPointTemperature.data[dewPointMask] = numpy.nan
            dewPointTemperature = numpy.asarray(dewPointTemperature.data,
                                                dtype=numpy.float32)

        pressure = masked_invalid(pressure[~mask])
        temperature = masked_invalid(temperature[~mask])
        dewPointTemperature = masked_invalid(dewPointTemperature[~mask])

        # Convert temperatures and pressure to hPa
        if not hPa:
            pressure /= 100

        if not celsius:
            temperature -= degCtoK
            dewPointTemperature -= degCtoK

        if parcel:

            parcelAnalysisResult = parcelAnalysis(pressure,
                                                  temperature,
                                                  dewPointTemperature,
                                                  hPa=True,
                                                  celsius=True,
                                                  useVirtual=1,
                                                  initialLevel=initialLevel,
                                                  method=method)

            initialLevel = parcelAnalysisResult['initialLevel']
            initialTemperature = temperature[initialLevel]

            pressureAtLCL = parcelAnalysisResult['pressureAtLCL']
            temperatureAtLCL = parcelAnalysisResult['temperatureAtLCL']

            pressureAtLFC = parcelAnalysisResult['pressureAtLFC']
            temperatureAtLFC = parcelAnalysisResult['temperatureAtLFC']

            pressureAtEL = parcelAnalysisResult['pressureAtEL']
            temperatureAtEL = parcelAnalysisResult['temperatureAtEL']

            parcelTemperature = liftParcel(initialTemperature,
                                           pressure,
                                           pressureAtLCL,
                                           initialLevel=initialLevel,
                                           hPa=True,
                                           celsius=True)

            # Add LCL
            belowLCL = numpy.where(pressure > pressureAtLCL, True, False)
            newParcelTemperature = numpy.concatenate(
                (parcelTemperature[belowLCL], [temperatureAtLCL],
                 parcelTemperature[~belowLCL]))
            newPressure = numpy.concatenate(
                (pressure[belowLCL], [pressureAtLCL], pressure[~belowLCL]))

            # Add EL
            belowEL = numpy.where(newPressure > pressureAtEL, True, False)
            newParcelTemperature = numpy.concatenate(
                (newParcelTemperature[belowEL], [temperatureAtEL],
                 newParcelTemperature[~belowEL]))
            newPressure = numpy.concatenate(
                (newPressure[belowEL], [pressureAtEL], newPressure[~belowEL]))

            belowLFC = numpy.where(newPressure > pressureAtLFC, True, False)
            newParcelTemperature = numpy.concatenate(
                (newParcelTemperature[belowLFC], [temperatureAtLFC],
                 newParcelTemperature[~belowLFC]))
            newPressure = numpy.concatenate(
                (newPressure[belowLFC], [pressureAtLFC],
                 newPressure[~belowLFC]))

            newTemperature = numpy.interp(newPressure, pressure[::-1],
                                          temperature[::-1])
            newParcelTemperature = masked_invalid(newParcelTemperature)
            if useVirtual:
                newDewPointTemperature = numpy.interp(
                    newPressure, pressure[::-1], dewPointTemperature[::-1])
                newTemperature = virtualTemp3(newTemperature,
                                              newDewPointTemperature,
                                              newPressure * 100)

                belowLCL = (newPressure >= pressureAtLCL)

                newParcelTemperature[belowLCL] = virtualTemp3(
                    newParcelTemperature[belowLCL],
                    dewPointTemperature[initialLevel],
                    newPressure[belowLCL] * 100)
                aboveLCL = (newPressure < pressureAtLCL)

                newParcelTemperature[aboveLCL] = virtualTemp4(
                    newParcelTemperature[aboveLCL],
                    newPressure[aboveLCL] * 100)

        else:
            newTemperature = temperature
            newPressure = pressure

        kwargs['zorder'] = kwargs.pop('zorder', 5)
        kwargs['linewidth'] = kwargs.pop('linewidth', 2.0)
        kwargs['linestyle'] = kwargs.pop('linestyle', '-')
        loc = kwargs.pop('loc', 'best')

        temperatureLine, = self.plot(newTemperature, newPressure, 'r',
                                     **kwargs)

        self.plot(dewPointTemperature, pressure, 'b', **kwargs)

        if label is not None:
            self.linesHandlers.append(temperatureLine)
            self.linesLabels.append(label)
            self.legend(self.linesHandlers, self.linesLabels, loc=loc)

        if parcel:
            self.plot(newParcelTemperature, newPressure, 'k', **kwargs)

            if parcelAnalysisResult['CAPE'] > 0:
                # Positive Buoyancy
                cond1 = (newPressure <= pressureAtLFC) * (newPressure >=
                                                          pressureAtEL)

                self.fill_betweenx(newPressure, newParcelTemperature, newTemperature, where=cond1, \
                                   color="#ff0009", alpha=0.4, zorder=10)

                # Negative Buoyancy

                validMask = ~getmaskarray(masked_invalid(newParcelTemperature))

                cond2 = ((newParcelTemperature[validMask] <=
                          newTemperature[validMask]) *
                         (newPressure[validMask] >= pressureAtLFC))

                self.fill_betweenx(newPressure[validMask], newParcelTemperature[validMask],
                                   newTemperature[validMask], where=cond2, \
                                   color="#045cff", alpha=0.4, zorder=10)

            if markers:
                if useVirtual:
                    temperatureAtLCL = virtualTemp4(temperatureAtLCL,
                                                    pressureAtLCL * 100)
                    temperatureAtLFC = virtualTemp4(temperatureAtLFC,
                                                    pressureAtLFC * 100)
                    temperatureAtEL = virtualTemp4(temperatureAtEL,
                                                   pressureAtEL * 100)

                self.plot(temperatureAtLCL,
                          pressureAtLCL,
                          ls='',
                          marker='o',
                          color='r')
                self.plot(temperatureAtLFC,
                          pressureAtLFC,
                          ls='',
                          marker='o',
                          color='g')
                self.plot(temperatureAtEL,
                          pressureAtEL,
                          ls='',
                          marker='o',
                          color='k')

            if diagnostics:
                # Add text to sounding
                dtext = "Diagnostics:\n"
                # dtext ="Parcel: %s\n"%ptype.upper()

                # dtext+="P  :%6.1fhPa\n"%startp
                # dtext+="T :  %4.1fC\n"%startt
                # dtext+="Td :  %4.1fC\n"%startdp
                dtext += "-------------\n"
                dtext += "P_par:%6.1fhPa\n" % (pressure[initialLevel])
                dtext += "P_LCL:%6.1fhPa\n" % (
                    parcelAnalysisResult['pressureAtLCL'])
                dtext += "T_LCL:%4.1fC\n" % (
                    parcelAnalysisResult['temperatureAtLCL'])
                dtext += "P_LFC:%6.1fhPa\n" % (
                    parcelAnalysisResult['pressureAtLFC'])
                dtext += "T_LFC:%4.1fC\n" % (
                    parcelAnalysisResult['temperatureAtLFC'])
                dtext += "P_EL:%6.1fhPa\n" % (
                    parcelAnalysisResult['pressureAtEL'])
                dtext += "T_EL:%4.1fC\n" % (
                    parcelAnalysisResult['temperatureAtEL'])
                dtext += "CAPE:%.1f\n" % parcelAnalysisResult['CAPE']
                dtext += "CIN: %.1fJ" % parcelAnalysisResult['CIN']

                axesBox = self.get_position().get_points()

                self.figure.text(axesBox[1, 0],
                                 axesBox[1, 1],
                                 dtext,
                                 fontname="monospace",
                                 backgroundcolor='white',
                                 zorder=10,
                                 verticalalignment='top',
                                 horizontalalignment='right',
                                 multialignment="left")