Skip to content

Commit

Permalink
Add workaround for problems with microseconds
Browse files Browse the repository at this point in the history
Workaround for storage not handling datetimes
with microseconds due to index overflow in netcdf3.
#6952
  • Loading branch information
eivindjahren committed Jan 22, 2024
1 parent bfb7547 commit 91e519a
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 24 deletions.
20 changes: 13 additions & 7 deletions src/ert/analysis/_es_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,22 +311,28 @@ def _get_obs_and_measure_data(
name: list(set(index.get_level_values(name))) for name in index.names
}
observation = observation.sel(sub_selection)
ds = source_fs.load_responses(group, tuple(iens_active_index))
response = source_fs.load_responses(group, tuple(iens_active_index))
if "time" in observation.coords:
response = response.reindex(
time=observation.time, method="nearest", tolerance="1s"

Check failure on line 317 in src/ert/analysis/_es_update.py

View workflow job for this annotation

GitHub Actions / type-checking (3.11)

Argument "tolerance" to "reindex" of "Dataset" has incompatible type "str"; expected "int | float | Iterable[int | float] | None"
)
try:
filtered_ds = observation.merge(ds, join="left")
filtered_response = observation.merge(response, join="left")
except KeyError as e:
raise ErtAnalysisError(
f"Mismatched index for: "
f"Observation: {obs_key} attached to response: {group}"
) from e

observation_keys.append([obs_key] * len(filtered_ds.observations.data.ravel()))
observation_values.append(filtered_ds["observations"].data.ravel())
observation_errors.append(filtered_ds["std"].data.ravel())
observation_keys.append(
[obs_key] * len(filtered_response.observations.data.ravel())
)
observation_values.append(filtered_response["observations"].data.ravel())
observation_errors.append(filtered_response["std"].data.ravel())
measured_data.append(
filtered_ds["values"]
filtered_response["values"]
.transpose(..., "realization")
.values.reshape((-1, len(filtered_ds.realization)))
.values.reshape((-1, len(filtered_response.realization)))
)
source_fs.load_responses.cache_clear()
return (
Expand Down
14 changes: 12 additions & 2 deletions src/ert/config/_read_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ def _read_spec(
hour=hour,
minute=minute,
second=microsecond // 10**6,
microsecond=microsecond % 10**6,
# Due to https://github.com/equinor/ert/issues/6952
# microsecond=self.micro_seconds % 10**6,
)
except Exception as err:
raise ValueError(
Expand Down Expand Up @@ -427,7 +428,16 @@ def read_params() -> None:
if last_params is not None:
vals = _check_vals("PARAMS", summary, last_params.read_array())
values.append(vals[indices])
dates.append(start_date + unit.make_delta(float(vals[date_index])))

truncate = lambda t, d: t + (datetime.min - t) % -d
dates.append(
truncate(
start_date + unit.make_delta(float(vals[date_index])),
timedelta(seconds=1),
)
)
# Due to https://github.com/equinor/ert/issues/6952
# dates.append(start_date + unit.make_delta(float(vals[date_index])))
last_params = None

with open(summary, mode) as fp:
Expand Down
13 changes: 0 additions & 13 deletions src/ert/config/summary_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,6 @@ def __post_init__(self) -> None:
def read_from_file(self, run_path: str, iens: int) -> xr.Dataset:
filename = self.input_file.replace("<IENS>", str(iens))
_, keys, time_map, data = read_summary(f"{run_path}/{filename}", self.keys)

if self.refcase:
assert isinstance(self.refcase, set)
missing = self.refcase.difference(time_map)
if missing:
first, last = min(missing), max(missing)
logger.warning(
f"Realization: {iens}, load warning: {len(missing)} "
f"inconsistencies in time map, first: Time mismatch for response "
f"time: {first}, last: Time mismatch for response time: "
f"{last} from: {run_path}/{filename}.UNSMRY"
)

ds = xr.Dataset(
{"values": (["name", "time"], data)},
coords={"time": time_map, "name": keys},
Expand Down
7 changes: 5 additions & 2 deletions tests/unit_tests/config/summary_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ def to_datetime(self) -> datetime:
hour=self.hour,
minute=self.minutes,
second=self.micro_seconds // 10**6,
microsecond=self.micro_seconds % 10**6,
# Due to https://github.com/equinor/ert/issues/6952
# microsecond=self.micro_seconds % 10**6,
)

@classmethod
Expand All @@ -216,7 +217,9 @@ def from_datetime(cls, dt: datetime) -> Self:
day=dt.day,
hour=dt.hour,
minutes=dt.minute,
micro_seconds=dt.second * 10**6 + dt.microsecond,
# Due to https://github.com/equinor/ert/issues/6952
micro_seconds=dt.second * 10**6,
# micro_seconds=dt.second * 10**6 + dt.microsecond,
)


Expand Down

0 comments on commit 91e519a

Please sign in to comment.