synthpops.people.people module

Alternate representation of a population as a People object. Originally based on the corresponding Covasim classes and functions.

class FlexPretty[source]

Bases: sciris.sc_utils.prettyobj

A class that supports multiple different display options: namely obj.brief() for a one-line description and obj.disp() for a full description.

New in version 1.10.0.

disp(output=False)[source]

Print or output verbose representation of the object

brief(output=False)[source]

Print or output a brief representation of the object

class BasePeople[source]

Bases: synthpops.people.people.FlexPretty

A class to handle all the boilerplate for people – note that as with the BaseSim vs Sim classes, everything interesting happens in the People class, whereas this class exists to handle the less interesting implementation details.

New in version 1.10.0.

keys()[source]

Get the keys that have been set

lock()[source]

Lock the people object to prevent keys from being added

unlock()[source]

Unlock the people object to allow keys to be added

summarize(output=False)[source]

Print a summary of the people – same as brief

set(key, value, die=True)[source]

Ensure sizes and dtypes match

get(key)[source]

Convenience method – key can be string or list of strings

true(key)[source]

Return indices matching the condition

false(key)[source]

Return indices not matching the condition

defined(key)[source]

Return indices of people who are not-nan

undefined(key)[source]

Return indices of people who are nan

count(key)[source]

Count the number of people for a given key

count_not(key)[source]

Count the number of people who do not have a property for a given key

set_pars(pars=None)[source]

Re-link the parameters stored in the people object to the sim containing it, and perform some basic validation.

layer_keys()[source]

Get the available contact keys – try contacts first, then beta_layer

indices()[source]

The indices of each people array

validate(die=True, verbose=False)[source]
to_df()[source]

Convert to a Pandas dataframe

to_arr()[source]

Return as numpy array

person(ind)[source]

Method to create person from the people

to_people()[source]

Return all people as a list

from_people(people, resize=True)[source]

Convert a list of people back into a People object

to_graph(full_output=False)[source]

Convert all people to a networkx MultiDiGraph, including all properties of the people (nodes) and contacts (edges).

Parameters:full_output (bool) – if true, return nodes and edges along with the graph object
init_contacts(reset=False)[source]

Initialize the contacts dataframe with the correct columns and data types

add_contacts(contacts, lkey=None, beta=None)[source]

Add new contacts to the array. See also contacts.add_layer().

make_edgelist(contacts)[source]

Parse a list of people with a list of contacts per person and turn it into an edge list.

static remove_duplicates(df)[source]

Sort the dataframe and remove duplicates – note, not extensively tested

class Person(pars=None, uid=None, age=-1, sex=-1, contacts=None)[source]

Bases: sciris.sc_utils.prettyobj

Class for a single person. Note: this is largely deprecated since People is now based on arrays rather than being a list of people.

New in version 1.10.0.

class FlexDict[source]

Bases: dict

A dict that allows more flexible element access: in addition to obj[‘a’], also allow obj[0]. Lightweight implementation of the Sciris odict class.

keys()[source]
values()[source]
items()[source]
class Contacts(layer_keys=None)[source]

Bases: synthpops.people.people.FlexDict

A simple (for now) class for storing different contact layers.

New in version 1.10.0.

add_layer(**kwargs)[source]

Small method to add one or more layers to the contacts. Layers should be provided as keyword arguments.

Example:

hospitals_layer = cv.Layer(label='hosp')
sim.people.contacts.add_layer(hospitals=hospitals_layer)
pop_layer(*args)[source]

Remove the layer(s) from the contacts.

Example:

sim.people.contacts.pop_layer('hospitals')

Note: while included here for convenience, this operation is equivalent to simply popping the key from the contacts dictionary.

to_graph()[source]

Convert all layers to a networkx MultiDiGraph

Example:

import networkx as nx
sim = cv.Sim(pop_size=50, pop_type='hybrid').run()
G = sim.people.contacts.to_graph()
nx.draw(G)
class Layer(label=None, **kwargs)[source]

Bases: synthpops.people.people.FlexDict

A small class holding a single layer of contact edges (connections) between people.

The input is typically three arrays: person 1 of the connection, person 2 of the connection, and the weight of the connection. Connections are undirected; each person is both a source and sink.

This class is usually not invoked directly by the user, but instead is called as part of the population creation.

Parameters:
  • p1 (array) – an array of N connections, representing people on one side of the connection
  • p2 (array) – an array of people on the other side of the connection
  • beta (array) – an array of weights for each connection
  • label (str) – the name of the layer (optional)
  • kwargs (dict) – other keys copied directly into the layer

Note that all arguments (except for label) must be arrays of the same length, although not all have to be supplied at the time of creation (they must all be the same at the time of initialization, though, or else validation will fail).

Examples:

# Generate an average of 10 contacts for 1000 people
n = 10_000
n_people = 1000
p1 = np.random.randint(n_people, size=n)
p2 = np.random.randint(n_people, size=n)
beta = np.ones(n)
layer = cv.Layer(p1=p1, p2=p2, beta=beta, label='rand')

# Convert one layer to another with extra columns
index = np.arange(n)
self_conn = p1 == p2
layer2 = cv.Layer(**layer, index=index, self_conn=self_conn, label=layer.label)

New in version 1.10.0.

members

Return sorted array of all members

meta_keys()[source]

Return the keys for the layer’s meta information – i.e., p1, p2, beta

validate()[source]

Check the integrity of the layer: right types, right lengths

pop_inds(inds)[source]

“Pop” the specified indices from the edgelist and return them as a dict. Returns in the right format to be used with layer.append().

Parameters:inds (int, array, slice) – the indices to be removed
append(contacts)[source]

Append contacts to the current layer.

Parameters:contacts (dict) – a dictionary of arrays with keys p1,p2,beta, as returned from layer.pop_inds()
to_df()[source]

Convert to dataframe

from_df(df, keys=None)[source]

Convert from a dataframe

to_graph()[source]

Convert to a networkx DiGraph

Example:

import networkx as nx
sim = cv.Sim(pop_size=20, pop_type='hybrid').run()
G = sim.people.contacts['h'].to_graph()
nx.draw(G)
find_contacts(inds, as_array=True)[source]

Find all contacts of the specified people

For some purposes (e.g. contact tracing) it’s necessary to find all of the contacts associated with a subset of the people in this layer. Since contacts are bidirectional it’s necessary to check both P1 and P2 for the target indices. The return type is a Set so that there is no duplication of indices (otherwise if the Layer has explicit symmetric interactions, they could appear multiple times). This is also for performance so that the calling code doesn’t need to perform its own unique() operation. Note that this cannot be used for cases where multiple connections count differently than a single infection, e.g. exposure risk.

Parameters:
  • inds (array) – indices of people whose contacts to return
  • as_array (bool) – if true, return as sorted array (otherwise, return as unsorted set)
Returns:

a set of indices for pairing partners

Return type:

contact_inds (array)

Example: If there were a layer with - P1 = [1,2,3,4] - P2 = [2,3,1,4] Then find_contacts([1,3]) would return {1,2,3}

update(people, frac=1.0)[source]

Regenerate contacts on each timestep.

This method gets called if the layer appears in sim.pars['dynam_lkeys']. The Layer implements the update procedure so that derived classes can customize the update e.g. implementing over-dispersion/other distributions, random clusters, etc.

Typically, this method also takes in the people object so that the update can depend on person attributes that may change over time (e.g. changing contacts for people that are severe/critical).

Parameters:frac (float) – the fraction of contacts to update on each timestep
class People(pars, strict=False, **kwargs)[source]

Bases: synthpops.people.people.BasePeople

A class to perform all the operations on the people. This class is usually not invoked directly, but instead is created automatically by the sim. The only required input argument is the population size, but typically the full parameters dictionary will get passed instead since it will be needed before the People object is initialized.

Note that this class handles the mechanics of updating the actual people, while BasePeople takes care of housekeeping (saving, loading, exporting, etc.). Please see the BasePeople class for additional methods.

Parameters:
  • pars (dict) – the sim parameters, e.g. sim.pars – alternatively, if a number, interpreted as pop_size
  • strict (bool) – whether or not to only create keys that are already in self.meta.person; otherwise, let any key be set
  • kwargs (dict) – the actual data, e.g. from a popdict, being specified

::Examples:

ppl1 = cv.People(2000)

sim = cv.Sim()
ppl2 = cv.People(sim.pars)

New in version 1.10.0.

plot(bins=None, width=1.0, alpha=0.6, fig_args=None, axis_args=None, plot_args=None, do_show=None, fig=None)[source]

Plot statistics of the population – age distribution, numbers of contacts, and overall weight of contacts (number of contacts multiplied by beta per layer).

Parameters:
  • bins (arr) – age bins to use (default, 0-100 in one-year bins)
  • width (float) – bar width
  • font_size (float) – size of font
  • alpha (float) – transparency of the plots
  • fig_args (dict) – passed to pl.figure()
  • axis_args (dict) – passed to pl.subplots_adjust()
  • plot_args (dict) – passed to pl.plot()
  • do_show (bool) – whether to show the plot
  • fig (fig) – handle of existing figure to plot into
plot_graph()[source]

Convert to networkx and draw. WARNING: extremely slow for more than ~100 people!

Example:

pop = sp.Pop(n=50)
pop.to_people().plot_graph()
story(uid, *args)[source]

Print out a short history of events in the life of the specified individual.

Parameters:
  • uid (int/list) – the person or people whose story is being regaled
  • args (list) – these people will tell their stories too

Example:

sim = cv.Sim(pop_type='hybrid', verbose=0)
sim.run()
sim.people.story(12)
sim.people.story(795)