Skip to content

Commit abac825

Browse files
authored
datacollector: store separate snapshots of model data per step (#2129)
* datecollector: store separate snapshots of model data per step - Ensure `DataCollector` stores unique copies of the data at each model step. - Use `deepcopy` in `collect` method to avoid storing references that lead to each step holding the same data. - Fixes the issue where PropertyLayer data was stored identically for all steps, preventing accurate visualization and analysis of model progression. * datacollection: Add deepcopy comment
1 parent a2d4afe commit abac825

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

mesa/datacollection.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import contextlib
3737
import itertools
3838
import types
39+
from copy import deepcopy
3940
from functools import partial
4041

4142
with contextlib.suppress(ImportError):
@@ -197,17 +198,21 @@ def collect(self, model):
197198
for var, reporter in self.model_reporters.items():
198199
# Check if lambda or partial function
199200
if isinstance(reporter, types.LambdaType | partial):
200-
self.model_vars[var].append(reporter(model))
201+
# Use deepcopy to store a copy of the data,
202+
# preventing references from being updated across steps.
203+
self.model_vars[var].append(deepcopy(reporter(model)))
201204
# Check if model attribute
202205
elif isinstance(reporter, str):
203-
self.model_vars[var].append(getattr(model, reporter, None))
206+
self.model_vars[var].append(
207+
deepcopy(getattr(model, reporter, None))
208+
)
204209
# Check if function with arguments
205210
elif isinstance(reporter, list):
206-
self.model_vars[var].append(reporter[0](*reporter[1]))
207-
# TODO: Check if method of a class, as of now it is assumed
208-
# implicitly if the other checks fail.
211+
self.model_vars[var].append(deepcopy(reporter[0](*reporter[1])))
212+
# Assume it's a callable otherwise (e.g., method)
213+
# TODO: Check if method of a class explicitly
209214
else:
210-
self.model_vars[var].append(reporter())
215+
self.model_vars[var].append(deepcopy(reporter()))
211216

212217
if self.agent_reporters:
213218
agent_records = self._record_agents(model)

0 commit comments

Comments
 (0)