logo Netzschleuder network catalog, repository, and centrifuge

History of portland_contacts

The changes to the source code of this entry in the repository, newest first, each with the differences it made to the entry's files. They are also listed on GitLab.

[entries] Add the date when each entry was added, and remove icon_hash by Tiago de Paula Peixoto beff7c9
The dates are those of the commits that first added the entries' files
(2020-08-11 for the entries of the initial commit); renamed entries keep
the date of their first name.

Changed: none
diff --git a/entries/portland_contacts/__init__.py b/entries/portland_contacts/__init__.py
index 1a0d955..571becb 100644
--- a/entries/portland_contacts/__init__.py
+++ b/entries/portland_contacts/__init__.py
@@ -35,7 +35,7 @@ citation = [('S. Eubank, H. Guclu, V. S. A. Kumar, M. V. Marathe, A. Srinivasan,
              'https://doi.org/10.1038/nature02541'),
             ('S. Yang, P. Senapati, D. Wang, C. T. Bauch, K. Fountoulakis, "Targeted pandemic containment through identifying local contact network bottlenecks." PLOS Computational Biology 17(8), e1009351 (2021)',
              'https://doi.org/10.1371/journal.pcbi.1009351')]
-icon_hash = None
+date_added = '2026-10-28'
 upstream_license = ("CC0", "https://creativecommons.org/publicdomain/zero/1.0/")
 
 upstream_prefix = 'https://api.figshare.com/v2/file/download'
[entries] Prefix the properties in the descriptions with (Node), (Edge) or (Graph) by Tiago de Paula Peixoto bc3dbbd
The lists of properties at the end of the descriptions marked edge
properties with "Edge" but left node properties unmarked, or grouped
them in "Nodes: `a`, ...; `b`, ..." items, so the kind of a property
was often unclear. Every item now starts with (Node), (Edge) or (Graph),
followed by the property names, a colon and the explanation, one item
per property or group of properties; qualifications (kinds of nodes,
networks) follow the names in parentheses. Properties that were only
named got a short explanation, and a few items that named the wrong
kind of property were corrected.
diff --git a/entries/portland_contacts/__init__.py b/entries/portland_contacts/__init__.py
index aa8e8df..1a0d955 100644
--- a/entries/portland_contacts/__init__.py
+++ b/entries/portland_contacts/__init__.py
@@ -28,7 +28,7 @@ The data are those redistributed by Yang et al. for their study of pandemic cont
 
 The network has the following properties:
 
-- `id`: the identifier of the person in the data."""
+- (Node) `id`: the identifier of the person in the data."""
 tags = ['Social', 'Offline', 'Public Health', 'Unweighted']
 url = 'https://doi.org/10.6084/m9.figshare.13166507.v1'
 citation = [('S. Eubank, H. Guclu, V. S. A. Kumar, M. V. Marathe, A. Srinivasan, Z. Toroczkai, N. Wang, "Modelling disease outbreaks in realistic urban social networks." Nature 429, 180-184 (2004)',
[entries] New entry: portland_contacts by Tiago de Paula Peixoto ee5eef1
diff --git a/entries/portland_contacts/__init__.py b/entries/portland_contacts/__init__.py
new file mode 100644
index 0000000..aa8e8df
--- /dev/null
+++ b/entries/portland_contacts/__init__.py
@@ -0,0 +1,84 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2026 Tiago de Paula Peixoto <tiago@skewed.de>
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import pyarrow
+import pyarrow.csv
+
+from .. import *
+
+title = "Synthetic contact network of Portland, Oregon"
+description = r"""A synthetic network of the physical contacts between the inhabitants of Portland, Oregon (USA), during a typical day, generated by the Network Dynamics and Simulation Science Laboratory (NDSSL, Virginia Tech, formerly at Los Alamos National Laboratory) with the TRANSIMS and EpiSims simulations from census data, land use data and activity surveys: synthetic individuals, with the demographics of the census, are assigned daily activities (home, work, school, shopping, ...) at real locations, and two persons are in contact if they are at the same location (sub-location) at the same time. Each node is a person, and an undirected edge means that the two persons were in contact during the day. This network was widely used to model the spread of infectious diseases in cities.
+
+The data are those redistributed by Yang et al. for their study of pandemic containment, who give the network without the durations and activity types of the contacts of the original NDSSL data, which is no longer available from its source. The node and edge lists of this redistribution are used as they are; the centrality scores (eigenvector and local-flow betweenness centralities) computed by Yang et al., and given in the same record, are not included.
+
+The network has the following properties:
+
+- `id`: the identifier of the person in the data."""
+tags = ['Social', 'Offline', 'Public Health', 'Unweighted']
+url = 'https://doi.org/10.6084/m9.figshare.13166507.v1'
+citation = [('S. Eubank, H. Guclu, V. S. A. Kumar, M. V. Marathe, A. Srinivasan, Z. Toroczkai, N. Wang, "Modelling disease outbreaks in realistic urban social networks." Nature 429, 180-184 (2004)',
+             'https://doi.org/10.1038/nature02541'),
+            ('S. Yang, P. Senapati, D. Wang, C. T. Bauch, K. Fountoulakis, "Targeted pandemic containment through identifying local contact network bottlenecks." PLOS Computational Biology 17(8), e1009351 (2021)',
+             'https://doi.org/10.1371/journal.pcbi.1009351')]
+icon_hash = None
+upstream_license = ("CC0", "https://creativecommons.org/publicdomain/zero/1.0/")
+
+upstream_prefix = 'https://api.figshare.com/v2/file/download'
+# portland_edgelist_sorted.txt, portland_nodes_sorted.txt
+files = [(('25319432', '25319492'), None, None)]
+
+def fetch_upstream(force=False):
+    return fetch_upstream_files(__name__.split(".")[-1], upstream_prefix, files,
+                                force)
+
+@cache_network()
+@coerce_props()
+@annotate()
+def parse(alts=None):
+    name = __name__.split(".")[-1]
+    for fnames, alt, fmt in files:
+        if alts is not None and alt not in alts:
+            continue
+        with open_upstream_file(name, fnames[1], "rb") as f:
+            ids = numpy.loadtxt(f, dtype="int64", ndmin=1)
+        with open_upstream_file(name, fnames[0], "rb") as f:
+            tab = pyarrow.csv.read_csv(
+                f,
+                read_options=pyarrow.csv.ReadOptions(column_names=["u", "v"],
+                                                     block_size=1 << 26),
+                parse_options=pyarrow.csv.ParseOptions(delimiter="\t"),
+                convert_options=pyarrow.csv.ConvertOptions(
+                    column_types={"u": pyarrow.int64(), "v": pyarrow.int64()}))
+        u = tab.column("u").to_numpy()
+        v = tab.column("v").to_numpy()
+        del tab
+        if len(numpy.unique(ids)) != len(ids):
+            raise ValueError("repeated node ids")
+        order = numpy.argsort(ids)
+        sids = ids[order]
+        iu, iv = numpy.searchsorted(sids, u), numpy.searchsorted(sids, v)
+        if (iu >= len(sids)).any() or (iv >= len(sids)).any() or \
+           (sids[numpy.minimum(iu, len(sids) - 1)] != u).any() or \
+           (sids[numpy.minimum(iv, len(sids) - 1)] != v).any():
+            raise ValueError("edges with unknown node ids")
+        del u, v
+        g = Graph(directed=False)
+        g.add_vertex(len(ids))
+        g.vp.id = g.new_vp("int64_t", vals=sids)
+        g.add_edge_list(numpy.column_stack((iu, iv)))
+        yield alt, g