docs: def run(self, params=None, return_columns=None, return_timestamps=None,
              initial_condition='original', reload=False):
          """ Simulate the model's behavior over time.
          Return a pandas dataframe with timestamps as rows,
          model elements as columns.
  
          Parameters
          ----------
          params : dictionary
              Keys are strings of model component names.
              Values are numeric or pandas Series.
              Numeric values represent constants over the model integration.
              Timeseries will be interpolated to give time-varying input.
  
          return_timestamps : list, numeric, numpy array(1-D)
              Timestamps in model execution at which to return state information.
              Defaults to model-file specified timesteps.
  
          return_columns : list of string model component names
              Returned dataframe will have corresponding columns.
              Defaults to model stock values.
  
          initial_condition : 'original'/'o', 'current'/'c', (t, {state})
              The starting time, and the state of the system (the values of all the stocks)
              at that starting time.
  
              * 'original' (default) uses model-file specified initial condition
              * 'current' uses the state of the model after the previous execution
              * (t, {state}) lets the user specify a starting time and (possibly partial)
                list of stock values.
  
          reload : bool
              If true, reloads the model from the translated model file before making changes
  
          Examples
          --------
  
          >>> model.run(params={'exogenous_constant': 42})
          >>> model.run(params={'exogenous_variable': timeseries_input})
          >>> model.run(return_timestamps=[1, 2, 3.1415, 4, 10])
          >>> model.run(return_timestamps=10)
          >>> model.run(return_timestamps=np.linspace(1, 10, 20))
  
          See Also
          --------
          pysd.set_components : handles setting model parameters
          pysd.set_initial_condition : handles setting initial conditions
  
          """
          if reload:
              self.reload()
  
          if params:
              self.set_components(params)
  
          self.set_initial_condition(initial_condition)
  
          return_timestamps = self._format_return_timestamps(return_timestamps)
  
          t_series = self._build_euler_timeseries(return_timestamps)
  
          if return_columns is None:
              return_columns = self._default_return_columns()
  
          self.time.stage = 'Run'
          self.clear_caches()
  
          capture_elements, return_addresses = utils.get_return_elements(
              return_columns, self.components._namespace, self.components._subscript_dict)
  
          res = self._integrate(t_series, capture_elements, return_timestamps)
  
          return_df = utils.make_flat_df(res, return_addresses)
          return_df.index = return_timestamps
  
          return return_df