Module pybeepop.pybeepop
pybeepop - BeePop+ interface for Python
Classes
class PyBeePop (lib_file=None,
parameter_file=None,
weather_file=None,
residue_file=None,
verbose=False)-
Expand source code
class PyBeePop: """ Python interface for the BeePop+ honey bee colony simulation model. BeePop+ is a mechanistic model for simulating honey bee colony dynamics, designed for ecological risk assessment and research applications. This interface enables programmatic access to BeePop+ from Python, supporting batch simulations, sensitivity analysis, and integration with data analysis workflows. For scientific background, model structure, and example applications, see: Garber et al. (2022), "Simulating the Effects of Pesticides on Honey Bee (Apis mellifera L.) Colonies with BeePop+", Ecologies. Minucci et al. (2025), "pybeepop: A Python interface for the BeePop+ honey bee colony model," Journal of Open Research Software. Example usage: >>> from pybeepop.pybeepop import PyBeePop >>> model = PyBeePop(parameter_file='params.txt', weather_file='weather.csv', residue_file='residues.csv') >>> model.run_model() >>> results = model.get_output() >>> model.plot_output() """ def __init__( self, lib_file=None, parameter_file=None, weather_file=None, residue_file=None, verbose=False, ): """ Initialize a PyBeePop object connected to a BeePop+ shared library. Args: lib_file (str, optional): Path to the BeePop+ shared library (.dll or .so). If None, attempts to auto-detect based on OS and architecture. parameter_file (str, optional): Path to a text file of BeePop+ parameters (one per line, parameter=value). See https://doi.org/10.3390/ecologies3030022 or the documentation for valid parameters. weather_file (str, optional): Path to a .csv or comma-separated .txt file containing weather data, where each row denotes: Date (MM/DD/YY), Max Temp (C), Min Temp (C), Avg Temp (C), Windspeed (m/s), Rainfall (mm), Hours of daylight (optional). residue_file (str, optional): Path to a .csv or comma-separated .txt file containing pesticide residue data. Each row should specify Date (MM/DD/YYYY), Concentration in nectar (g A.I. / g), Concentration in pollen (g A.I. / g). Values can be in scientific notation (e.g., "9.00E-08"). verbose (bool, optional): If True, print additional debugging statements. Defaults to False. Raises: FileNotFoundError: If a provided file does not exist at the specified path. NotImplementedError: If run on a platform that is not 64-bit Windows or Linux. """ self.parent = os.path.dirname(os.path.abspath(__file__)) self.platform = platform.system() self.verbose = verbose if ( lib_file is None ): # detect OS and architecture and use pre-compiled BeePop+ if possible if self.platform == "Windows": if platform.architecture()[0] == "32bit": raise NotImplementedError( "Windows x86 (32-bit) is not supported by BeePop+. Please run on an x64 platform." ) else: lib_file = os.path.join(self.parent, "lib/beepop_win64.dll") elif self.platform == "Linux": lib_file = os.path.join(self.parent, "lib/beepop_linux.so") if self.verbose: print( """ Running in Linux mode. Trying manylinux/musllinux version. If you encounter errors, you may need to compile your own version of BeePop+ from source and pass the path to your .so file with the lib_file option. Currently, only 64-bit architecture is supported. See the pybeepop README for instructions. """ ) else: raise NotImplementedError("BeePop+ only supports Windows and Linux.") if not os.path.isfile(lib_file): raise FileNotFoundError( """ BeePop+ shared object library does not exist or is not compatible with your operating system. You may need to compile BeePop+ from source (see https://github.com/USEPA/pybeepop/blob/main/README.md for more info.) Currently, only 64-bit architecture is supported. """ ) self.lib_file = lib_file self.beepop = BeePopModel(self.lib_file, verbose=self.verbose) self.parameters = None if parameter_file is not None: self.load_parameter_file(self.parameter_file) else: self.parameter_file = None if weather_file is not None: self.load_weather(weather_file) else: self.weather_file = None if residue_file is not None: self.load_residue_file(self.residue_file) else: self.residue_file = None # self.new_features = new_features # not being used? self.output = None def set_parameters(self, parameters): """ Set BeePop+ parameters based on a dictionary {parameter: value}. Args: parameters (dict): Dictionary of BeePop+ parameters {parameter: value}. See https://doi.org/10.3390/ecologies3030022 or the documentation for valid parameters. Raises: TypeError: If parameters is not a dict. ValueError: If a parameter is not a valid BeePop+ parameter. """ if (parameters is not None) and (not isinstance(parameters, dict)): raise TypeError( "parameters must be a named dictionary of BeePop+ parameters" ) self.parameters = self.beepop.set_parameters(parameters) def get_parameters(self): """ Return all parameters that have been set by the user. Returns: dict: Dictionary of current BeePop+ parameters. """ return self.beepop.get_parameters() def load_weather(self, weather_file): """ Load a weather file. The file should be a .csv or comma-delimited .txt file where each row denotes: Date (MM/DD/YY), Max Temp (C), Min Temp (C), Avg Temp (C), Windspeed (m/s), Rainfall (mm), Hours of daylight (optional). Args: weather_file (str): Path to the weather file (csv or txt). See docs/weather_readme.txt and manuscript for format details. Raises: FileNotFoundError: If the provided file does not exist at the specified path. """ if not os.path.isfile(weather_file): raise FileNotFoundError( "Weather file does not exist at path: {}!".format(weather_file) ) self.weather_file = weather_file self.beepop.load_weather(self.weather_file) def load_parameter_file(self, parameter_file): """ Load a .txt file of parameter values to set. Each row of the file is a string with the format 'parameter=value'. Args: parameter_file (str): Path to a txt file of BeePop+ parameters. See https://doi.org/10.3390/ecologies3030022 or the documentation for valid parameters. Raises: FileNotFoundError: If the provided file does not exist at the specified path. ValueError: If a listed parameter is not a valid BeePop+ parameter. """ if not os.path.isfile(parameter_file): raise FileNotFoundError( "Paramter file does not exist at path: {}!".format(parameter_file) ) self.parameter_file = parameter_file self.beepop.load_input_file(self.parameter_file) def load_residue_file(self, residue_file): """ Load a .csv or comma-delimited .txt file of pesticide residues in pollen/nectar. Each row should specify Date (MM/DD/YYYY), Concentration in nectar (g A.I. / g), Concentration in pollen (g A.I. / g). Values can be in scientific notation (e.g., "9.00E-08"). Args: residue_file (str): Path to the residue .csv or .txt file. See docs/residue_file_readme.txt and manuscript for format details. Raises: FileNotFoundError: If the provided file does not exist at the specified path. """ if not os.path.isfile(residue_file): raise FileNotFoundError( "Residue file does not exist at path: {}!".format(residue_file) ) self.residue_file = residue_file self.beepop.load_contam_file(self.residue_file) def run_model(self): """ Run the BeePop+ model simulation. Raises: RuntimeError: If the weather file has not yet been set. Returns: pandas.DataFrame: DataFrame of daily time series results for the BeePop+ run, including colony size, adult workers, brood, eggs, and other metrics. """ # check to see if parameters have been supplied if (self.parameter_file is None) and (self.parameters is None): print("No parameters have been set. Running with defualt settings.") if self.weather_file is None: raise RuntimeError("Weather must be set before running BeePop+!") self.output = self.beepop.run_beepop() return self.output def get_output(self, format="DataFrame"): """ Get the output from the last BeePop+ run. Args: format (str, optional): Return results as DataFrame ('DataFrame') or JSON string ('json'). Defaults to 'DataFrame'. Raises: RuntimeError: If there is no output because run_model has not yet been called. Returns: pandas.DataFrame or str: DataFrame or JSON string of the model results. JSON output is a dictionary of lists keyed by column name. """ if self.output is None: raise RuntimeError( "There are no results to plot. Please run the model first." ) if format == "json": result = json.dumps(self.output.to_dict(orient="list")) else: result = self.output return result def plot_output( self, columns=[ "Colony Size", "Adult Workers", "Capped Worker Brood", "Worker Larvae", "Worker Eggs", ], ): """ Plot the output as a time series. Args: columns (list, optional): List of column names to plot (as strings). Defaults to key colony metrics. Raises: RuntimeError: If there is no output because run_model has not yet been called. IndexError: If any column name is not a valid output column. Returns: matplotlib.axes.Axes: Matplotlib Axes object for further customization. """ if self.output is None: raise RuntimeError( "There are no results to plot. Please run the model first." ) invalid_cols = [col not in self.output.columns for col in columns] if any(invalid_cols): raise IndexError( "The column name {} is not a valid output column.".format( [i for (i, v) in zip(columns, invalid_cols) if v] ) ) plot = plot_timeseries(output=self.output, columns=columns) return plot def get_error_log(self): """ Return the BeePop+ session error log as a string for debugging. Useful for troubleshooting. Returns: str: Error log from the BeePop+ session. """ return self.beepop.get_errors() def get_info_log(self): """ Return the BeePop+ session info log as a string for debugging.. Returns: str: Info log from the BeePop+ session. """ return self.beepop.get_info() def version(self): """ Return the BeePop+ version as a string. Returns: str: BeePop+ version string. """ version = self.beepop.get_version() return version def exit(self): """ Close the connection to the BeePop+ shared library and clean up resources. """ self.beepop.close_library() del self.beepop return
Python interface for the BeePop+ honey bee colony simulation model.
BeePop+ is a mechanistic model for simulating honey bee colony dynamics, designed for ecological risk assessment and research applications. This interface enables programmatic access to BeePop+ from Python, supporting batch simulations, sensitivity analysis, and integration with data analysis workflows.
For scientific background, model structure, and example applications, see: Garber et al. (2022), "Simulating the Effects of Pesticides on Honey Bee (Apis mellifera L.) Colonies with BeePop+", Ecologies. Minucci et al. (2025), "pybeepop: A Python interface for the BeePop+ honey bee colony model," Journal of Open Research Software.
Example usage: >>> from pybeepop.pybeepop import PyBeePop >>> model = PyBeePop(parameter_file='params.txt', weather_file='weather.csv', residue_file='residues.csv') >>> model.run_model() >>> results = model.get_output() >>> model.plot_output()
Initialize a PyBeePop object connected to a BeePop+ shared library.
Args
lib_file
:str
, optional- Path to the BeePop+ shared library (.dll or .so). If None, attempts to auto-detect based on OS and architecture.
parameter_file
:str
, optional- Path to a text file of BeePop+ parameters (one per line, parameter=value). See https://doi.org/10.3390/ecologies3030022 or the documentation for valid parameters.
weather_file
:str
, optional- Path to a .csv or comma-separated .txt file containing weather data, where each row denotes: Date (MM/DD/YY), Max Temp (C), Min Temp (C), Avg Temp (C), Windspeed (m/s), Rainfall (mm), Hours of daylight (optional).
residue_file
:str
, optional- Path to a .csv or comma-separated .txt file containing pesticide residue data. Each row should specify Date (MM/DD/YYYY), Concentration in nectar (g A.I. / g), Concentration in pollen (g A.I. / g). Values can be in scientific notation (e.g., "9.00E-08").
verbose
:bool
, optional- If True, print additional debugging statements. Defaults to False.
Raises
FileNotFoundError
- If a provided file does not exist at the specified path.
NotImplementedError
- If run on a platform that is not 64-bit Windows or Linux.
Methods
def exit(self)
-
Expand source code
def exit(self): """ Close the connection to the BeePop+ shared library and clean up resources. """ self.beepop.close_library() del self.beepop return
Close the connection to the BeePop+ shared library and clean up resources.
def get_error_log(self)
-
Expand source code
def get_error_log(self): """ Return the BeePop+ session error log as a string for debugging. Useful for troubleshooting. Returns: str: Error log from the BeePop+ session. """ return self.beepop.get_errors()
Return the BeePop+ session error log as a string for debugging. Useful for troubleshooting.
Returns
str
- Error log from the BeePop+ session.
def get_info_log(self)
-
Expand source code
def get_info_log(self): """ Return the BeePop+ session info log as a string for debugging.. Returns: str: Info log from the BeePop+ session. """ return self.beepop.get_info()
Return the BeePop+ session info log as a string for debugging..
Returns
str
- Info log from the BeePop+ session.
def get_output(self, format='DataFrame')
-
Expand source code
def get_output(self, format="DataFrame"): """ Get the output from the last BeePop+ run. Args: format (str, optional): Return results as DataFrame ('DataFrame') or JSON string ('json'). Defaults to 'DataFrame'. Raises: RuntimeError: If there is no output because run_model has not yet been called. Returns: pandas.DataFrame or str: DataFrame or JSON string of the model results. JSON output is a dictionary of lists keyed by column name. """ if self.output is None: raise RuntimeError( "There are no results to plot. Please run the model first." ) if format == "json": result = json.dumps(self.output.to_dict(orient="list")) else: result = self.output return result
Get the output from the last BeePop+ run.
Args
format
:str
, optional- Return results as DataFrame ('DataFrame') or JSON string ('json'). Defaults to 'DataFrame'.
Raises
RuntimeError
- If there is no output because run_model has not yet been called.
Returns
pandas.DataFrame
orstr
- DataFrame or JSON string of the model results. JSON output is a dictionary of lists keyed by column name.
def get_parameters(self)
-
Expand source code
def get_parameters(self): """ Return all parameters that have been set by the user. Returns: dict: Dictionary of current BeePop+ parameters. """ return self.beepop.get_parameters()
Return all parameters that have been set by the user.
Returns
dict
- Dictionary of current BeePop+ parameters.
def load_parameter_file(self, parameter_file)
-
Expand source code
def load_parameter_file(self, parameter_file): """ Load a .txt file of parameter values to set. Each row of the file is a string with the format 'parameter=value'. Args: parameter_file (str): Path to a txt file of BeePop+ parameters. See https://doi.org/10.3390/ecologies3030022 or the documentation for valid parameters. Raises: FileNotFoundError: If the provided file does not exist at the specified path. ValueError: If a listed parameter is not a valid BeePop+ parameter. """ if not os.path.isfile(parameter_file): raise FileNotFoundError( "Paramter file does not exist at path: {}!".format(parameter_file) ) self.parameter_file = parameter_file self.beepop.load_input_file(self.parameter_file)
Load a .txt file of parameter values to set. Each row of the file is a string with the format 'parameter=value'.
Args
parameter_file
:str
- Path to a txt file of BeePop+ parameters. See https://doi.org/10.3390/ecologies3030022 or the documentation for valid parameters.
Raises
FileNotFoundError
- If the provided file does not exist at the specified path.
ValueError
- If a listed parameter is not a valid BeePop+ parameter.
def load_residue_file(self, residue_file)
-
Expand source code
def load_residue_file(self, residue_file): """ Load a .csv or comma-delimited .txt file of pesticide residues in pollen/nectar. Each row should specify Date (MM/DD/YYYY), Concentration in nectar (g A.I. / g), Concentration in pollen (g A.I. / g). Values can be in scientific notation (e.g., "9.00E-08"). Args: residue_file (str): Path to the residue .csv or .txt file. See docs/residue_file_readme.txt and manuscript for format details. Raises: FileNotFoundError: If the provided file does not exist at the specified path. """ if not os.path.isfile(residue_file): raise FileNotFoundError( "Residue file does not exist at path: {}!".format(residue_file) ) self.residue_file = residue_file self.beepop.load_contam_file(self.residue_file)
Load a .csv or comma-delimited .txt file of pesticide residues in pollen/nectar. Each row should specify Date (MM/DD/YYYY), Concentration in nectar (g A.I. / g), Concentration in pollen (g A.I. / g). Values can be in scientific notation (e.g., "9.00E-08").
Args
residue_file
:str
- Path to the residue .csv or .txt file. See docs/residue_file_readme.txt and manuscript for format details.
Raises
FileNotFoundError
- If the provided file does not exist at the specified path.
def load_weather(self, weather_file)
-
Expand source code
def load_weather(self, weather_file): """ Load a weather file. The file should be a .csv or comma-delimited .txt file where each row denotes: Date (MM/DD/YY), Max Temp (C), Min Temp (C), Avg Temp (C), Windspeed (m/s), Rainfall (mm), Hours of daylight (optional). Args: weather_file (str): Path to the weather file (csv or txt). See docs/weather_readme.txt and manuscript for format details. Raises: FileNotFoundError: If the provided file does not exist at the specified path. """ if not os.path.isfile(weather_file): raise FileNotFoundError( "Weather file does not exist at path: {}!".format(weather_file) ) self.weather_file = weather_file self.beepop.load_weather(self.weather_file)
Load a weather file. The file should be a .csv or comma-delimited .txt file where each row denotes: Date (MM/DD/YY), Max Temp (C), Min Temp (C), Avg Temp (C), Windspeed (m/s), Rainfall (mm), Hours of daylight (optional).
Args
weather_file
:str
- Path to the weather file (csv or txt). See docs/weather_readme.txt and manuscript for format details.
Raises
FileNotFoundError
- If the provided file does not exist at the specified path.
def plot_output(self,
columns=['Colony Size', 'Adult Workers', 'Capped Worker Brood', 'Worker Larvae', 'Worker Eggs'])-
Expand source code
def plot_output( self, columns=[ "Colony Size", "Adult Workers", "Capped Worker Brood", "Worker Larvae", "Worker Eggs", ], ): """ Plot the output as a time series. Args: columns (list, optional): List of column names to plot (as strings). Defaults to key colony metrics. Raises: RuntimeError: If there is no output because run_model has not yet been called. IndexError: If any column name is not a valid output column. Returns: matplotlib.axes.Axes: Matplotlib Axes object for further customization. """ if self.output is None: raise RuntimeError( "There are no results to plot. Please run the model first." ) invalid_cols = [col not in self.output.columns for col in columns] if any(invalid_cols): raise IndexError( "The column name {} is not a valid output column.".format( [i for (i, v) in zip(columns, invalid_cols) if v] ) ) plot = plot_timeseries(output=self.output, columns=columns) return plot
Plot the output as a time series.
Args
columns
:list
, optional- List of column names to plot (as strings). Defaults to key colony metrics.
Raises
RuntimeError
- If there is no output because run_model has not yet been called.
IndexError
- If any column name is not a valid output column.
Returns
matplotlib.axes.Axes
- Matplotlib Axes object for further customization.
def run_model(self)
-
Expand source code
def run_model(self): """ Run the BeePop+ model simulation. Raises: RuntimeError: If the weather file has not yet been set. Returns: pandas.DataFrame: DataFrame of daily time series results for the BeePop+ run, including colony size, adult workers, brood, eggs, and other metrics. """ # check to see if parameters have been supplied if (self.parameter_file is None) and (self.parameters is None): print("No parameters have been set. Running with defualt settings.") if self.weather_file is None: raise RuntimeError("Weather must be set before running BeePop+!") self.output = self.beepop.run_beepop() return self.output
Run the BeePop+ model simulation.
Raises
RuntimeError
- If the weather file has not yet been set.
Returns
pandas.DataFrame
- DataFrame of daily time series results for the BeePop+ run, including colony size, adult workers, brood, eggs, and other metrics.
def set_parameters(self, parameters)
-
Expand source code
def set_parameters(self, parameters): """ Set BeePop+ parameters based on a dictionary {parameter: value}. Args: parameters (dict): Dictionary of BeePop+ parameters {parameter: value}. See https://doi.org/10.3390/ecologies3030022 or the documentation for valid parameters. Raises: TypeError: If parameters is not a dict. ValueError: If a parameter is not a valid BeePop+ parameter. """ if (parameters is not None) and (not isinstance(parameters, dict)): raise TypeError( "parameters must be a named dictionary of BeePop+ parameters" ) self.parameters = self.beepop.set_parameters(parameters)
Set BeePop+ parameters based on a dictionary {parameter: value}.
Args
parameters
:dict
- Dictionary of BeePop+ parameters {parameter: value}. See https://doi.org/10.3390/ecologies3030022 or the documentation for valid parameters.
Raises
TypeError
- If parameters is not a dict.
ValueError
- If a parameter is not a valid BeePop+ parameter.
def version(self)
-
Expand source code
def version(self): """ Return the BeePop+ version as a string. Returns: str: BeePop+ version string. """ version = self.beepop.get_version() return version
Return the BeePop+ version as a string.
Returns
str
- BeePop+ version string.