Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document possible agent reporter inputs in the datacollector #1837

Closed
EwoutH opened this issue Oct 18, 2023 · 8 comments · Fixed by #1838
Closed

Document possible agent reporter inputs in the datacollector #1837

EwoutH opened this issue Oct 18, 2023 · 8 comments · Fixed by #1838

Comments

@EwoutH
Copy link
Member

EwoutH commented Oct 18, 2023

Currently in the data collector documentation its defined very well which inputs model reporters can take:

Notes:
If you want to pickle your model you must not use lambda functions.
If your model includes a large number of agents, you should *only*
use attribute names for the agent reporter, it will be much faster.
Model reporters can take four types of arguments:
lambda like above:
{"agent_count": lambda m: m.schedule.get_agent_count() }
method of a class/instance:
{"agent_count": self.get_agent_count} # self here is a class instance
{"agent_count": Model.get_agent_count} # Model here is a class
class attributes of a model
{"model_attribute": "model_attribute"}
functions with parameters that have placed in a list
{"Model_Function":[function, [param_1, param_2]]}
"""
self.model_reporters = {}
self.agent_reporters = {}

However, this isn't done for the agent reports. Could this documentation be added?

@rht
Copy link
Contributor

rht commented Oct 18, 2023

I checked the code. I can't find any that implements

             functions with parameters that have placed in a list 
             {"Model_Function":[function, [param_1, param_2]]} 

in the latest main.

@rht
Copy link
Contributor

rht commented Oct 19, 2023

I found it in

self.model_vars[var].append(reporter[0](*reporter[1]))
. Was added in 80511e2#diff-72396865b218fb20682afecba66d3b794e1306841d39490ed4037e26cba31b29L165. @tpike3 is the reason why you added the feature was for pickling issue in multiprocessing?

@EwoutH
Copy link
Member Author

EwoutH commented Oct 24, 2023

I would be fine with removing the "Functions with parameters placed in a list" behaviour by the way, as long as we keep the syntax for agent_reporters and model_reporters identical (and thus remove it from both).

@rht
Copy link
Contributor

rht commented Oct 24, 2023

I agree with removing it in both agent and model reporters. I haven't compiled the list of breaking changes for Mesa 3.0 yet.

@EwoutH
Copy link
Member Author

EwoutH commented Oct 24, 2023

Then I would propose removing it for the agent-reporter immediately, and adding a deprecation warning to the model-reporter ASAP.

To summerize, we propose to remove method nr 4 as it's practically identical to nr 1.

Model reporters can take four types of arguments:
        1. Lambda function:
           {"agent_count": lambda m: m.schedule.get_agent_count()}
        2. Method of a class/instance:
           {"agent_count": self.get_agent_count} # self here is a class instance
           {"agent_count": Model.get_agent_count} # Model here is a class
        3. Class attributes of a model:
           {"model_attribute": "model_attribute"}
        4. Functions with parameters that have been placed in a list:
           {"Model_Function": [function, [param_1, param_2]]}

        Agent reporters can similarly take:
        1. Attribute name (string) referring to agent's attribute:
           {"energy": "energy"}
        2. Lambda function:
           {"energy": lambda a: a.energy}
        3. Method of an agent class/instance:
           {"agent_action": self.do_action} # self here is an agent class instance
           {"agent_action": Agent.do_action} # Agent here is a class
        4. Functions with parameters placed in a list:
           {"Agent_Function": [function, [param_1, param_2]]}

@tpike3 @jackiekazil @Corvince curious what you think.

@Corvince
Copy link
Contributor

Agree with removing #4, but I think #1 and #2 are also the same, unless I am missing something.

I would say removing #4 leaves us with two possibilities: either as an attribute string or a function-like object that takes either model or agent as its only argument. It shouldn't matter if it's a lambda type, class/instance method or normal function. Or am I missing something?

@wang-boyu
Copy link
Member

Got a question that's related to #4. If a function has extra parameters, how should it be used in reporters?

For example for agent reports

def some_func(agent, param_1, param_2):
    result = ... # do something with agent and parameters
    return result

should it be used like this

from functools import partial


agent_reporters = {
    "reported_value": partial(some_func, param_1=some_value, param_2=some_other_value)
}

@tpike3
Copy link
Member

tpike3 commented Oct 25, 2023

I found it in

self.model_vars[var].append(reporter[0](*reporter[1]))

. Was added in 80511e2#diff-72396865b218fb20682afecba66d3b794e1306841d39490ed4037e26cba31b29L165. @tpike3 is the reason why you added the feature was for pickling issue in multiprocessing?

Sorry for the delay, but yes @rht reason was because of pickling issue for multiprocessing, so if I am understnading correctly removing option 4 would cause some issues with batch_run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants