Example #1
0
 def checkDataIntegrity(self):
     if not qc_tools.isHGHTValid(self.hght):
         qc_tools.raiseError("Invalid height data.  Data has repeat height values or height does not increase as pressure decreases.", qc_tools.DataQualityException)
     if not qc_tools.isTMPCValid(self.tmpc):
         qc_tools.raiseError("Invalid temperature data. Profile contains a temperature value < -273.15 Celsius.", qc_tools.DataQualityException)
     if not qc_tools.isDWPCValid(self.dwpc):
         qc_tools.raiseError("Invalid dewpoint data. Profile contains a dewpoint value < -273.15 Celsius.", qc_tools.DataQualityException)
     if not qc_tools.isWSPDValid(self.wspd):
         qc_tools.raiseError("Invalid wind speed data. Profile contains a wind speed value < 0 knots.", qc_tools.DataQualityException)
     if not qc_tools.isWDIRValid(self.wdir):
         qc_tools.raiseError("Invalid wind direction data. Profile contains a wind direction < 0 degrees or >= 360 degrees.", qc_tools.DataQualityException)
Example #2
0
    def __init__(self, **kwargs):
        '''
        Create the sounding data object
        
        Parameters
        ----------
        Mandatory Keywords
        pres : array_like
        The pressure values (Hectopaschals)
        hght : array_like
        The corresponding height values (Meters)
        tmpc : array_like
        The corresponding temperature values (Celsius)
        dwpc : array_like
        The corresponding dewpoint temperature values (Celsius)
            
        Optional Keyword Pairs (must use one or the other)
        wdir : array_like
        The direction from which the wind is blowing in
        meteorological degrees
        wspd : array_like
        The speed of the wind
            
        OR
            
        u : array_like
        The U-component of the direction from which the wind
        is blowing
            
        v : array_like
        The V-component of the direction from which the wind
        is blowing.
            
        Optional Keywords
        missing : number (default: sharppy.sharptab.constants.MISSING)
        The value of the missing flag

        location : string (default: None)
        The 3 character station identifier or 4 character
        WMO station ID for radiosonde locations. Used for
        the PWV database.
        
        strictQC : boolean
        A flag that indicates whether or not the strict quality control
        routines should be run on the profile upon construction.

        Returns
        -------
        prof: Profile object
            
        '''
        super(BasicProfile, self).__init__(**kwargs)

        strictQC = kwargs.get('strictQC', True)

        assert len(self.pres) == len(self.hght) == len(self.tmpc) == len(self.dwpc),\
                "Length of pres, hght, tmpc, or dwpc arrays passed to constructor are not the same."

        ## did the user provide the wind in vector form?
        if self.wdir is not None:
            assert len(self.wdir) == len(self.wspd) == len(
                self.pres
            ), "Length of wdir and wspd arrays passed to constructor are not the same length as the pres array."
            self.wdir[self.wdir == self.missing] = ma.masked
            self.wspd[self.wspd == self.missing] = ma.masked
            self.wdir[self.wspd.mask] = ma.masked
            self.wspd[self.wdir.mask] = ma.masked
            self.u, self.v = utils.vec2comp(self.wdir, self.wspd)

        ## did the user provide the wind in u,v form?
        elif self.u is not None:
            assert len(self.u) == len(self.v) == len(
                self.pres
            ), "Length of u and v arrays passed to constructor are not the same length as the pres array."
            self.u[self.u == self.missing] = ma.masked
            self.v[self.v == self.missing] = ma.masked
            self.u[self.v.mask] = ma.masked
            self.v[self.u.mask] = ma.masked
            self.wdir, self.wspd = utils.comp2vec(self.u, self.v)

        ## check if any standard deviation data was supplied
        if self.tmp_stdev is not None:
            self.dew_stdev[self.dew_stdev == self.missing] = ma.masked
            self.tmp_stdev[self.tmp_stdev == self.missing] = ma.masked
            self.dew_stdev.set_fill_value(self.missing)
            self.tmp_stdev.set_fill_value(self.missing)

        if self.omeg is not None:
            ## get the omega data and turn into arrays
            assert len(self.omeg) == len(
                self.pres
            ), "Length of omeg array passed to constructor is not the same length as the pres array."
            self.omeg[self.omeg == self.missing] = ma.masked
        else:
            self.omeg = ma.masked_all(len(self.hght))

        # QC Checks on the arrays passed to the constructor.
        qc_tools.areProfileArrayLengthEqual(self)

        ## mask the missing values
        self.pres[self.pres == self.missing] = ma.masked
        self.hght[self.hght == self.missing] = ma.masked
        self.tmpc[self.tmpc == self.missing] = ma.masked
        self.dwpc[self.dwpc == self.missing] = ma.masked

        #if not qc_tools.isPRESValid(self.pres):
        ##    qc_tools.raiseError("Incorrect order of pressure array (or repeat values) or pressure array is of length <= 1.", ValueError)
        if not qc_tools.isHGHTValid(self.hght) and strictQC:
            qc_tools.raiseError(
                "Incorrect order of height (or repeat values) array or height array is of length <= 1.",
                ValueError)
        if not qc_tools.isTMPCValid(self.tmpc):
            qc_tools.raiseError(
                "Invalid temperature array. Array contains a value < -273.15 Celsius.",
                ValueError)
        if not qc_tools.isDWPCValid(self.dwpc):
            qc_tools.raiseError(
                "Invalid dewpoint array. Array contains a value < -273.15 Celsius.",
                ValueError)
        if not qc_tools.isWSPDValid(self.wspd) and strictQC:
            qc_tools.raiseError(
                "Invalid wind speed array. Array contains a value < 0 knots.",
                ValueError)
        if not qc_tools.isWDIRValid(self.wdir) and strictQC:
            qc_tools.raiseError(
                "Invalid wind direction array. Array contains a value < 0 degrees or value > 360 degrees.",
                ValueError)

        self.logp = np.log10(self.pres.copy())
        self.vtmp = thermo.virtemp(self.pres, self.tmpc, self.dwpc)
        idx = np.ma.where(self.pres > 0)[0]
        self.vtmp[self.dwpc.mask[idx]] = self.tmpc[
            self.dwpc.mask[idx]]  # Masking any virtual temperature

        ## get the index of the top and bottom of the profile
        self.sfc = self.get_sfc()
        self.top = self.get_top()
        ## generate the wetbulb profile
        self.wetbulb = self.get_wetbulb_profile()
        ## generate theta-e profile
        self.thetae = self.get_thetae_profile()
Example #3
0
''' Create the Sounding (Profile) Object '''
Example #4
0
    def __init__(self, **kwargs):
        '''
        Create the sounding data object
        
        Parameters
        ----------
        Mandatory Keywords
        pres : array_like
        The pressure values (Hectopaschals)
        hght : array_like
        The corresponding height values (Meters)
        tmpc : array_like
        The corresponding temperature values (Celsius)
        dwpc : array_like
        The corresponding dewpoint temperature values (Celsius)
            
        Optional Keyword Pairs (must use one or the other)
        wdir : array_like
        The direction from which the wind is blowing in
        meteorological degrees
        wspd : array_like
        The speed of the wind
            
        OR
            
        u : array_like
        The U-component of the direction from which the wind
        is blowing
            
        v : array_like
        The V-component of the direction from which the wind
        is blowing.
            
        Optional Keywords
        missing : number (default: sharppy.sharptab.constants.MISSING)
        The value of the missing flag
        location : string (default: None)
        The 3 character station identifier or 4 character
        WMO station ID for radiosonde locations. Used for
        the PWV database.
        
        strictQC : boolean
        A flag that indicates whether or not the strict quality control
        routines should be run on the profile upon construction.
        Returns
        -------
        prof: Profile object
            
        '''
        super(BasicProfile, self).__init__(**kwargs)

        strictQC = kwargs.get('strictQC', True)

        assert len(self.pres) == len(self.hght) == len(self.tmpc) == len(self.dwpc),\
                "Length of pres, hght, tmpc, or dwpc arrays passed to constructor are not the same."

        ## did the user provide the wind in vector form?
        if self.wdir is not None:
            assert len(self.wdir) == len(self.wspd) == len(self.pres), "Length of wdir and wspd arrays passed to constructor are not the same length as the pres array."
            self.wdir[self.wdir == self.missing] = ma.masked
            self.wspd[self.wspd == self.missing] = ma.masked
            self.wdir[self.wspd.mask] = ma.masked
            self.wspd[self.wdir.mask] = ma.masked
            self.u, self.v = utils.vec2comp(self.wdir, self.wspd)

        ## did the user provide the wind in u,v form?
        elif self.u is not None:
            assert len(self.u) == len(self.v) == len(self.pres), "Length of u and v arrays passed to constructor are not the same length as the pres array."
            self.u[self.u == self.missing] = ma.masked
            self.v[self.v == self.missing] = ma.masked
            self.u[self.v.mask] = ma.masked
            self.v[self.u.mask] = ma.masked
            self.wdir, self.wspd = utils.comp2vec(self.u, self.v)

        ## check if any standard deviation data was supplied
        if self.tmp_stdev is not None:
            self.dew_stdev[self.dew_stdev == self.missing] = ma.masked
            self.tmp_stdev[self.tmp_stdev == self.missing] = ma.masked
            self.dew_stdev.set_fill_value(self.missing)
            self.tmp_stdev.set_fill_value(self.missing)

        if self.omeg is not None:
            ## get the omega data and turn into arrays
            assert len(self.omeg) == len(self.pres), "Length of omeg array passed to constructor is not the same length as the pres array."
            self.omeg[self.omeg == self.missing] = ma.masked
        else:
            self.omeg = ma.masked_all(len(self.hght))

        # QC Checks on the arrays passed to the constructor.
        qc_tools.areProfileArrayLengthEqual(self)
       
        ## mask the missing values
        self.pres[self.pres == self.missing] = ma.masked
        self.hght[self.hght == self.missing] = ma.masked
        self.tmpc[self.tmpc == self.missing] = ma.masked
        self.dwpc[self.dwpc == self.missing] = ma.masked

        #if not qc_tools.isPRESValid(self.pres):
        ##    qc_tools.raiseError("Incorrect order of pressure array (or repeat values) or pressure array is of length <= 1.", ValueError)
        if not qc_tools.isHGHTValid(self.hght) and strictQC:
            qc_tools.raiseError("Incorrect order of height (or repeat values) array or height array is of length <= 1.", ValueError)
        if not qc_tools.isTMPCValid(self.tmpc):
            qc_tools.raiseError("Invalid temperature array. Array contains a value < 273.15 Celsius.", ValueError)
        if not qc_tools.isDWPCValid(self.dwpc):
            qc_tools.raiseError("Invalid dewpoint array. Array contains a value < 273.15 Celsius.", ValueError)
        if not qc_tools.isWSPDValid(self.wspd) and strictQC:
            qc_tools.raiseError("Invalid wind speed array. Array contains a value < 0 knots.", ValueError)
        if not qc_tools.isWDIRValid(self.wdir) and strictQC:
            qc_tools.raiseError("Invalid wind direction array. Array contains a value < 0 degrees or value >= 360 degrees.", ValueError)     


        self.logp = np.log10(self.pres.copy())
        self.vtmp = thermo.virtemp( self.pres, self.tmpc, self.dwpc )
        idx = np.ma.where(self.pres > 0)[0]
        self.vtmp[self.dwpc.mask[idx]] = self.tmpc[self.dwpc.mask[idx]] # Masking any virtual temperature 

        ## get the index of the top and bottom of the profile
        self.sfc = self.get_sfc()
        self.top = self.get_top()
        ## generate the wetbulb profile
        self.wetbulb = self.get_wetbulb_profile()
        ## generate theta-e profile
        self.thetae = self.get_thetae_profile()