DHDRL commited on
Commit
21d2d59
·
verified ·
1 Parent(s): aa86e49

Update weather_forecast_env.py

Browse files
Files changed (1) hide show
  1. weather_forecast_env.py +27 -38
weather_forecast_env.py CHANGED
@@ -236,25 +236,25 @@ def _make_per_zone_forecasts(
236
  clean_ratio: float,
237
  spatial_corr: float = 0.85,
238
  event_plan: Optional[List[Dict[str, bool]]] = None,
 
239
  ) -> List[Any]:
240
  if event_plan is None:
241
- event_plan = _episode_event_plan(
242
- len(zone_ids), base_seed, clean_ratio, spatial_corr
243
- )
244
  forecasts = []
245
  for i, zid in enumerate(zone_ids):
246
- ev = event_plan[i] if i < len(event_plan) else _zone_event_flags(
247
- base_seed + i, clean_ratio
248
- )
249
- fc = make_synthetic_forecast_result(
250
- zid,
251
- horizon_days=horizon,
252
- valid_time=valid_time,
253
- seed=base_seed + i * 31,
254
- drought=ev["drought"],
255
- flood=ev["flood"],
256
- )
257
- forecasts.append(fc)
258
  return forecasts
259
 
260
 
@@ -383,32 +383,20 @@ class WeatherForecastEnv(gym.Env):
383
  self._context_source: str = "synthetic"
384
 
385
  self._real_index = None
386
- pkl_path = getattr(self.config, "real_data_pkl_path", None)
387
  if pkl_path:
388
  if RealEpisodeIndex is None:
389
- logger.warning(
390
- "WeatherForecastEnv: config.real_data_pkl_path=%r set, "
391
- "but real_episode_sampler.py is not importable -- "
392
- "training will remain fully synthetic.",
393
- pkl_path,
394
  )
395
- else:
396
- try:
397
- self._real_index = RealEpisodeIndex(pkl_path)
398
- logger.info(
399
- "WeatherForecastEnv: real-data training sampling "
400
- "ENABLED from %s (%d eligible dates, "
401
- "real_data_ratio=%.2f, inject_noise=%s)",
402
- pkl_path, self._real_index.n_eligible_dates,
403
- self.config.real_data_ratio, self.config.inject_noise,
404
- )
405
- except Exception as e:
406
- logger.error(
407
- "WeatherForecastEnv: failed to load "
408
- "real_data_pkl_path=%r (%s) -- training will "
409
- "remain fully synthetic.", pkl_path, e,
410
- )
411
- self._real_index = None
412
 
413
  logger.info(
414
  "WeatherForecastEnv: n_zones=%d horizon=%dd max_steps=%d "
@@ -567,6 +555,7 @@ class WeatherForecastEnv(gym.Env):
567
  self.config.clean_episode_ratio,
568
  spatial_corr=rho,
569
  event_plan=plan,
 
570
  )
571
  self._zone_obs = _make_per_zone_obs(
572
  self._zone_ids, effective_seed, self.config.clean_episode_ratio,
 
236
  clean_ratio: float,
237
  spatial_corr: float = 0.85,
238
  event_plan: Optional[List[Dict[str, bool]]] = None,
239
+ flag_error_rate: float = 0.0,
240
  ) -> List[Any]:
241
  if event_plan is None:
242
+ event_plan = _episode_event_plan(len(zone_ids), base_seed, clean_ratio, spatial_corr)
243
+ err_rng = random.Random(base_seed + 1337) # separate stream, never perturbs other draws
 
244
  forecasts = []
245
  for i, zid in enumerate(zone_ids):
246
+ ev = event_plan[i] if i < len(event_plan) else _zone_event_flags(base_seed + i, clean_ratio)
247
+ drought, flood = ev['drought'], ev['flood']
248
+ if flag_error_rate > 0.0 and err_rng.random() < flag_error_rate:
249
+ if drought or flood:
250
+ drought = flood = False # forecast misses a real event
251
+ elif err_rng.random() < 0.5:
252
+ drought, flood = True, False # false drought alarm
253
+ else:
254
+ drought, flood = False, True # false flood alarm
255
+ forecasts.append(make_synthetic_forecast_result(
256
+ zid, horizon_days=horizon, valid_time=valid_time,
257
+ seed=base_seed + i * 31, drought=drought, flood=flood))
258
  return forecasts
259
 
260
 
 
383
  self._context_source: str = "synthetic"
384
 
385
  self._real_index = None
386
+ pkl_path = getattr(self.config, 'real_data_pkl_path', None)
387
  if pkl_path:
388
  if RealEpisodeIndex is None:
389
+ raise RuntimeError(
390
+ f'real_data_pkl_path={pkl_path!r} is set but real_episode_sampler.py '
391
+ 'is not importable; refusing to fall back to synthetic training.'
 
 
392
  )
393
+ self._real_index = RealEpisodeIndex(pkl_path) # load errors propagate
394
+ logger.info(
395
+ 'WeatherForecastEnv: real-data sampling ENABLED from %s '
396
+ '(%d eligible dates, real_data_ratio=%.2f, inject_noise=%s)',
397
+ pkl_path, self._real_index.n_eligible_dates,
398
+ self.config.real_data_ratio, self.config.inject_noise,
399
+ )
 
 
 
 
 
 
 
 
 
 
400
 
401
  logger.info(
402
  "WeatherForecastEnv: n_zones=%d horizon=%dd max_steps=%d "
 
555
  self.config.clean_episode_ratio,
556
  spatial_corr=rho,
557
  event_plan=plan,
558
+ flag_error_rate=float(getattr(self.config, 'forecast_flag_error_rate', 0.0)),
559
  )
560
  self._zone_obs = _make_per_zone_obs(
561
  self._zone_ids, effective_seed, self.config.clean_episode_ratio,