Ejemplo n.º 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)
Ejemplo n.º 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()
Ejemplo n.º 3
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()
Ejemplo n.º 4
0
''' Create the Sounding (Profile) Object '''
Ejemplo n.º 5
0
    def __init__(self, **kwargs):
        '''
        Create the sounding data object
        
        Parameters
        ----------
        Mandatory Keywords
        hght : array_like
        The corresponding height values (Meters)
            
        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
        rms : array_like
        The RMS from the VAD algorithm.
        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.
        Returns
        -------
        prof: Profile object
            
        '''

        #Dummy variables so Profile doesn't crash
        wspd = kwargs.get('wspd')
        kwargs['tmpc'] = np.ones(len(wspd))
        kwargs['dwpc'] = np.ones(len(wspd))
        kwargs['pres'] = np.arange(1,len(wspd)+1,1)[::-1]

        super(VADProfile, self).__init__(**kwargs)
        
        self.rms = kwargs.get('rms')
        
        assert 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.hght), "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.hght), "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)

                ## mask the missing values
        self.hght[self.hght == self.missing] = ma.masked
        strictQC = False
        #if not qc_tools.isHGHTValid(self.hght):
        #    qc_tools.raiseError("Incorrect order of height (or repeat values) array or height array is of length <= 1.", 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)     

        print """Using the VADDecoder...something to keep in mind is that all interp.py routines
               use the prof.logp variable to perform the pressure based interpolation.  Because VAD 
               and radar wind profiler data does not contain pressure data, this will break
               any interpolation routines and any routines that require pressure. 
               Will have to find a way around this."""
        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[slf.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()