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)
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()
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()
''' Create the Sounding (Profile) Object '''
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()