def fill_in_fields(self): # The following is from BSF d = self.first.date() s = sun.Sun(lat=self.lat, lng=self.lng) sunrise = s.sunrise_hr(d) + self.utc_offset sunset = s.sunset_hr(d) + self.utc_offset # default Planetary Boundary Layer (PBL) step function default_pbl = lambda hr, sunrise, sunset: 1000.0 if ( sunrise + 1) < hr < sunset else 100.0 for dt, hp in list(self.hourly_profile.items()): hr = (dt - self.first).total_seconds() / 3600.0 hp['lat'] = self.lat hp['lng'] = self.lng for k in [ 'pressure', 'TPOT', 'WSPD', 'WDIR', 'WWND', 'TEMP', 'SPHU' ]: hp[k] = hp.get(k) if not hp.get('HGTS'): hp['HGTS'] = self.calc_height(hp['pressure']) if not hp.get('RELH'): hp['RELH'] = self.calc_rh(hp['pressure'], hp['SPHU'], hp['TEMP']) hp['dew_point'] = self.calc_dew_point(hp['RELH'], hp['TEMP']) hp['sunrise_hour'] = sunrise hp['sunset_hour'] = sunset # Note: Based on what they stand for and on looking at the SEV # plumerise logic, it appears that 'PBLH' and 'HPBL' are aliases # for one anohther. ('Planetary Boundary Layer Height' vs 'Height # of Planetary Boundary Layer'.) If so, I don't see why the two # values aren't consolidated into a single variable here, as opposed # to storing them as separate values and only defaulting 'HPBL' to # `default_pbl(hr, sunrise, sunset)` (which is the current logic # that was taken from BSF). The logic could be replace with # something like: # _pblh = self.list_to_scalar(hp, pblh, lambda: None) # _hpbl = self.list_to_scalar(hp, hpbl, lambda: None) # if _pblh is not None: # hp['pblh'] = _pblh # elif _hpbl is not None: # hp['pblh'] = _pblh # else: # hp['pblh'] = default_pbl(hr, sunrise, sunset) for k in [ 'TO2M', 'RH2M', 'TPP3', 'TPP6', 'PBLH', 'T02M', 'U10M', 'V10M', 'PRSS', 'SHGT', 'TPPA', 'pressure_at_surface', ]: self.list_to_scalar(hp, k, lambda: None) self.list_to_scalar(hp, 'HPBL', lambda: default_pbl(hr, sunrise, sunset))
def _f(fire, working_dir): # TODO: create and change to working directory here (per fire), # above (one working dir per all fires), or below (per activity # window)...or just let plumerise create temp workingdir (as # it's currently doing? for aa in fire.active_areas: start = aa.get('start') if not start: raise ValueError(MISSING_START_TIME_ERROR_MSG) start = datetimeutils.parse_datetime(aa.get('start'), 'start') if not aa.get('timeprofile'): raise ValueError(MISSING_TIMEPROFILE_ERROR_MSG) for loc in aa.locations: if not loc.get('consumption', {}).get('summary'): raise ValueError(MISSING_CONSUMPTION_ERROR_MSG) # Fill in missing sunrise / sunset if any([ loc.get(k) is None for k in ('sunrise_hour', 'sunset_hour') ]): # default: UTC utc_offset = datetimeutils.parse_utc_offset( loc.get('utc_offset', 0.0)) # Use NOAA-standard sunrise/sunset calculations latlng = locationutils.LatLng(loc) s = sun.Sun(lat=latlng.latitude, lng=latlng.longitude) d = start.date() # just set them both, even if one is already set loc["sunrise_hour"] = s.sunrise_hr(d, utc_offset) loc["sunset_hour"] = s.sunset_hr(d, utc_offset) fire_working_dir = _get_fire_working_dir(fire, working_dir) plumerise_data = pr.compute(aa['timeprofile'], loc['consumption']['summary'], loc, working_dir=fire_working_dir) loc['plumerise'] = plumerise_data['hours'] if config.get("load_heat"): if 'fuelbeds' not in loc: raise ValueError( "Fuelbeds should exist before loading heat in plumerise" ) loc["fuelbeds"][0]["heat"] = _loadHeat( fire_working_dir)
def _fill_fire_location_info(self, fire_loc, fire_location_info): for k, v in list(self.FIRE_LOCATION_INFO_DEFAULTS.items()): if fire_location_info.get(k) is None: fire_location_info[k] = v if fire_location_info.get('sunset_hour') is None: dt = fire_loc['start'] utc_offset = fire_loc['utc_offset'] tmidday = datetime(dt.year, dt.month, dt.day, int(12)) try: s = sun.Sun(lat=float(fire_loc["specified_points"][0]['lat']), lng=float(fire_loc["specified_points"][0]['lng'])) fire_location_info['sunrise_hour'] = s.sunrise_hr( tmidday, int(utc_offset)) fire_location_info['sunset_hour'] = s.sunset_hr( tmidday, int(utc_offset)) except: # this calculation can fail near the North/South poles fire_location_info['sunrise_hour'] = 6 fire_location_info['sunset_hour'] = 18
def _f(fire): # TODO: create and change to working directory here (per fire), # above (one working dir per all fires), or below (per activity # window)...or just let plumerise create temp workingdir (as # it's currently doing? for a in fire.activity: if not a.get('consumption', {}).get('summary'): raise ValueError("Missing fire activity consumption data " "required for FEPS plumerise") # Fill in missing sunrise / sunset if any([a['location'].get(k) is None for k in ('sunrise_hour', 'sunset_hour')]): start = datetimeutils.parse_datetime(a['start'], 'start') if not start: raise ValueError("Missing fire activity start time " "required by FEPS plumerise") # default: UTC utc_offset = datetimeutils.parse_utc_offset( a['location'].get('utc_offset', 0.0)) # Use NOAA-standard sunrise/sunset calculations latlng = locationutils.LatLng(a['location']) s = sun.Sun(lat=latlng.latitude, lng=latlng.longitude) d = start.date() # just set them both, even if one is already set a['location']["sunrise_hour"] = s.sunrise_hr(d, utc_offset) a['location']["sunset_hour"] = s.sunset_hr(d, utc_offset) if not a.get('timeprofile'): raise ValueError("Missing timeprofile data required for " "computing FEPS plumerise") plumerise_data = pr.compute(a['timeprofile'], a['consumption']['summary'], a['location'], working_dir=_get_working_dir(fire)) a['plumerise'] = plumerise_data['hours']