Beispiel #1
0
/**
 * Initializer for OLSR
 */
void olsr_init(node_state *s, tw_lp *lp)
{
    hello *h;
    tw_event *e;
    olsr_msg_data *msg;
    tw_stime ts;
    
    //s->num_tuples = 0;
    s->num_neigh  = 0;
    s->num_two_hop = 0;
    s->local_address = lp->gid;
    s->lng = tw_rand_unif(lp->rng) * GRID_MAX;
    s->lat = tw_rand_unif(lp->rng) * GRID_MAX;
    
    ts = tw_rand_unif(lp->rng) * STAGGER_MAX;
    
    e = tw_event_new(lp->gid, ts, lp);
    msg = tw_event_data(e);
    msg->type = HELLO_TX;
    msg->originator = s->local_address;
    msg->lng = s->lng;
    msg->lat = s->lat;
    h = &msg->mt.h;
    h->num_neighbors = 0;
    //h->neighbor_addrs[0] = s->local_address;
    tw_event_send(e);
}
static void svr_init(
    svr_state * ns,
    tw_lp * lp)
{
    tw_event *e;
    svr_msg *m;
    tw_stime kickoff_time;
    
    memset(ns, 0, sizeof(*ns));

    /* each server sends a dummy event to itself that will kick off the real
     * simulation
     */


    //printf("\n Initializing servers %d ", (int)lp->gid);
    /* skew each kickoff event slightly to help avoid event ties later on */
    kickoff_time = g_tw_lookahead + tw_rand_unif(lp->rng); 

    e = codes_event_new(lp->gid, kickoff_time, lp);
    m = tw_event_data(e);
    m->svr_event_type = KICKOFF;
    tw_event_send(e);

    return;
}
Beispiel #3
0
void
mem_event_handler(mem_state * s, tw_bf * bf, mem_message * m, tw_lp * lp)
{
    tw_lpid		 dest;
    tw_event	*e;
    tw_memory	*b;

    int		 i;

    s->stats.s_recv++;

    // read membufs off inbound event, check it and free it
    for(i = 0; i < nbufs; i++)
    {
        b = tw_event_memory_get(lp);

        if(!b)
            tw_error(TW_LOC, "Missing memory buffers: %d of %d",
                     i+1, nbufs);

        mem_verify(b);
        tw_memory_free(lp, b, my_fd);

        s->stats.s_mem_free++;
        s->stats.s_mem_get++;
    }

    if(tw_rand_unif(lp->rng) <= percent_remote)
    {
        bf->c1 = 1;
        dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1);

        dest += offset_lpid;

        if(dest >= ttl_lps)
            dest -= ttl_lps;
    } else
    {
        bf->c1 = 0;
        dest = lp->gid;
    }

    e = tw_event_new(dest, tw_rand_exponential(lp->rng, mean), lp);

    // allocate membufs and attach them to the event
    for(i = 0; i < nbufs; i++)
    {
        b = mem_alloc(lp);

        if(!b)
            tw_error(TW_LOC, "no membuf allocated!");

        mem_fill(b);
        tw_event_memory_set(e, b, my_fd);
        s->stats.s_mem_alloc++;
    }

    tw_event_send(e);
}
Beispiel #4
0
void
tmr_event_handler(tmr_state * s, tw_bf * bf, tmr_message * m, tw_lp * lp)
{
	tw_lpid	 dest;

	* (int *) bf = 0;

	if(s->timer)
	{
		// if current event being processed is the timer
		if(tw_event_data(s->timer) == m)
		{
			bf->c1 = 1;

			m->old_timer = s->timer;
			s->timer = NULL;

			fprintf(f, "%lld: tmr fired at %lf\n", 
				lp->gid, tw_now(lp));

			return;
		} else
		{
			bf->c2 = 1;

			m->old_time = s->timer->recv_ts;
			tw_timer_reset(lp, &s->timer, tw_now(lp) + 100.0);

			if(s->timer == NULL)
				fprintf(f, "%lld: reset tmr failed %lf\n", 
					lp->gid, tw_now(lp) + 100.0);
			else
				fprintf(f, "%lld: reset tmr to %lf\n", 
					lp->gid, tw_now(lp) + 100.0);
		}
	}

	if(tw_rand_unif(lp->rng) <= percent_remote)
	{
		bf->c3 = 1;
		dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1);

		dest += offset_lpid;

		if(dest >= ttl_lps)
			dest -= ttl_lps;
	} else
	{
		bf->c3 = 0;
		dest = lp->gid;
	}

	if(!lp->gid)
		dest = 0;

	tw_event_send(tw_event_new(dest, tw_rand_exponential(lp->rng, mean), lp));
}
//Forward event handler
void model_event (state *s, tw_bf *bf, message *in_msg, tw_lp *lp) {
  int self = lp->gid;

  // initialize the bit field
  *(int *) bf = (int) 0;

  // update the current state
  // however, save the old value in the 'reverse' message
  SWAP(&(s->value), &(in_msg->contents));

  // handle the message
  switch (in_msg->type) {
    case HELLO :
    {
      s->rcvd_count_H++;
      break;
    }
    case GOODBYE :
    {
      s->rcvd_count_G++;
      break;
    }
    default :
      printf("Unhandeled forward message type %d\n", in_msg->type);
  }

  tw_event *e = tw_event_new(self, 1, lp);
  message *msg = tw_event_data(e);
  //# randomly choose message type
  double random = tw_rand_unif(lp->rng);
  if (random < 0.5) {
    msg->type = HELLO;
  } else {
    msg->type = GOODBYE;
  }
  msg->contents = tw_rand_unif(lp->rng);
  msg->sender = self;
  tw_event_send(e);
}
//Init function
// - called once for each LP
// ! LP can only send messages to itself during init !
void model_init (state *s, tw_lp *lp) {
  int self = lp->gid;

  // init state data
  s->rcvd_count_H = 0;
  s->rcvd_count_G = 0;
  s->value = -1;

  // Init message to myself
  tw_event *e = tw_event_new(self, 1, lp);
  message *msg = tw_event_data(e);
  msg->type = HELLO;
  msg->contents = tw_rand_unif(lp->rng);
  msg->sender = self;
  tw_event_send(e);
}
Beispiel #7
0
static void node_init(node_state *ns, tw_lp *lp) {

  tw_event *e;
  node_msg *m;
  tw_stime init_time;

  memset(ns, 0, sizeof(*ns));

  init_time = g_tw_lookahead + tw_rand_unif(lp->rng);
  e = codes_event_new(lp->gid, init_time, lp);

  m = tw_event_data(e);
  m->node_event_type = INIT;
  tw_event_send(e);

  return;
}
Beispiel #8
0
void
phold_pre_run(phold_state * s, tw_lp * lp)
{
    tw_lpid	 dest;

	if(tw_rand_unif(lp->rng) <= percent_remote)
	{
		dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1);
	} else
	{
		dest = lp->gid;
	}

	if(dest >= (g_tw_nlp * tw_nnodes()))
		tw_error(TW_LOC, "bad dest");

	tw_event_send(tw_event_new(dest, tw_rand_exponential(lp->rng, mean) + lookahead, lp));
}
static void svr_init(
    svr_state * ns,
    tw_lp * lp)
{
    tw_event *e;
    svr_msg *m;
    tw_stime kickoff_time;
    
    memset(ns, 0, sizeof(*ns));

    /* each server sends a dummy event to itself */

    /* skew each kickoff event slightly to help avoid event ties later on */
    kickoff_time = g_tw_lookahead + tw_rand_unif(lp->rng); 

    e = codes_event_new(lp->gid, kickoff_time, lp);
    m = tw_event_data(e);
    m->event_type = KICKOFF;
    tw_event_send(e);

    return;
}
static void svr_init(
    svr_state * ns,
    tw_lp * lp)
{
    tw_event *e;
    svr_msg *m;
    tw_stime kickoff_time;

    memset(ns, 0, sizeof(*ns));

    /* each server sends a dummy event to itself that will kick off the real
     * simulation
     */

    /* skew each kickoff event slightly to help avoid event ties later on */
    kickoff_time = g_tw_lookahead + tw_rand_unif(lp->rng);

    e = tw_event_new(lp->gid, kickoff_time, lp);
    m = tw_event_data(e);
    msg_set_header(magic, KICKOFF, lp->gid, &m->h);
    tw_event_send(e);

    return;
}
Beispiel #11
0
void
phold_event_handler(phold_state * s, tw_bf * bf, phold_message * m, tw_lp * lp)
{
	tw_lpid	 dest;

	if(tw_rand_unif(lp->rng) <= percent_remote)
	{
		bf->c1 = 1;
		dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1);
		// Makes PHOLD non-deterministic across processors! Don't uncomment
		/* dest += offset_lpid; */
		/* if(dest >= ttl_lps) */
		/* 	dest -= ttl_lps; */
	} else
	{
		bf->c1 = 0;
		dest = lp->gid;
	}

	if(dest >= (g_tw_nlp * tw_nnodes()))
		tw_error(TW_LOC, "bad dest");

	tw_event_send(tw_event_new(dest, tw_rand_exponential(lp->rng, mean) + lookahead, lp));
}
Beispiel #12
0
void
phold_event_handler(phold_state * s, tw_bf * bf, phold_message * m, tw_lp * lp)
{
	tw_lpid	 dest;

	if(tw_rand_unif(lp->rng) <= percent_remote)
	{
		bf->c1 = 1;
		dest = tw_rand_integer(lp->rng, 0, ttl_lps - 1);

		dest += offset_lpid;

		if(dest >= ttl_lps)
			dest -= ttl_lps;
	} else
	{
		bf->c1 = 0;
		dest = lp->gid;
	}

	rn_event_send(
		rn_event_new(dest, tw_rand_exponential(lp->rng, mean), 
				lp, DOWNSTREAM, 0));
}
Beispiel #13
0
void
epi_xml(epi_state * state, tw_lp * lp)
{
	xmlNodePtr	 agent;
	xmlNodePtr	 move;
	rn_machine	*m = rn_getmachine(lp->id);

	epi_agent	*a;
	epi_ic_stage	*s;

	double		 x;

	int		 ct;
	int		 i;

	char		*sick;

	// create census tract table if it does not exist
	// need 1 more than number of stages to save dead agents
	// dead is not a stage.
	if (!g_epi_ct)
	{
		g_epi_nct = 2200; //rn_getarea(m)->nsubnets;
		g_epi_ct = tw_vector_create(sizeof(unsigned int *), g_epi_nct);

		for (i = 0; i < g_epi_nct; i++)
			g_epi_ct[i] = tw_vector_create(sizeof(unsigned int), g_epi_nstages);
	}

	state->stats = tw_vector_create(sizeof(epi_statistics), 1);
	state->pq = pq_create();

	ct = rn_getsubnet(m)->id - rn_getarea(m)->subnets[0].id;

	// spin through agents 'homed' at this location and allocate + init them
	//
	// NOTE: May not have *any* agents homed at a given location
	for(agent = node->children; agent; agent = agent->next)
	{
		if(0 != strcmp((char *) agent->name, "agent"))
			continue;

		a = tw_vector_create(sizeof(epi_agent), 1);

		a->ct = m->uid; //ct;
		a->num = tw_getlp(atoi(xml_getprop(agent, "num")));
		//a->a_type = atoi(xml_getprop(agent,"type"));

		sick = xml_getprop(agent, "sick");
		if(g_epi_psick > EPSILON)
		{
			if ( tw_rand_unif(lp->rng) < g_epi_psick )
				sick = "1";
		}

		if(0 != strcmp(sick, "0"))
		{
			//a->ts_infected = atof(sick);
			a->stage = EPI_INCUBATING;

			s = &g_epi_stages[a->stage];

			x = ((double) tw_rand_integer(lp->rng, 0, INT_MAX) / (double) INT_MAX);
		
			a->ts_stage_tran = (s->min_duration + 
						(x * (s->max_duration - s->min_duration)));

#if EPI_XML_VERIFY
			printf("\tstage: %d, time %5f \n",
				s->stage_index, a->ts_stage_tran);
#endif

			g_epi_nsick++;
		} else
		{
			a->stage = EPI_SUSCEPTIBLE;
			a->ts_stage_tran = DBL_MAX;
			//a->ts_infected = DBL_MAX;
		}

		g_epi_ct[a->ct][a->stage]++;

		//a->id = g_epi_nagents++;
		g_epi_nagents++;
		a->curr = 0;
		//a->ts_last_tran = 0.0;
		a->ts_next = a->ts_remove = (double) 86400.0;
		//a->n_infected = 0;

		for(move = agent->children; move; move = move->next)
		{
			if(0 != strcmp((char *) move->name, "move"))
				continue;

			a->nloc++;
		}

		if(!a->nloc)
			tw_error(TW_LOC, "Agent has no locations!");

		a->nloc++; // add a location to return home at end of day

		a->loc = tw_vector_create(sizeof(int) * a->nloc, 1);
		a->dur = tw_vector_create(sizeof(tw_stime) * a->nloc, 1);

		int seconds_used = 0; // totals duration to check for 24 hours

		for(i = 0, move = agent->children; move; move = move->next)
		{
			if(0 != strcmp((char *) move->name, "move"))
				continue;

			a->loc[i] = atoi(xml_getprop(move, "loc"));
			a->dur[i] = atoi(xml_getprop(move, "dur")) * 3600;
			seconds_used += a->dur[i];
			i++;
		}

		if (seconds_used > 86400)
			tw_error(TW_LOC, "Agent has duration more than 24 hours\n");

		else if (seconds_used == 86400)
			a->nloc--; // do not need last location
		else {
			a->loc[a->nloc-1] = a->loc[0]; // return home
			a->dur[a->nloc-1] = 86400 - seconds_used;
		}

		a->behavior_flags = 0;
		if (g_epi_worried_well_rate > 0)
		{
			if (tw_rand_unif(lp->rng) < g_epi_worried_well_rate)
				a->behavior_flags = 1;
		} else if (g_epi_work_while_sick_p > EPSILON)
			if (tw_rand_unif(lp->rng) < g_epi_work_while_sick_p)
				a->behavior_flags = 2;

		// Set ts_next and enqueue
		a->ts_remove = a->dur[a->curr];
		if(a->ts_remove < a->ts_stage_tran)
			a->ts_next = a->ts_remove;
		else
			a->ts_next = a->ts_stage_tran;

		pq_enqueue(state->pq, a);
	}
}
Beispiel #14
0
/**
 * Initializer function for SRW.  Here we set all the necessary
 * initial values we assume for the beginning of the simulation.
 * We also bootstrap the event queue with some random data.
 */
void srw_init(srw_state *s, tw_lp *lp)
{
  int i;
  int num_radios;
  tw_event *e;
  /* global_id is required to make sure all nodes get unique IDs */
  static long global_id = 0;
  /* current_id is just the starting ID for this particular iteration */
  long current_id = global_id;

  /* Initialize the state of this LP (or master) */
  num_radios    = tw_rand_integer(lp->rng, 1, SRW_MAX_GROUP_SIZE);
  s->num_radios = num_radios;
  s->movements  = 0;
  s->comm_fail  = 0;
  s->comm_try   = 0;

  /* Initialize nodes */
  for (i = 0; i < num_radios; i++) {
    (s->nodes[i]).node_id   = global_id++;
    (s->nodes[i]).lng       = 0.0;
    (s->nodes[i]).lat       = 0.0;
    (s->nodes[i]).movements =   0;
    (s->nodes[i]).comm_fail =   0;
    (s->nodes[i]).comm_try  =   0;
  }

  /* Priming events */
  for (i = 0; i < num_radios; i++) {
    tw_stime ts;
    srw_msg_data *msg;

    // GPS event first, as it's the simplest
    ts = tw_rand_unif(lp->rng);
    ts = ts * SRW_GPS_RATE;

    e = tw_event_new(lp->gid, ts, lp);
    msg = tw_event_data(e);
    msg->node_id = current_id + i;
    msg->type = GPS;
    tw_event_send(e);

    // Now schedule some movements
    ts = tw_rand_exponential(lp->rng, SRW_MOVE_MEAN);
    e = tw_event_new(lp->gid, ts, lp);
    msg = tw_event_data(e);
    msg->node_id = current_id + i;
    msg->type = MOVEMENT;
    // We have to figure out a good way to set the initial lat/long
    tw_event_send(e);

    // Now some communications
    ts = tw_rand_exponential(lp->rng, SRW_COMM_MEAN);
    e = tw_event_new(lp->gid, ts, lp);
    msg = tw_event_data(e);
    msg->node_id = current_id + i;
    msg->type = COMMUNICATION;
    // Something should probably go here as well...
    tw_event_send(e);
  }
}
Beispiel #15
0
/*
 * Stage transition causes the agent to be removed from the
 * queue (it is at the head), increment the stage, collect
 * statistics, and place back in the queue with the minimum
 * of the next stage transition time and the remove time.
 */
void
agent_stage_tran(epi_state * state, tw_bf * bf, tw_memory * buf, epi_pathogen * p, tw_lp * lp)
{
	epi_ic_stage	*s;
	epi_agent	*a;

	a = tw_memory_data(buf);
	s = &g_epi_diseases[p->index].stages[p->stage];

	if(5 == a->id || 1)
		printf("%lld: transition %d at %lf \n", lp->gid, a->id && 0, tw_now(lp));

	// if this agent is contagious in the old stage, then reduce the location number of
	// contagious agents by one.
	if(s->ln_multiplier != 0.0)
	{
		state->ncontagious[p->index]--;
		state->ncontagious_tot--;

		if(a->behavior_flags == EPI_AGENT_WORRIED_WELL)
			a->behavior_flags = 0;
	}

	if(state->ncontagious[p->index] < 0)
		tw_error(TW_LOC, "Less than zero ncontagious!");

	g_epi_regions[a->region][p->index][p->stage]--;
	p->stage++;
	g_epi_regions[a->region][p->index][p->stage]++;

	if(p->stage >= g_epi_diseases[p->index].nstages)
		tw_error(TW_LOC, "Invalid stage: %d", p->stage);

	s = &g_epi_diseases[p->index].stages[p->stage];
	p->ts_stage_tran = tw_now(lp);

	if(fabs(s->max_duration - s->min_duration) < EPSILON)
		p->ts_stage_tran += s->min_duration;
	else
		p->ts_stage_tran += s->min_duration + 
				tw_rand_unif(lp->rng) * (s->max_duration - s->min_duration);

	if(p->ts_stage_tran > tw_now(lp) + s->max_duration)
		tw_error(TW_LOC, "Too long!");

	if(p->ts_stage_tran < tw_now(lp))
		tw_error(TW_LOC, "Backwards stage tran!");

	if(p->ts_stage_tran < s->min_duration)
		tw_error(TW_LOC, "Too short!");

	// Perform mortality check
	if (s->mortality_rate > 0 && tw_rand_unif(lp->rng) < s->mortality_rate )
	{
		a->behavior_flags = EPI_AGENT_DEAD;
		a->days_remaining = 0;
		g_epi_regions[a->region][p->index][p->stage]--;
		p->stage = g_epi_diseases[p->index].nstages;
		g_epi_regions[a->region][p->index][p->stage]++;

		// collect statistics
		state->stats->s_ndead++;
	} else
	{
		// if new stage has infectivity, 
		// then increment number of contagious agents in location.
		if(s->ln_multiplier != 0.0)
		{
			state->ncontagious[p->index]++;
			state->ncontagious_tot++;
			state->stats->s_ninfected++;

			// then must set number of days to stay home
			if(!(a->behavior_flags & EPI_AGENT_WORK_WHILE_SICK))
			{
				a->days_remaining = ((int) (p->ts_stage_tran - tw_now(lp)) / TWENTY_FOUR_HOURS);

				if (a->days_remaining < 1)
					a->days_remaining = 1;

				g_epi_hospital[state->hospital][0]++;
			}
		}

		epi_agent_update_ts(state, bf, a, lp);

		// re-enqueue with new ts_next
		pq_enqueue(g_epi_pq[lp->id], buf);
	}
}
Beispiel #16
0
/*
 * epi_seir_compute: compute SEIR model for all agents in location LPn
 *
 * Assume that the probability of catching the disease is constant over time.
 * If the probability of catching the disease in one hour is P, then the
 * geometric distribution gives the number of hours before the disease is
 * caught.  We do a draw on the random number generator from the geometric
 * distribution and if the result is less than the time interval, then the
 * agent gets sick at that time.
 */
void
epi_seir_compute(epi_state * state, tw_bf * bf, epi_agent * in_a, tw_lp * lp)
{
	/*
	 * For each susceptible agent, for each contagious agent, determine
	 * the susceptible agent caught the disease.
	 */

	double		 draw,
			 delta_t;
	epi_agent	*a, *ai;
	epi_ic_stage	*s, *sn;
	unsigned int	 queue_size;
	unsigned int	 i, j;

	void		*pq;

	queue_size = pq_get_size(state->pq);
	if (queue_size <= 1)
		return;

	delta_t = tw_now(lp) - state->last_event;

	//printf(" lp %2d SEIR delta_t %f at %f\n", (int) lp->id, delta_t, tw_now(lp));

	if (delta_t < EPSILON) // already done an seir check at this time.
		return;

	//printf("SEIR Check %f\n", tw_now(lp));

	pq = state->pq;

	//printf( "Queue size: %d  ", queue_size);

	for ( i = 0; i < queue_size; i++)
	{
		a = (epi_agent *) pq_next( pq, i);
		//printf("\ta: %d, stage: %d\n ", a->id, a->stage);
		if (a->stage == EPI_SUSCEPTIBLE)
		{
			for (j = 0; j < queue_size; j++)
			{
				if ( j == i ) continue;
				ai = (epi_agent *) pq_next(pq, j);
				s = &g_epi_stages[ai->stage];
				//printf("a: %d, ai: %d, ln_multiplier: %f\n", a->id, ai->id, s->ln_multiplier);
				if (abs(s->ln_multiplier) > EPSILON)
				{
					// tw_geometric draws from uniform until the draw is greater than P.
					// tw_geometric then returns the number of draws.
					// For large P (which is 1.0 - multiplier) this could be very large.
					// Also note that tw_geometric always returns an integer of 1 or
					// greater.
					draw = tw_rand_unif(lp->id);

					draw = log(draw);
					draw /= g_epi_stages[a->stage].ln_multiplier;

					//draw = tw_rand_geometric(lp->id, (s->start_multiplier + s->stop_multiplier)/2);
					//state->stats->s_ndraws += draw;
					state->stats->s_nchecked++;
					//printf("SEIR agent %d, stage %d, agent %d, stage %d, draw: %g\n",
					//	a->id, a->stage, ai->id, ai->stage, draw);
					if (draw <= delta_t) //Make agent sick
					{
#if EPI_DEBUG
						printf("%7.3f, lp, %7d, agent_infect, , , , %7d, %5.3f, %5.2f\n",
							tw_now(lp), (int) lp->id, a->id, delta_t, draw);
#endif
						a->stage = EPI_INCUBATING;
						g_epi_ct[a->ct][0]--;
						g_epi_ct[a->ct][1]++;
						if (g_epi_position_f)
							fprintf(g_epi_position_f, "%.3f,%d,%d,%d\n", tw_now(lp), a->id, (int) lp->id, a->stage);

						sn = &g_epi_stages[a->stage];
						a->ts_infected = tw_now(lp);
						a->ts_stage_tran = tw_rand_unif(lp->id)*(sn->max_duration - sn->min_duration)
								+ sn->min_duration + tw_now(lp);
						a->ts_last_tran = tw_now(lp);
						// collect statistics
						state->stats->s_ninfected++;
						break;
					}
#if EPI_DEBUG
					else
					{
						printf("%7.3f, lp, %7d, agent_not_infect, , , , %7d, %5.3f, %5.2f\n",
							tw_now(lp), (int) lp->id, a->id, delta_t, draw);
					}
#endif
				}
			}
		}
	}	
 
	//printf("SEIR compputed at %f ", state->last_event);
}
Beispiel #17
0
/*
 * epi_init - initialize node LPs state variables
 * 
 * state	- our node LP state space
 * lp		- our node LP
 */
void
epi_init(epi_state * state, tw_lp * lp)
{
	tw_memory	*b;
	tw_memory	*agent = NULL;
	tw_stime	 ts_min_tran = DBL_MAX;

	epi_agent	*a;
	epi_pathogen	*p;
	epi_ic_stage	*s;

	double		 x;

	int		 i;
	int		 j;
	int		 sz;

	// hard-coded, single hospital LP
	if(lp->id == g_tw_nlp-1)
	{
		fprintf(g_epi_hospital_f, "0 0 %u %u %u\n", 
			g_epi_hospital[0][0], g_epi_hospital_ww[0][0], 
			g_epi_hospital_wws[0][0]);

		g_epi_hospital[0][0] = 0;
		g_epi_hospital_ww[0][0] = 0;
		g_epi_hospital_wws[0][0] = 0;

		return;
	}

	// ID of the hospital I go to (or nearest if office/school)
	state->hospital = 0;
	state->stats = tw_calloc(TW_LOC, "", sizeof(epi_statistics), 1);
	state->ncontagious = tw_calloc(TW_LOC, "", sizeof(unsigned int), g_epi_ndiseases);
	state->ts_seir = tw_calloc(TW_LOC, "", sizeof(tw_stime), g_epi_ndiseases);

	for(i = 0; i < g_epi_ndiseases; i++)
		state->ts_seir[i] = DBL_MAX;

	// if no agents initially at this location, then we are done!
	if(0 == (sz = pq_get_size(g_epi_pq[lp->id])))
		return;

	// determine agents initial parameters / configuration
	for(i = 0; i < sz; i++)
	{
		agent = pq_next(g_epi_pq[lp->id], i);
		a = tw_memory_data(agent);

		for(j = 0; j < g_epi_ndiseases; j++)
		{
			if(!a->id && !j)
			{
				// ALLOCATE PATHOGEN AND FILL IT IN
				b = tw_memory_alloc(lp, g_epi_pathogen_fd);
				p = tw_memory_data(b);

				b->next = a->pathogens;
				a->pathogens = b;

				p->index = j;
				p->stage = EPI_SUSCEPTIBLE;
				p->ts_stage_tran = DBL_MAX;

				g_epi_regions[a->region][p->index][p->stage]--;
				p->stage = EPI_EXPOSED;
				g_epi_regions[a->region][p->index][p->stage]++;
				g_epi_exposed_today[j]++;
	
				// determine if agents start out sick.
				if(tw_rand_unif(lp->rng) < g_epi_sick_rate)
				{

				s = &g_epi_diseases[p->index].stages[p->stage];

				x = ((double) tw_rand_integer(lp->rng, 0, INT_MAX) / 
						(double) INT_MAX);

				p->ts_stage_tran = (s->min_duration + 
						(x * (s->max_duration - s->min_duration)));

				if(0.0 >= p->ts_stage_tran)
					tw_error(TW_LOC, "Immediate stage transition?!");

				//state->stats->s_ninfected++;
				state->ncontagious[p->index]++;
				state->ncontagious_tot++;
				//g_epi_hospital[0][0]++;
				g_epi_sick_init_pop[j]++;

				ts_min_tran = min(ts_min_tran, p->ts_stage_tran);

				if(!a->id)
					printf("%ld: agent exposed %d: %s, transition at %lf\n", 
					lp->id, a->id, g_epi_diseases[j].name, 
					p->ts_stage_tran);
				}
			}
		}

		// reflect ts_next change in PQ ordering
		if(ts_min_tran < a->ts_next)
		{
			a->ts_next = ts_min_tran;
			pq_delete_any(g_epi_pq[lp->id], &agent);
			pq_enqueue(g_epi_pq[lp->id], agent);
		}

		// determine if agents are a part of worried well population.
		if(g_epi_ww_rate)
		{
			if(tw_rand_unif(lp->rng) < g_epi_ww_rate)
			{
				a->behavior_flags = 1;
				g_epi_hospital_ww[0][0]++;
				g_epi_ww_init_pop++;
			}
		} else if(g_epi_wws_rate)
		{
			if(tw_rand_unif(lp->rng) < g_epi_wws_rate)
			{
				a->behavior_flags = 2;
				g_epi_hospital_wws[0][0]++;
				g_epi_wws_init_pop++;
			}
		}

		// define agent's at work contact population
		//g_epi_regions[a->region][a->stage]++;
	}

	epi_location_timer(state, lp);
}