def test_mixed_parcel(): """Test the mixed parcel calculation.""" pressure = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.hPa temperature = np.array([22.2, 14.6, 12., 9.4, 7., -38.]) * units.degC dewpoint = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.degC parcel_pressure, parcel_temperature, parcel_dewpoint = mixed_parcel( pressure, temperature, dewpoint, depth=250 * units.hPa) assert_almost_equal(parcel_pressure, 959. * units.hPa, 6) assert_almost_equal(parcel_temperature, 28.7363771 * units.degC, 6) assert_almost_equal(parcel_dewpoint, 7.1534658 * units.degC, 6)
def test_el_ml(): """Test equilibrium layer calculation for a mixed parcel.""" levels = np.array([959., 779.2, 751.3, 724.3, 700., 400., 269.]) * units.mbar temperatures = np.array([22.2, 14.6, 12., 9.4, 7., -25., -35.]) * units.celsius dewpoints = np.array([19., -11.2, -10.8, -10.4, -10., -35., -53.2]) * units.celsius __, t_mixed, td_mixed = mixed_parcel(levels, temperatures, dewpoints) mixed_parcel_prof = parcel_profile(levels, t_mixed, td_mixed) el_pressure, el_temperature = el(levels, temperatures, dewpoints, mixed_parcel_prof) assert_almost_equal(el_pressure, 355.834 * units.mbar, 3) assert_almost_equal(el_temperature, -28.371 * units.degC, 3)
def test_lfc_ml(): """Test Mixed-Layer LFC calculation.""" levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar temperatures = np.array([22.2, 14.6, 12., 9.4, 7., -49.]) * units.celsius dewpoints = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius __, t_mixed, td_mixed = mixed_parcel(levels, temperatures, dewpoints) mixed_parcel_prof = parcel_profile(levels, t_mixed, td_mixed) lfc_pressure, lfc_temp = lfc(levels, temperatures, dewpoints, mixed_parcel_prof) assert_almost_equal(lfc_pressure, 631.794 * units.mbar, 2) assert_almost_equal(lfc_temp, -1.862 * units.degC, 2)
def calcMLCAPE(levels, temperature, dewpoint, depth=100.0 * units.hPa): _, T_parc, Td_par = mixed_parcel( levels, temperature, dewpoint, depth=depth, interpolate=False, ) profile = parcel_profile(levels, T_parc, Td_parc) cape, cin = cape_cin(levels, temperature, dewpoint, profile) return cape
def test_mixed_parcel(): """Test the mixed parcel calculation.""" pressure = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.hPa temperature = np.array([22.2, 14.6, 12., 9.4, 7., -38.]) * units.degC dewpoint = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.degC parcel_pressure, parcel_temperature, parcel_dewpoint = mixed_parcel(pressure, temperature, dewpoint, depth=250 * units.hPa) assert_almost_equal(parcel_pressure, 959. * units.hPa, 6) assert_almost_equal(parcel_temperature, 28.7363771 * units.degC, 6) assert_almost_equal(parcel_dewpoint, 7.1534658 * units.degC, 6)
def getData(self, time, model_vars, mdl2stnd, previous_data=None): ''' Name: awips_model_base Purpose: A function to get data from NAM40 model to create HDWX products Inputs: request : A DataAccessLayer request object time : List of datatime(s) for data to grab model_vars : Dictionary with variables/levels to get mdl2stnd : Dictionary to convert from model variable names to standardized names Outputs: Returns a dictionary containing all data Keywords: previous_data : Dictionary with data from previous time step ''' log = logging.getLogger(__name__) # Set up function for logger initTime, fcstTime = get_init_fcst_times(time[0]) data = { 'model': self._request.getLocationNames()[0], 'initTime': initTime, 'fcstTime': fcstTime } # Initialize empty dictionary log.info('Attempting to download {} data'.format(data['model'])) for var in model_vars: # Iterate over variables in the vars list log.debug('Getting: {}'.format(var)) self._request.setParameters(*model_vars[var]['parameters']) # Set parameters for the download request self._request.setLevels(*model_vars[var]['levels']) # Set levels for the download request response = DAL.getGridData(self._request, time) # Request the data for res in response: # Iterate over all data request responses varName = res.getParameter() # Get name of the variable in the response varLvl = res.getLevel() # Get level of the variable in the response varName = mdl2stnd[varName] # Convert variable name to local standarized name if varName not in data: data[varName] = {} # If variable name NOT in data dictionary, initialize new dictionary under key data[varName][varLvl] = res.getRawData() # Add data under level name try: # Try to unit = units(res.getUnit()) # Get units and convert to MetPy units except: # On exception unit = '?' # Set units to ? else: # If get units success data[varName][varLvl] *= unit # Get data and create MetPy quantity by multiplying by units log.debug( 'Got data for:\n Var: {}\n Lvl: {}\n Unit: {}'.format( varName, varLvl, unit)) data['lon'], data['lat'] = res.getLatLonCoords() # Get latitude and longitude values data['lon'] *= units('degree') # Add units of degree to longitude data['lat'] *= units('degree') # Add units of degree to latitude # Absolute vorticity dx, dy = lat_lon_grid_deltas(data['lon'], data['lat']) # Get grid spacing in x and y uTag = mdl2stnd[model_vars['wind']['parameters'][0]] # Get initial tag name for u-wind vTag = mdl2stnd[model_vars['wind']['parameters'][1]] # Get initial tag name for v-wind if (uTag in data) and ( vTag in data): # If both tags are in the data structure data['abs_vort'] = {} # Add absolute vorticity key for lvl in model_vars['wind'][ 'levels']: # Iterate over all leves in the wind data if (lvl in data[uTag]) and ( lvl in data[vTag] ): # If given level in both u- and v-wind dictionaries log.debug('Computing absolute vorticity at {}'.format(lvl)) data['abs_vort'][ lvl ] = \ absolute_vorticity( data[uTag][lvl], data[vTag][lvl], dx, dy, data['lat'] ) # Compute absolute vorticity # 1000 MB equivalent potential temperature if ('temperature' in data) and ( 'dewpoint' in data): # If temperature AND depoint data were downloaded data['theta_e'] = {} T, Td = 'temperature', 'dewpoint' if ('1000.0MB' in data[T]) and ( '1000.0MB' in data[Td] ): # If temperature AND depoint data were downloaded log.debug( 'Computing equivalent potential temperature at 1000 hPa') data['theta_e']['1000.0MB'] = equivalent_potential_temperature( 1000.0 * units('hPa'), data[T]['1000.0MB'], data[Td]['1000.0MB']) return data # MLCAPE log.debug('Computing mixed layer CAPE') T_lvl = list(data[T].keys()) Td_lvl = list(data[Td].keys()) levels = list(set(T_lvl).intersection(Td_lvl)) levels = [float(lvl.replace('MB', '')) for lvl in levels] levels = sorted(levels, reverse=True) nLvl = len(levels) if nLvl > 0: log.debug( 'Found {} matching levels in temperature and dewpoint data' .format(nLvl)) nLat, nLon = data['lon'].shape data['MLCAPE'] = np.zeros(( nLat, nLon, ), dtype=np.float32) * units('J/kg') TT = np.zeros(( nLvl, nLat, nLon, ), dtype=np.float32) * units('degC') TTd = np.zeros(( nLvl, nLat, nLon, ), dtype=np.float32) * units('degC') log.debug('Sorting temperature and dewpoint data by level') for i in range(nLvl): key = '{:.1f}MB'.format(levels[i]) TT[i, :, :] = data[T][key].to('degC') TTd[i, :, :] = data[Td][key].to('degC') levels = np.array(levels) * units.hPa depth = 100.0 * units.hPa log.debug('Iterating over grid boxes to compute MLCAPE') for j in range(nLat): for i in range(nLon): try: _, T_parc, Td_parc = mixed_parcel( levels, TT[:, j, i], TTd[:, j, i], depth=depth, interpolate=False, ) profile = parcel_profile(levels, T_parc, Td_parc) cape, cin = cape_cin(levels, TT[:, j, i], TTd[:, j, i], profile) except: log.warning( 'Failed to compute MLCAPE for lon/lat: {}; {}'. format(data['lon'][j, i], data['lat'][j, i])) else: data['MLCAPE'][j, i] = cape return data