m->fprintf = local_fprintf;
  m->free = local_free;

  /* Make sure the right XML subtree was sent. */
  g_assert (strcmp (scew_element_name (params), MODEL_NAME) == 0);

#if DEBUG
  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "setting production types");
#endif
  local_data->production_types = herds->production_type_names;
  local_data->production_type =
    naadsm_read_prodtype_attribute (params, "production-type", herds->production_type_names);

  e = scew_element_by_name (params, "latent-period");
  g_assert (e != NULL);
  local_data->latent_period = PAR_get_PDF (e);

  e = scew_element_by_name (params, "infectious-subclinical-period");
  g_assert (e != NULL);
  local_data->infectious_subclinical_period = PAR_get_PDF (e);

  e = scew_element_by_name (params, "infectious-clinical-period");
  g_assert (e != NULL);
  local_data->infectious_clinical_period = PAR_get_PDF (e);

  e = scew_element_by_name (params, "immunity-period");
  g_assert (e != NULL);
  local_data->immunity_period = PAR_get_PDF (e);

  e = scew_element_by_name (params, "prevalence");
  if (e != NULL)
/**
 * Adds a set of parameters to an airborne spread model.
 */
void
set_params (struct ergadm_model_t_ *self, scew_element * params)
{
  local_data_t *local_data;
  gboolean *from_production_type, *to_production_type;
  unsigned int nprod_types, i, j;
  param_block_t *param_block;
  scew_element const *e;
  gboolean success;
  gboolean use_rtree;

#if DEBUG
  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "----- ENTER set_params (%s)", MODEL_NAME);
#endif

  /* Make sure the right XML subtree was sent. */
  g_assert (strcmp (scew_element_name (params), MODEL_NAME) == 0);

  local_data = (local_data_t *) (self->model_data);

  /* Find out which to-from production type combinations these parameters apply
   * to. */
  from_production_type =
    ergadm_read_prodtype_attribute (params, "from-production-type", local_data->production_types);
  to_production_type =
    ergadm_read_prodtype_attribute (params, "to-production-type", local_data->production_types);

  nprod_types = local_data->production_types->len;
  for (i = 0; i < nprod_types; i++)
    if (from_production_type[i] == TRUE)
      for (j = 0; j < nprod_types; j++)
        if (to_production_type[j] == TRUE)
          {
            /* If necessary, create a row in the 2D array for this from-
             * production type. */
            if (local_data->param_block[i] == NULL)
              local_data->param_block[i] = g_new0 (param_block_t *, nprod_types);

            /* Create a parameter block for this to-from production type
             * combination, or overwrite the existing one. */
            param_block = local_data->param_block[i][j];
            if (param_block == NULL)
              {
                param_block = g_new (param_block_t, 1);
                local_data->param_block[i][j] = param_block;
#if DEBUG
                g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
                       "setting parameters for %s -> %s",
                       (char *) g_ptr_array_index (local_data->production_types, i),
                       (char *) g_ptr_array_index (local_data->production_types, j));
#endif
              }
            else
              {
                g_warning ("overwriting previous parameters for %s -> %s",
                           (char *) g_ptr_array_index (local_data->production_types, i),
                           (char *) g_ptr_array_index (local_data->production_types, j));
              }

            e = scew_element_by_name (params, "prob-spread-1km");
            param_block->prob_spread_1km = PAR_get_probability (e, &success);
            if (success == FALSE)
              {
                g_warning ("setting probability of spread at 1 km to 0");
                param_block->prob_spread_1km = 0;
              }

            e = scew_element_by_name (params, "wind-direction-start");
            param_block->wind_dir_start = PAR_get_angle (e, &success);
            if (success == FALSE)
              {
                g_warning ("setting start of wind direction range to 0");
                param_block->wind_dir_start = 0;
              }
            /* Force the angle into the range [0,360). */
            while (param_block->wind_dir_start < 0)
              param_block->wind_dir_start += 360;
            while (param_block->wind_dir_start >= 360)
              param_block->wind_dir_start -= 360;

            e = scew_element_by_name (params, "wind-direction-end");
            param_block->wind_dir_end = PAR_get_angle (e, &success);
            if (success == FALSE)
              {
                g_warning ("setting end of wind direction range to 360");
                param_block->wind_dir_end = 360;
              }
            /* Force the angle into the range [0,360]. */
            while (param_block->wind_dir_end < 0)
              param_block->wind_dir_end += 360;
            while (param_block->wind_dir_end > 360)
              param_block->wind_dir_end -= 360;

            /* Note that start > end is allowed.  See the header comment. */
            param_block->wind_range_crosses_0 =
              (param_block->wind_dir_start > param_block->wind_dir_end);

            /* Setting both start and end to 0 seems like a sensible way to
             * turn off airborne spread, but headings close to north will
             * "sneak through" this restriction because we allow a little
             * wiggle room for rounding errors.  If the user tries this,
             * instead set prob-spread-1km=0. */
            if (param_block->wind_dir_start == 0 && param_block->wind_dir_end == 0)
              param_block->prob_spread_1km = 0;

            e = scew_element_by_name (params, "max-spread");
            param_block->max_spread = PAR_get_length (e, &success);
            if (success == FALSE)
              {
                g_warning ("setting maximum distance of spread to 0");
                param_block->max_spread = 0;
              }
            /* The maximum spread distance cannot be negative. */
            if (param_block->max_spread < 0)
              {
                g_warning ("maximum distance of spread cannot be negative, setting to 0");
                param_block->max_spread = 0;
              }
            /* Setting the maximum spread distance to 0 seems like a sensible
             * way to turn off airborne spread, but max-spread <= 1 doesn't
             * make sense in the formula.  If the user tries this, instead set
             * max-spread=2, prob-spread-1km=0. */
            if (param_block->max_spread <= 1)
              {
                param_block->max_spread = 2;
                param_block->prob_spread_1km = 0;
              }

            e = scew_element_by_name (params, "delay");
            if (e != NULL)
              {
                param_block->delay = PAR_get_PDF (e);
              }
            else
              param_block->delay = PDF_new_point_dist (0);

            /* Keep track of the maximum distance of spread from each
             * production type.  This determines whether we will use the R-tree
             * index when looking for herds to spread infection to. */
            if (param_block->max_spread > local_data->max_spread[i])
              {
                local_data->max_spread[i] = param_block->max_spread;

                /* Use the following heuristic to decide whether to use the
                 * R-tree index in searches: if the ratio of the diameter of
                 * circle of maximum spread to the short axis of the oriented
                 * bounding rectangle around the herds is <= 0.25, use the
                 * R-tree. */
                if (local_data->short_axis_length > 0)
                  {
                    use_rtree = (param_block->max_spread * 2 / local_data->short_axis_length) <= 0.25;
                  }
                else
                  {
                    use_rtree = FALSE;
                  }

#if defined(USE_RTREE) && USE_RTREE == 0
                /* For debugging purposes, you can #define USE_RTREE to 0 to never
                 * use the spatial index, or 1 to always use it. */
                use_rtree = FALSE;
#endif
                local_data->use_rtree_index[i] = use_rtree;
              }

          }

  g_free (from_production_type);
  g_free (to_production_type);

#if DEBUG
  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "----- EXIT set_params (%s)", MODEL_NAME);
#endif

  return;
}