logo Netzschleuder network catalog, repository, and centrifuge

History of sp_infectious

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.

[pipeline] Generalize archive member access and accept plain-string licences by Tiago de Paula Peixoto 4d6df54
- Archive member names are parsed in one place (split_archive_member()):
  .zip, .tar.gz, .tgz, .tar.bz2, .tbz2, .tar.xz, .tar, .rar and .7z, by
  extension or as "<name>:<kind>:"; members may themselves be archives
  ("x.zip:inner.zip:path"). Tar archives are opened with any compression.
  Text-mode reads accept an encoding.
- zst_open("rb") returns a buffered reader, so that binary line iteration
  works; files named *.zst are read decompressed.
- fetch_archived_files checks for existing files without opening them
  (archives of any kind), and checks the zip magic of downloads.
- upstream_license may be a plain string (a name without url) or a
  (name, url) tuple; plain strings were stored character by character.
- entries/template.py: ustream_license -> upstream_license.
diff --git a/entries/sp_infectious/__init__.py b/entries/sp_infectious/__init__.py
index d47c029..98d8755 100644
--- a/entries/sp_infectious/__init__.py
+++ b/entries/sp_infectious/__init__.py
@@ -57,7 +57,7 @@ days = ['2009_04_28', '2009_04_29', '2009_04_30', '2009_05_01',
         '2009_07_08', '2009_07_09', '2009_07_10', '2009_07_11',
         '2009_07_12', '2009_07_14', '2009_07_15', '2009_07_16',
         '2009_07_17']
-files = [([f'sciencegallery_infectious_contacts.tgz:tar.gz:listcontacts_{d}.txt'
+files = [([f'sciencegallery_infectious_contacts.tgz:listcontacts_{d}.txt'
            for d in days], 'contacts', 'edgelist')]
 files += [(f'INFECTIOUS_cumulative_daily_networks.tar.gz:./INFECTIOUS_cumulative_daily_networks/cumulative_{d.replace("_", "-")}.gml',
            f'day_{d}', 'gml') for d in days]
[entries] Fix parse bugs and improve descriptions and metadata by Tiago de Paula Peixoto 6bb6851
- parse fixes from the review of the descriptions, e.g. us_patents
  (directed), celegans_2019 (synapse direction), ecoli_transcription and
  yeast_transcription (regulator to target), bitcoin (direction, phantom
  node), ego_social (Google+ features and circles), scotus_majority,
  arxiv_authors and social_location (as in SNAP), caida_as, dnc, dom,
  mist, reuters and bibsonomy (names on the right nodes), uci_zoo
- every description now states explicitly what the nodes and edges
  represent; corrected titles, years, tags, citations and licences
- the "Hypergraph" tag is removed; very large entries are marked
  `huge = True` (see --skip-huge)
- ICON ids of partial duplicates added (hiv_transmission, congress_bills,
  openflights, dutch_school)
diff --git a/entries/sp_infectious/__init__.py b/entries/sp_infectious/__init__.py
index ac3a2c6..d47c029 100644
--- a/entries/sp_infectious/__init__.py
+++ b/entries/sp_infectious/__init__.py
@@ -20,52 +20,47 @@ from .. import *
 
 import csv
 
-title = "Art exhibit dynamic contacts (2011)"
-description = """This dataset contains the daily dynamic contact networks collected during the Infectious SocioPatterns event that took place at the Science Gallery in Dublin, Ireland, during the artscience exhibition INFECTIOUS: STAY AWAY. Each file in the downloadable package contains a tab-separated list representing the active contacts during 20-second intervals of one day of data collection.  Each line has the form “t i j“, where i and j are the anonymous IDs of the persons in contact, and the interval during which this contact was active is [ t – 20s, t ]. If multiple contacts are active in a given interval, you will see multiple lines starting with the same value of t. Time is measured in seconds and expressed in UNIX ctime.[^icon]
-[^icon]: Description obtained from the [ICON](https://icon.colorado.edu) project."""
-tags = ['Social', 'Offline', 'Unweighted', 'Temporal']
-url = 'http://www.sociopatterns.org/datasets/infectious-sociopatterns-dynamic-contact-networks/'
+title = "Art exhibit dynamic contacts (2009)"
+description = r"""Networks of face-to-face proximity contacts among visitors of the exhibition "INFECTIOUS: STAY AWAY" at the Science Gallery in Dublin, Ireland, measured by the SocioPatterns collaboration with wearable sensors, from 28 April to 17 July 2009. Visitors volunteered to wear radio badges that detected face-to-face proximity. Data were collected on 69 days, and each visitor was present on only one day. The following networks are provided:
+
+- `contacts`: temporal network of all contacts. The upstream data consist of one file per day of data collection; here they are combined into a single network. Nodes are visitors, and each edge is a contact between two visitors active during a 20-second interval of the data collection, so that a pair of visitors is connected by one edge per interval in which they were in contact.
+- `day_YYYY_MM_DD` (69 networks, one per day of data collection): the cumulative network of the given day, as represented in the Infectious SocioPatterns visualization and published separately upstream. Nodes are visitors, and an edge connects two visitors that were in contact at least once during the day; a few nodes are isolated. These networks were processed independently from the contact lists of the `contacts` network, and they do not match them exactly (on most days, they contain more nodes and contacts). Their nodes carry no identifier: the upstream node numbers are reused in different days for different visitors, and they do not correspond to the identifiers of the `contacts` network.
+
+The networks have the following properties:
+
+- `id` (`contacts`): the anonymous identifier of the visitor.
+- `time` (`contacts`): the end of the 20-second interval $[t - 20\,\text{s}, t]$ during which the contact was active, as a UNIX timestamp in seconds.
+- `weight` (`day_YYYY_MM_DD`): the number of 20-second intervals during which the two visitors were in contact on that day."""
+tags = ['Social', 'Offline', 'Unweighted', 'Weighted', 'Temporal']
+url = 'https://sociopatterns.org/datasets/infectious-exhibition-dynamic-contact-networks/'
 citation = [('L. Isella et al., "What\'s in a crowd? Analysis of face-to-face behavioral networks." Journal of Theoretical Biology 271, 166-180 (2011).', 'http://arxiv.org/abs/1006.1260')]
-icon_hash = '56a85c8e26855e083a2f78d9'
-ustream_license = ("Creative Commons Attribution-NonCommercial-ShareAlike",
+icon_hash = ['56a85c8e26855e083a2f78d9',
+             '57e18fb08cf714f319c38be0']
+upstream_license = ("Creative Commons Attribution-NonCommercial-ShareAlike",
                    "http://creativecommons.org/licenses/by-nc-sa/3.0/")
-upstream_prefix = 'http://www.sociopatterns.org/files/datasets/004'
-files = [([f'sg_infectious_contact_list.tgz:tar.gz:{f}' for f in
-           ["listcontacts_2009_04_28.txt", "listcontacts_2009_04_29.txt",
-            "listcontacts_2009_04_30.txt", "listcontacts_2009_05_01.txt",
-            "listcontacts_2009_05_02.txt", "listcontacts_2009_05_03.txt",
-            "listcontacts_2009_05_05.txt", "listcontacts_2009_05_06.txt",
-            "listcontacts_2009_05_07.txt", "listcontacts_2009_05_09.txt",
-            "listcontacts_2009_05_10.txt", "listcontacts_2009_05_12.txt",
-            "listcontacts_2009_05_13.txt", "listcontacts_2009_05_14.txt",
-            "listcontacts_2009_05_15.txt", "listcontacts_2009_05_16.txt",
-            "listcontacts_2009_05_17.txt", "listcontacts_2009_05_19.txt",
-            "listcontacts_2009_05_20.txt", "listcontacts_2009_05_21.txt",
-            "listcontacts_2009_05_22.txt", "listcontacts_2009_05_23.txt",
-            "listcontacts_2009_05_24.txt", "listcontacts_2009_05_26.txt",
-            "listcontacts_2009_05_27.txt", "listcontacts_2009_05_28.txt",
-            "listcontacts_2009_05_29.txt", "listcontacts_2009_05_30.txt",
-            "listcontacts_2009_05_31.txt", "listcontacts_2009_06_02.txt",
-            "listcontacts_2009_06_03.txt", "listcontacts_2009_06_04.txt",
-            "listcontacts_2009_06_05.txt", "listcontacts_2009_06_06.txt",
-            "listcontacts_2009_06_07.txt", "listcontacts_2009_06_09.txt",
-            "listcontacts_2009_06_10.txt", "listcontacts_2009_06_11.txt",
-            "listcontacts_2009_06_12.txt", "listcontacts_2009_06_13.txt",
-            "listcontacts_2009_06_14.txt", "listcontacts_2009_06_16.txt",
-            "listcontacts_2009_06_17.txt", "listcontacts_2009_06_18.txt",
-            "listcontacts_2009_06_19.txt", "listcontacts_2009_06_20.txt",
-            "listcontacts_2009_06_21.txt", "listcontacts_2009_06_23.txt",
-            "listcontacts_2009_06_24.txt", "listcontacts_2009_06_25.txt",
-            "listcontacts_2009_06_26.txt", "listcontacts_2009_06_27.txt",
-            "listcontacts_2009_06_28.txt", "listcontacts_2009_06_30.txt",
-            "listcontacts_2009_07_01.txt", "listcontacts_2009_07_02.txt",
-            "listcontacts_2009_07_03.txt", "listcontacts_2009_07_04.txt",
-            "listcontacts_2009_07_05.txt", "listcontacts_2009_07_07.txt",
-            "listcontacts_2009_07_08.txt", "listcontacts_2009_07_09.txt",
-            "listcontacts_2009_07_10.txt", "listcontacts_2009_07_11.txt",
-            "listcontacts_2009_07_12.txt", "listcontacts_2009_07_14.txt",
-            "listcontacts_2009_07_15.txt", "listcontacts_2009_07_16.txt",
-            "listcontacts_2009_07_17.txt"]], None, 'edgelist')]
+upstream_prefix = 'https://sociopatterns.org/assets/data'
+days = ['2009_04_28', '2009_04_29', '2009_04_30', '2009_05_01',
+        '2009_05_02', '2009_05_03', '2009_05_05', '2009_05_06',
+        '2009_05_07', '2009_05_09', '2009_05_10', '2009_05_12',
+        '2009_05_13', '2009_05_14', '2009_05_15', '2009_05_16',
+        '2009_05_17', '2009_05_19', '2009_05_20', '2009_05_21',
+        '2009_05_22', '2009_05_23', '2009_05_24', '2009_05_26',
+        '2009_05_27', '2009_05_28', '2009_05_29', '2009_05_30',
+        '2009_05_31', '2009_06_02', '2009_06_03', '2009_06_04',
+        '2009_06_05', '2009_06_06', '2009_06_07', '2009_06_09',
+        '2009_06_10', '2009_06_11', '2009_06_12', '2009_06_13',
+        '2009_06_14', '2009_06_16', '2009_06_17', '2009_06_18',
+        '2009_06_19', '2009_06_20', '2009_06_21', '2009_06_23',
+        '2009_06_24', '2009_06_25', '2009_06_26', '2009_06_27',
+        '2009_06_28', '2009_06_30', '2009_07_01', '2009_07_02',
+        '2009_07_03', '2009_07_04', '2009_07_05', '2009_07_07',
+        '2009_07_08', '2009_07_09', '2009_07_10', '2009_07_11',
+        '2009_07_12', '2009_07_14', '2009_07_15', '2009_07_16',
+        '2009_07_17']
+files = [([f'sciencegallery_infectious_contacts.tgz:tar.gz:listcontacts_{d}.txt'
+           for d in days], 'contacts', 'edgelist')]
+files += [(f'INFECTIOUS_cumulative_daily_networks.tar.gz:./INFECTIOUS_cumulative_daily_networks/cumulative_{d.replace("_", "-")}.gml',
+           f'day_{d}', 'gml') for d in days]
 
 def fetch_upstream(force=False):
     return fetch_upstream_files(__name__.split(".")[-1], upstream_prefix, files,
@@ -80,8 +75,14 @@ def parse(alts=None):
     for fnames, alt, fmt in files:
         if alts is not None and alt not in alts:
             continue
-        if isinstance(fnames, str):
-            fnames = [fnames]
+        if fmt == "gml":
+            with open_upstream_file(name, fnames, "rb") as f:
+                g = load_graph(f, fmt="gml")
+            # The node numbers are just the vertex indices
+            del g.gp["directed"]
+            g.ep.weight = g.ep.weight.copy("int")
+            yield alt, g
+            continue
         with ExitStack() as stack:
             fs = [stack.enter_context(open_upstream_file(name, fn, "r")) for fn in fnames]
             def get_edges():
Update copyright information by Tiago de Paula Peixoto 73a4f0d
diff --git a/entries/sp_infectious/__init__.py b/entries/sp_infectious/__init__.py
index 416aac4..ac3a2c6 100644
--- a/entries/sp_infectious/__init__.py
+++ b/entries/sp_infectious/__init__.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2020-2024 Tiago de Paula Peixoto <tiago@skewed.de>
+# Copyright (C) 2020-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
Update copyright information by Tiago de Paula Peixoto 3d288ea
diff --git a/entries/sp_infectious/__init__.py b/entries/sp_infectious/__init__.py
index 6f578db..416aac4 100644
--- a/entries/sp_infectious/__init__.py
+++ b/entries/sp_infectious/__init__.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2020-2023 Tiago de Paula Peixoto <tiago@skewed.de>
+# Copyright (C) 2020-2024 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
Update copyright information by Tiago de Paula Peixoto 8d005ae
diff --git a/entries/sp_infectious/__init__.py b/entries/sp_infectious/__init__.py
index b693921..6f578db 100644
--- a/entries/sp_infectious/__init__.py
+++ b/entries/sp_infectious/__init__.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2021 Tiago de Paula Peixoto <tiago@skewed.de>
+# Copyright (C) 2020-2023 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
Update copyright info by Tiago de Paula Peixoto db2efcc
diff --git a/entries/sp_infectious/__init__.py b/entries/sp_infectious/__init__.py
index 98047ae..b693921 100644
--- a/entries/sp_infectious/__init__.py
+++ b/entries/sp_infectious/__init__.py
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2020 Tiago de Paula Peixoto <tiago@skewed.de>
+# Copyright (C) 2021 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
Change license from GPLv3 to AGPLv3 by Tiago de Paula Peixoto d754be5
diff --git a/entries/sp_infectious/__init__.py b/entries/sp_infectious/__init__.py
index efbfb62..98047ae 100644
--- a/entries/sp_infectious/__init__.py
+++ b/entries/sp_infectious/__init__.py
@@ -3,18 +3,18 @@
 #
 # Copyright (C) 2020 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 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 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 General Public License for more details.
+# 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 General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# 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/>.
 
 from .. import *
 
Add explicit attribution to descriptions obtained from ICON by Tiago de Paula Peixoto 1645314
diff --git a/entries/sp_infectious/__init__.py b/entries/sp_infectious/__init__.py
index 2970ace..efbfb62 100644
--- a/entries/sp_infectious/__init__.py
+++ b/entries/sp_infectious/__init__.py
@@ -21,7 +21,8 @@ from .. import *
 import csv
 
 title = "Art exhibit dynamic contacts (2011)"
-description = "This dataset contains the daily dynamic contact networks collected during the Infectious SocioPatterns event that took place at the Science Gallery in Dublin, Ireland, during the artscience exhibition INFECTIOUS: STAY AWAY. Each file in the downloadable package contains a tab-separated list representing the active contacts during 20-second intervals of one day of data collection.  Each line has the form “t i j“, where i and j are the anonymous IDs of the persons in contact, and the interval during which this contact was active is [ t – 20s, t ]. If multiple contacts are active in a given interval, you will see multiple lines starting with the same value of t. Time is measured in seconds and expressed in UNIX ctime."
+description = """This dataset contains the daily dynamic contact networks collected during the Infectious SocioPatterns event that took place at the Science Gallery in Dublin, Ireland, during the artscience exhibition INFECTIOUS: STAY AWAY. Each file in the downloadable package contains a tab-separated list representing the active contacts during 20-second intervals of one day of data collection.  Each line has the form “t i j“, where i and j are the anonymous IDs of the persons in contact, and the interval during which this contact was active is [ t – 20s, t ]. If multiple contacts are active in a given interval, you will see multiple lines starting with the same value of t. Time is measured in seconds and expressed in UNIX ctime.[^icon]
+[^icon]: Description obtained from the [ICON](https://icon.colorado.edu) project."""
 tags = ['Social', 'Offline', 'Unweighted', 'Temporal']
 url = 'http://www.sociopatterns.org/datasets/infectious-sociopatterns-dynamic-contact-networks/'
 citation = [('L. Isella et al., "What\'s in a crowd? Analysis of face-to-face behavioral networks." Journal of Theoretical Biology 271, 166-180 (2011).', 'http://arxiv.org/abs/1006.1260')]
Initial commit by Tiago de Paula Peixoto cc85872
diff --git a/entries/sp_infectious/__init__.py b/entries/sp_infectious/__init__.py
new file mode 100644
index 0000000..2970ace
--- /dev/null
+++ b/entries/sp_infectious/__init__.py
@@ -0,0 +1,97 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2020 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 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from .. import *
+
+import csv
+
+title = "Art exhibit dynamic contacts (2011)"
+description = "This dataset contains the daily dynamic contact networks collected during the Infectious SocioPatterns event that took place at the Science Gallery in Dublin, Ireland, during the artscience exhibition INFECTIOUS: STAY AWAY. Each file in the downloadable package contains a tab-separated list representing the active contacts during 20-second intervals of one day of data collection.  Each line has the form “t i j“, where i and j are the anonymous IDs of the persons in contact, and the interval during which this contact was active is [ t – 20s, t ]. If multiple contacts are active in a given interval, you will see multiple lines starting with the same value of t. Time is measured in seconds and expressed in UNIX ctime."
+tags = ['Social', 'Offline', 'Unweighted', 'Temporal']
+url = 'http://www.sociopatterns.org/datasets/infectious-sociopatterns-dynamic-contact-networks/'
+citation = [('L. Isella et al., "What\'s in a crowd? Analysis of face-to-face behavioral networks." Journal of Theoretical Biology 271, 166-180 (2011).', 'http://arxiv.org/abs/1006.1260')]
+icon_hash = '56a85c8e26855e083a2f78d9'
+ustream_license = ("Creative Commons Attribution-NonCommercial-ShareAlike",
+                   "http://creativecommons.org/licenses/by-nc-sa/3.0/")
+upstream_prefix = 'http://www.sociopatterns.org/files/datasets/004'
+files = [([f'sg_infectious_contact_list.tgz:tar.gz:{f}' for f in
+           ["listcontacts_2009_04_28.txt", "listcontacts_2009_04_29.txt",
+            "listcontacts_2009_04_30.txt", "listcontacts_2009_05_01.txt",
+            "listcontacts_2009_05_02.txt", "listcontacts_2009_05_03.txt",
+            "listcontacts_2009_05_05.txt", "listcontacts_2009_05_06.txt",
+            "listcontacts_2009_05_07.txt", "listcontacts_2009_05_09.txt",
+            "listcontacts_2009_05_10.txt", "listcontacts_2009_05_12.txt",
+            "listcontacts_2009_05_13.txt", "listcontacts_2009_05_14.txt",
+            "listcontacts_2009_05_15.txt", "listcontacts_2009_05_16.txt",
+            "listcontacts_2009_05_17.txt", "listcontacts_2009_05_19.txt",
+            "listcontacts_2009_05_20.txt", "listcontacts_2009_05_21.txt",
+            "listcontacts_2009_05_22.txt", "listcontacts_2009_05_23.txt",
+            "listcontacts_2009_05_24.txt", "listcontacts_2009_05_26.txt",
+            "listcontacts_2009_05_27.txt", "listcontacts_2009_05_28.txt",
+            "listcontacts_2009_05_29.txt", "listcontacts_2009_05_30.txt",
+            "listcontacts_2009_05_31.txt", "listcontacts_2009_06_02.txt",
+            "listcontacts_2009_06_03.txt", "listcontacts_2009_06_04.txt",
+            "listcontacts_2009_06_05.txt", "listcontacts_2009_06_06.txt",
+            "listcontacts_2009_06_07.txt", "listcontacts_2009_06_09.txt",
+            "listcontacts_2009_06_10.txt", "listcontacts_2009_06_11.txt",
+            "listcontacts_2009_06_12.txt", "listcontacts_2009_06_13.txt",
+            "listcontacts_2009_06_14.txt", "listcontacts_2009_06_16.txt",
+            "listcontacts_2009_06_17.txt", "listcontacts_2009_06_18.txt",
+            "listcontacts_2009_06_19.txt", "listcontacts_2009_06_20.txt",
+            "listcontacts_2009_06_21.txt", "listcontacts_2009_06_23.txt",
+            "listcontacts_2009_06_24.txt", "listcontacts_2009_06_25.txt",
+            "listcontacts_2009_06_26.txt", "listcontacts_2009_06_27.txt",
+            "listcontacts_2009_06_28.txt", "listcontacts_2009_06_30.txt",
+            "listcontacts_2009_07_01.txt", "listcontacts_2009_07_02.txt",
+            "listcontacts_2009_07_03.txt", "listcontacts_2009_07_04.txt",
+            "listcontacts_2009_07_05.txt", "listcontacts_2009_07_07.txt",
+            "listcontacts_2009_07_08.txt", "listcontacts_2009_07_09.txt",
+            "listcontacts_2009_07_10.txt", "listcontacts_2009_07_11.txt",
+            "listcontacts_2009_07_12.txt", "listcontacts_2009_07_14.txt",
+            "listcontacts_2009_07_15.txt", "listcontacts_2009_07_16.txt",
+            "listcontacts_2009_07_17.txt"]], None, 'edgelist')]
+
+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):
+    global files
+    name = __name__.split(".")[-1]
+    for fnames, alt, fmt in files:
+        if alts is not None and alt not in alts:
+            continue
+        if isinstance(fnames, str):
+            fnames = [fnames]
+        with ExitStack() as stack:
+            fs = [stack.enter_context(open_upstream_file(name, fn, "r")) for fn in fnames]
+            def get_edges():
+                for f in fs:
+                    reader = csv.reader(f, delimiter="\t")
+                    for row in reader:
+                        t, u, v = [int(x) for x in row]
+                        yield u, v, t
+            g = Graph(directed=False)
+            g.ep.time = g.new_ep("int")
+            g.vp.id = g.add_edge_list(get_edges(), hashed=True,
+                                      hash_type="int",
+                                      eprops=[g.ep.time])
+        yield alt, g