History of iwdb
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] Use American spelling in the descriptions 802d564
British spellings in the titles and descriptions of 69 entries (e.g. labelled, organisation, millimetres, centres, anonymised, neighbours, analysed, modelled, colour, licence) are replaced by the American ones. Proper names keep their spelling (Otago Harbour, the Centre for Water Systems, the Centre jeunesse de Montréal, the Dutch Ministry of Defence), as do quoted upstream terms, citations, and property names.
diff --git a/entries/iwdb/__init__.py b/entries/iwdb/__init__.py
index fac8ff1..77c56a2 100644
--- a/entries/iwdb/__init__.py
+++ b/entries/iwdb/__init__.py
@@ -40,7 +40,7 @@ The networks are named `<type>_<author>`, after the kind of interaction and the
- `pollination_elberling` (Elberling and Olesen 1999): plants and their insect flower visitors in the subarctic alpine zone of Latnjajaure, northern Sweden, observed from 21 May to 23 August 1994, in a study of the structure of a high-latitude plant-flower visitor system and of the role of flies as flower visitors. All insects found on flowers were counted as flower visitors, whether they foraged for nectar or pollen or were sun-basking. Nodes: `name`, `genus`, `species`, `is_pollinator`. Edges: `count`, the number of visits.
- `pollination_hocking` (Hocking 1968): plants and their flower visitors (insects, and also spiders and mites) on Ellesmere Island, Northwest Territories (now Nunavut), Canada, from a study of the composition of the assemblage of flower visitors in the high Arctic and its relationship to nectar production. Unweighted. Nodes: `name`, `genus`, `species` (or a higher taxon such as a family when not identified further), `is_pollinator`.
- `pollination_inouye` (Inouye and Pyke 1988): alpine plants and their insect flower visitors in Kosciusko National Park, Snowy Mountains, New South Wales, Australia, observed from December 1983 to March 1984, in a community-level study of alpine pollination biology compared with montane Colorado, USA. The source lists 20 further plant species without any visitation data; they are not included. Nodes: `name`, `genus`, `species` (some insects are distinguished by sex); `order`, the insect order (Diptera, Hymenoptera or Lepidoptera; empty for plants); `is_pollinator`. Edges: `count`, the number of insect individuals caught on the flowers of the plant species.
-- `pollination_kaiser_bunbury_control`, `pollination_kaiser_bunbury_restored` (Kaiser-Bunbury et al. 2009, 2010): quantitative networks of plants and their flower visitors (insects, birds and lizards) in the upland heathland of Mauritius, comparing an area heavily invaded by introduced plant species (`control`) with an area from which the non-native plants had been removed (`restored`). Interactions were recorded by static observations ("sit-and-observe") of flowers, with varying numbers of flowers and observation times; to account for these differences, visitation rates were computed as visits per flower per hour and averaged over the total observation time. For each edge, the visitation rate and the interaction strength (which in addition accounts for the floral abundance of the plant at the site) are given; a few interactions have a nonzero value in only one of the two matrices of the source. Plant species without any recorded visit appear as isolated nodes. Nodes: `name`, the species name (for animals with the authority, as given in the source); `family`, the taxonomic family; `origin`, the origin of the species as a numeric code (the codes are not explained in the data file); `flower_colour` and `flower_category`, numeric codes for the flower colour and flower type of the plants (not explained in the data file; zero for animals); `floral_abundance`, the floral abundance of the plants at the site (zero for animals); `probed_flowers`, the number of flowers probed by the animal species (zero for plants); `is_pollinator`. Edges: `visitation_rate`, the visitation rate (visits per flower per hour); `interaction_strength`, the interaction strength.
+- `pollination_kaiser_bunbury_control`, `pollination_kaiser_bunbury_restored` (Kaiser-Bunbury et al. 2009, 2010): quantitative networks of plants and their flower visitors (insects, birds and lizards) in the upland heathland of Mauritius, comparing an area heavily invaded by introduced plant species (`control`) with an area from which the non-native plants had been removed (`restored`). Interactions were recorded by static observations ("sit-and-observe") of flowers, with varying numbers of flowers and observation times; to account for these differences, visitation rates were computed as visits per flower per hour and averaged over the total observation time. For each edge, the visitation rate and the interaction strength (which in addition accounts for the floral abundance of the plant at the site) are given; a few interactions have a nonzero value in only one of the two matrices of the source. Plant species without any recorded visit appear as isolated nodes. Nodes: `name`, the species name (for animals with the authority, as given in the source); `family`, the taxonomic family; `origin`, the origin of the species as a numeric code (the codes are not explained in the data file); `flower_colour` and `flower_category`, numeric codes for the flower color and flower type of the plants (not explained in the data file; zero for animals); `floral_abundance`, the floral abundance of the plants at the site (zero for animals); `probed_flowers`, the number of flowers probed by the animal species (zero for plants); `is_pollinator`. Edges: `visitation_rate`, the visitation rate (visits per flower per hour); `interaction_strength`, the interaction strength.
- `pollination_kato` (Kato et al. 1990): plants and flower-visiting insect species (or morphospecies) in the primary beech forest of the Kyoto University Forest of Ashu, at the northeastern boundary of Kyoto Prefecture, Japan, studied by M. Kato, T. Makutani, T. Inoue and T. Itino between 1984 and 1987; the study recorded the flowering phenology of 91 plant species and collected the insects visiting their flowers. An edge connects an insect to a plant on whose flowers it was caught. Nodes: `is_pollinator`, whether the node is an insect (otherwise a plant); `idx`, the index of the species in the source matrix; `pol_ge_sp`, the name of the insect species, followed by abbreviations of its family and order in parentheses (as in "Actina jezoensis (Str. : Dip. )"; empty for plants); `plant_ge`, `plant_sp`, the genus and species of the plant (empty for insects). Edges: `count`, the number of individuals of the insect species collected on the plant species.
- `pollination_kevan` (Kevan 1970): plants and the arthropods visiting their flowers at Hazen Camp, near Lake Hazen on northern Ellesmere Island (81°49'N, 71°18'W), in the Canadian high Arctic, observed in 1967 for P. G. Kevan's PhD thesis on the importance of insect-flower relations for arctic plants and insects. For some interactions the source gives only a qualitative indication instead of a number ("few", "several", "many", "eggs", or "?"). The willow *Salix arctica* is split into three nodes, for its staminate, pistillate and undetermined catkins. Nodes: `name`, `genus`, `species` (or a higher taxon such as a family when not identified further), `is_pollinator`. Edges: `count`, the number of individuals caught (NaN if only a qualitative indication is given); `note`, the qualitative indication given instead of a number (empty otherwise).
- `pollination_mcmullen` (McMullen 1993): plants and their insect flower visitors in the Galápagos Islands, compiled by C. K. McMullen from records of plant-flower visitor interactions in the literature, together with a field study on Pinta Island of the flower visitors of six plant species (the IWDB spells the author's name "McCullen"). Unweighted. Nodes: `name`, `genus`, `species` (or a higher group such as "Beetles" when not identified further), `is_pollinator`.
@@ -62,18 +62,18 @@ The networks are named `<type>_<author>`, after the kind of interaction and the
- `ant_plant_bluthgen` (Blüthgen et al. 2004): ants and the plants whose nectaries they attend, in the rainforest at the Australian Canopy Crane site in Cape Tribulation, Far North Queensland, Australia (16°07'S, 145°27'E, 80 m a.s.l.), and in adjacent forests within 5 km of the crane, including patches of open secondary forest. Ant colonies attending extrafloral nectaries (EFN) and floral nectaries (FN) of plants were recorded, and an edge connects an ant species to a plant nectary type, weighted by the number of ant individuals of the species collected on the plant species. Plant species with both kinds of nectaries are represented by two nodes, one for each nectary type. The data also include independent abundance estimates of the ant species from sugar-bait experiments (Blüthgen and Fiedler 2004) and of the plants. Nodes: `name`, the species name; `family`, the plant family, or `subfamily`, the ant subfamily (each empty for the other kind of node); `nectaries`, the nectary type of the plant node ("EFN" extrafloral, "FN" floral; empty for ants); `life_form`, the life form of the plant ("cl" climber, "he" herb, "sh" shrub, "tr" tree, "pa" palm; empty for ants); `abundance`, for ants the abundance of colonies estimated from sugar-bait experiments (zero for ants not recorded at the baits), and for plants the number of plant individuals on whose nectaries any insect was recorded; `is_ant`. Edges: `count`, the number of ant individuals collected.
- `ant_plant_davidson` (Davidson et al. 1989): ants and eight myrmecophytes (plants housing ant colonies) in the tropical moist forests of western Amazonia, Peru, surveyed in September, October and November of 1985 and 1986, in a study of the variation in the ant associates of the myrmecophytes, of competition among ants for host plants and of the significance of plant trichomes. Species listed in the source without any recorded association appear as isolated nodes. Nodes: `name`, `genus`, `species`, `is_ant`. Edges: `count`, the number of recorded associations, as given in the source.
- `ant_plant_davidson_fisher` (Davidson and Fisher 1991): six *Cecropia* trees and the four ant species inhabiting them, from a study of the symbiosis of ants with *Cecropia* as a function of the light regime, in which the authors discuss how different kinds of asymmetry in specialization lead to different forms of coevolution. Nodes: `name`, `genus`, `species`, `is_ant`. Edges: `count`, the number of recorded associations, as given in the source.
-- `ant_plant_fonseca` (Fonseca and Ganade 1996): ants and myrmecophytes in the Central Amazonian rainforest north of Manaus, Amazonas, Brazil, studied from June to August 1990, to describe the ant-myrmecophyte matrix quantitatively, search for patterns of compartmentalization, and compare the ant-plant system with other mutualistic systems. Ants not identified to species are labelled with letter codes. Nodes: `name`, `genus`, `species`, `is_ant`. Edges: `count`, the number of recorded associations, as given in the source.
+- `ant_plant_fonseca` (Fonseca and Ganade 1996): ants and myrmecophytes in the Central Amazonian rainforest north of Manaus, Amazonas, Brazil, studied from June to August 1990, to describe the ant-myrmecophyte matrix quantitatively, search for patterns of compartmentalization, and compare the ant-plant system with other mutualistic systems. Ants not identified to species are labeled with letter codes. Nodes: `name`, `genus`, `species`, `is_ant`. Edges: `count`, the number of recorded associations, as given in the source.
**Plant-herbivore networks.**
-- `herbivory_joern_altuda`, `herbivory_joern_marathon` (Joern 1979): grasshoppers (Orthoptera: Acrididae) and the plants they feed on, in two arid grassland communities of the Trans-Pecos region of Texas, USA, near Altuda (`altuda`) and Marathon (`marathon`), from a study of the feeding patterns and diet specialization of grasshoppers, carried out from May to November in 1974 and 1975. An edge connects a grasshopper species to a plant taxon it was found to feed on. Plants not identified to genus are labelled "Unknown Forb" with a letter. Unweighted. Nodes: `name`, `genus`, `species`, `is_herbivore`.
+- `herbivory_joern_altuda`, `herbivory_joern_marathon` (Joern 1979): grasshoppers (Orthoptera: Acrididae) and the plants they feed on, in two arid grassland communities of the Trans-Pecos region of Texas, USA, near Altuda (`altuda`) and Marathon (`marathon`), from a study of the feeding patterns and diet specialization of grasshoppers, carried out from May to November in 1974 and 1975. An edge connects a grasshopper species to a plant taxon it was found to feed on. Plants not identified to genus are labeled "Unknown Forb" with a letter. Unweighted. Nodes: `name`, `genus`, `species`, `is_herbivore`.
- `herbivory_leather_britain`, `herbivory_leather_finland` (Leather 1991): plum and cherry species (genus *Prunus*) and the macrolepidoptera (moths and butterflies) whose larvae feed on them, in Britain (`britain`) and Finland (`finland`), compiled at the scale of the whole country, from a study of the influence of host plant range and history on the diet breadth of the insects and on insect species richness. An edge connects a *Prunus* species to a lepidopteran species feeding on it. Unweighted. Nodes: `name`, `genus`, `species`, `is_herbivore` (lepidopterans).
**Seed dispersal (plant-frugivore) networks.** An edge connects a frugivore species to a plant species whose fruits it was seen eating.
-- `seed_dispersal_beehler` (Beehler 1983): fruiting plants and frugivorous birds in a forest on the southwest slopes of Mount Missim, north-northeast of Wau, Morobe Province, Papua New Guinea, observed from July 1978 to November 1980 during a study of the behaviour and ecology of four species of birds of paradise; the data cover the birds of paradise and other bird species sharing their fruit resources. The plants are identified by genus or species (some only to family), and the birds by their common names. Nodes: `name`, the common name of the bird, or the name of the plant taxon (as given in the source, with abbreviated genera such as "S. sogerensis"); `is_bird`. Edges: `count`, the number of feeding visits.
+- `seed_dispersal_beehler` (Beehler 1983): fruiting plants and frugivorous birds in a forest on the southwest slopes of Mount Missim, north-northeast of Wau, Morobe Province, Papua New Guinea, observed from July 1978 to November 1980 during a study of the behavior and ecology of four species of birds of paradise; the data cover the birds of paradise and other bird species sharing their fruit resources. The plants are identified by genus or species (some only to family), and the birds by their common names. Nodes: `name`, the common name of the bird, or the name of the plant taxon (as given in the source, with abbreviated genera such as "S. sogerensis"); `is_bird`. Edges: `count`, the number of feeding visits.
- `seed_dispersal_poulin_miconia`, `seed_dispersal_poulin_psychotria` (Poulin et al. 1999): bird-dispersed plants of the genera *Miconia* (`miconia`) and *Psychotria* (`psychotria`) and the birds eating their fruits, in the semideciduous tropical forest of Soberanía National Park, central Panama, from a study of the synchrony of fruiting phenologies of congeneric bird-dispersed plants (which also used phenological data from nearby Barro Colorado Island). The diet of the birds was determined from birds mist-netted in the national park. Nodes: `name`, `genus`, `species` (genus abbreviations of the source, such as "P. mentalis", are expanded using the full genus names given elsewhere in the file); `is_bird`. Edges: `count`, the number of fruits of the plant taken by the bird species.
-- `seed_dispersal_schleuning` (Schleuning et al. 2011): fleshy-fruited plants and the frugivorous birds and mammals feeding on them in the northern Kakamega Forest, Kenya, a tropical montane rain forest. All plant species with fleshy fruits in an area of about 250 ha were studied from December 2007 to March 2008, covering species of different forest strata (canopy, midstory and understory) and forest types (primary and secondary forest). For each plant species, two to four individuals bearing many ripe fruits were each observed once from 7:00 to 14:00 by five ornithologists, standardizing the sampling effort to 28 hours per plant species, and all fruit-eating individuals (birds and monkeys) were recorded and identified to species. The source also provides the subnetworks of each forest stratum and forest type, which can be obtained from this network with the plant properties. Nodes: `name`, the scientific name of the species; `common_name`, the English name of the frugivores (empty for plants); `code`, the abbreviation of the plant species in the source (empty for frugivores); `forest_type`, the forest type of the plant ("Prim" primary or "Sec" secondary; empty for frugivores); `stratum`, the forest stratum of the plant ("C" canopy, "M" midstory, "U" understory; empty for frugivores); `height`, the plant height in metres (NaN for frugivores); `diet`, the diet specialization of the frugivore on fruits ("Ob" obligate, "Pt" partial, "Op" opportunistic; empty for plants); `forest_dependence`, the forest dependence of the frugivore ("F" forest species, "V" visitor species; empty for plants); `is_frugivore`. Edges: `count`, the interaction frequency, the number of fruit-eating individuals of the frugivore species recorded on the plant species (regardless of whether fruits were swallowed, pecked or dropped).
+- `seed_dispersal_schleuning` (Schleuning et al. 2011): fleshy-fruited plants and the frugivorous birds and mammals feeding on them in the northern Kakamega Forest, Kenya, a tropical montane rain forest. All plant species with fleshy fruits in an area of about 250 ha were studied from December 2007 to March 2008, covering species of different forest strata (canopy, midstory and understory) and forest types (primary and secondary forest). For each plant species, two to four individuals bearing many ripe fruits were each observed once from 7:00 to 14:00 by five ornithologists, standardizing the sampling effort to 28 hours per plant species, and all fruit-eating individuals (birds and monkeys) were recorded and identified to species. The source also provides the subnetworks of each forest stratum and forest type, which can be obtained from this network with the plant properties. Nodes: `name`, the scientific name of the species; `common_name`, the English name of the frugivores (empty for plants); `code`, the abbreviation of the plant species in the source (empty for frugivores); `forest_type`, the forest type of the plant ("Prim" primary or "Sec" secondary; empty for frugivores); `stratum`, the forest stratum of the plant ("C" canopy, "M" midstory, "U" understory; empty for frugivores); `height`, the plant height in meters (NaN for frugivores); `diet`, the diet specialization of the frugivore on fruits ("Ob" obligate, "Pt" partial, "Op" opportunistic; empty for plants); `forest_dependence`, the forest dependence of the frugivore ("F" forest species, "V" visitor species; empty for plants); `is_frugivore`. Edges: `count`, the interaction frequency, the number of fruit-eating individuals of the frugivore species recorded on the plant species (regardless of whether fruits were swallowed, pecked or dropped).
- `seed_dispersal_snow` (Snow and Snow 1988): fruiting plants and the birds eating their fruits in England, from the observations reported in the book "Birds and Berries". Species listed in the source without any recorded interaction appear as isolated nodes. Nodes: `name`, the common name of the species; `genus` and `species`, the scientific genus and species names (empty for some species without them in the source); `is_bird`. Edges: `count`, the number of feeding visits.
- `seed_dispersal_sorensen` (Sorensen 1981): fruiting plants and the birds eating their fruits in Wytham Woods, near Oxford, UK, from a study of the feeding preferences of frugivorous birds in relation to the seasonality, abundance, growth form and nutritive and energetic value of the fruits. Species listed in the source without any recorded interaction appear as isolated nodes. Nodes: `name`, the common name of the species (as spelled in the source); `is_bird`. Edges: `count`, the number of feeding visits.
@@ -84,11 +84,11 @@ The networks are named `<type>_<author>`, after the kind of interaction and the
**Host-parasite networks.**
-- `host_parasite_canada_<site>` (compiled by the IWDB): freshwater fish species and their metazoan parasites in Canadian lakes and rivers in which most fish species were surveyed for parasites, from six parasitological surveys: Aishihik Lake, Yukon (`aishihik`; Arthur et al. 1976); Cold Lake, Alberta (`cold`; Leong and Holmes 1981); Lake of the Woods, Ontario (`woods`; Dechtiar 1972); the headwaters of the McGregor (`mcgregor`) and Parsnip (`parsnip`) rivers, British Columbia (Arai and Mudry 1983); Lake Huron and Manitoulin Island, Ontario (`huron`; Bangham 1955); and the Smallwood Reservoir, Labrador (`smallwood`; Chinniah and Threlfall 1978). Only fish species with at least 5 individuals examined at a locality are included, since infection levels are inaccurate for smaller samples. All internal and external metazoan parasites are considered (nematodes, acanthocephalans, cestodes, trematodes, monogeneans, leeches, copepods and branchiurans); when a species of internal worm occurred both as larva and as adult, the two forms are treated as distinct parasite nodes, since they often have different modes of transmission and infect different hosts and organs. An edge connects a fish species to a parasite found in it, with the prevalence of infection (the percentage of examined host individuals harbouring the parasite) and, for five of the localities, the mean intensity of infection (the average number of parasite individuals per host). Fish species without any recorded parasite appear as isolated nodes. Nodes: `name`, the species name (for parasites, "(L)" marks larval forms, as in the source); `genus` and `species`, the two parts of the parasite name (empty for hosts); `sample_size`, the number of host individuals examined (zero for parasites); `relative_abundance`, an independent estimate of the relative abundance of the host species, from Leong and Holmes (1981) (only in `cold`; NaN for parasites); `is_parasite`. Edges: `prevalence`, the prevalence of infection, in percent; `intensity`, the intensity of infection (NaN if not available; absent in `woods` and `huron`).
+- `host_parasite_canada_<site>` (compiled by the IWDB): freshwater fish species and their metazoan parasites in Canadian lakes and rivers in which most fish species were surveyed for parasites, from six parasitological surveys: Aishihik Lake, Yukon (`aishihik`; Arthur et al. 1976); Cold Lake, Alberta (`cold`; Leong and Holmes 1981); Lake of the Woods, Ontario (`woods`; Dechtiar 1972); the headwaters of the McGregor (`mcgregor`) and Parsnip (`parsnip`) rivers, British Columbia (Arai and Mudry 1983); Lake Huron and Manitoulin Island, Ontario (`huron`; Bangham 1955); and the Smallwood Reservoir, Labrador (`smallwood`; Chinniah and Threlfall 1978). Only fish species with at least 5 individuals examined at a locality are included, since infection levels are inaccurate for smaller samples. All internal and external metazoan parasites are considered (nematodes, acanthocephalans, cestodes, trematodes, monogeneans, leeches, copepods and branchiurans); when a species of internal worm occurred both as larva and as adult, the two forms are treated as distinct parasite nodes, since they often have different modes of transmission and infect different hosts and organs. An edge connects a fish species to a parasite found in it, with the prevalence of infection (the percentage of examined host individuals harboring the parasite) and, for five of the localities, the mean intensity of infection (the average number of parasite individuals per host). Fish species without any recorded parasite appear as isolated nodes. Nodes: `name`, the species name (for parasites, "(L)" marks larval forms, as in the source); `genus` and `species`, the two parts of the parasite name (empty for hosts); `sample_size`, the number of host individuals examined (zero for parasites); `relative_abundance`, an independent estimate of the relative abundance of the host species, from Leong and Holmes (1981) (only in `cold`; NaN for parasites); `is_parasite`. Edges: `prevalence`, the prevalence of infection, in percent; `intensity`, the intensity of infection (NaN if not available; absent in `woods` and `huron`).
**Predator-prey networks.** These are directed food webs.
-- `food_web_lafferty` (Lafferty et al. 2006): the food web of the Carpinteria Salt Marsh Reserve, Santa Barbara County, California, USA, including both free-living species and parasites, compiled by K. D. Lafferty and collaborators to study the effect of parasites on food-web topology. Nodes are taxa (species or groups of species, e.g. "Oligochaete"), basal resources such as detritus, carrion and primary producers, free-living animals, and parasites (larval and adult parasite stages, mostly trematodes and other helminths). The web consists of four subwebs: predator-prey, parasite-host, predator-parasite (predation on parasites, e.g. on free-living stages or on parasites inside eaten hosts) and parasite-parasite. The links come from a combination of published reports, direct observations, and logical but presumed interactions. A directed edge points from a resource (prey or host) to its consumer (predator or parasite), and is labelled by the type of trophic interaction, coded in the source as follows (a value N.1 marks a proposed or presumed link of type N): 1, first intermediate host (1.2: first and second intermediate host; 1.25: first and second intermediate host, with excystment outside the second intermediate host); 2, second intermediate host (2.5: second intermediate host, with an external, non-trophic cyst); 3, final host; 4, predator-prey (4.2: egg predator; 4.11 is the same as 4.1); 5, predation on free-living cercarial stage of a trematode; 6, micropredation (mosquito); 7, predation on a parasite in a host; 8, predation on a parasite in a host, with possible transmission to the predator; 9, parasite-parasite (mostly intraguild predation). This is an early version of the web, which was later updated and extended (Hechinger et al. 2011): the later version, resolved by life stage, is the network `carpinteria` of the entry `california_estuaries`, and a version of it aggregated by species is the network `carpinteria` of `coastal_parasite_webs`; this 2006 version is also included in `gateway_foodwebs`. Nodes: `name`, the name of the taxon or resource; `kind`, whether it is a basal resource ("Basal"), a free-living species ("Freeliving") or a parasite ("Parasite"); `group`, a one-letter taxonomic group code given in the source (not explained there, but apparently: "D" detritus, "K" carrion, "P" primary producers, "A" annelids, "B" birds, "C" crustaceans, "F" fishes, "G" gastropods, "I" insects, "V" bivalves, "R" mammals (raccoon), "L" leeches, "N" nematodes, "T" trematodes, "W" cestodes, "O" other parasites). Edges: `link_type`, the code of the type of interaction (see above).
+- `food_web_lafferty` (Lafferty et al. 2006): the food web of the Carpinteria Salt Marsh Reserve, Santa Barbara County, California, USA, including both free-living species and parasites, compiled by K. D. Lafferty and collaborators to study the effect of parasites on food-web topology. Nodes are taxa (species or groups of species, e.g. "Oligochaete"), basal resources such as detritus, carrion and primary producers, free-living animals, and parasites (larval and adult parasite stages, mostly trematodes and other helminths). The web consists of four subwebs: predator-prey, parasite-host, predator-parasite (predation on parasites, e.g. on free-living stages or on parasites inside eaten hosts) and parasite-parasite. The links come from a combination of published reports, direct observations, and logical but presumed interactions. A directed edge points from a resource (prey or host) to its consumer (predator or parasite), and is labeled by the type of trophic interaction, coded in the source as follows (a value N.1 marks a proposed or presumed link of type N): 1, first intermediate host (1.2: first and second intermediate host; 1.25: first and second intermediate host, with excystment outside the second intermediate host); 2, second intermediate host (2.5: second intermediate host, with an external, non-trophic cyst); 3, final host; 4, predator-prey (4.2: egg predator; 4.11 is the same as 4.1); 5, predation on free-living cercarial stage of a trematode; 6, micropredation (mosquito); 7, predation on a parasite in a host; 8, predation on a parasite in a host, with possible transmission to the predator; 9, parasite-parasite (mostly intraguild predation). This is an early version of the web, which was later updated and extended (Hechinger et al. 2011): the later version, resolved by life stage, is the network `carpinteria` of the entry `california_estuaries`, and a version of it aggregated by species is the network `carpinteria` of `coastal_parasite_webs`; this 2006 version is also included in `gateway_foodwebs`. Nodes: `name`, the name of the taxon or resource; `kind`, whether it is a basal resource ("Basal"), a free-living species ("Freeliving") or a parasite ("Parasite"); `group`, a one-letter taxonomic group code given in the source (not explained there, but apparently: "D" detritus, "K" carrion, "P" primary producers, "A" annelids, "B" birds, "C" crustaceans, "F" fishes, "G" gastropods, "I" insects, "V" bivalves, "R" mammals (raccoon), "L" leeches, "N" nematodes, "T" trematodes, "W" cestodes, "O" other parasites). Edges: `link_type`, the code of the type of interaction (see above).
- `food_web_thompson_<stream>` (Thompson and Townsend 2003, and related studies): 26 food webs of streams in New Zealand and in Maine and North Carolina (USA), compiled by R. M. Thompson, C. R. Townsend and collaborators in a series of studies on the effects of land use (e.g. native versus exotic forest), disturbance, resource supply, taxonomic resolution and season on stream food web structure. Nodes are taxa (algae, aquatic invertebrates, mostly insects, and fish), and a directed edge $(i, j)$ indicates that taxon $j$ feeds on taxon $i$. Each network is named after the stream; some streams were sampled in several seasons, indicated by the suffixes `Sp` (spring), `Su` (summer) and `Au` (autumn), and `AkatoreA` and `AkatoreB` are two webs from the Akatore stream. The IWDB distributes these data as binary interaction matrices without taxon names, so the networks carry no node metadata. Ten of the New Zealand webs (Blackrock, Broad, Canton, Dempsters, German, Healy, Kyeburn, LilKyeburn, Stony and Sutton) are also contained in `gateway_foodwebs` (as Townsend et al. 1998), with taxon names and the same or nearly the same number of links."""
tags = ['Biological', 'Food web', 'Weighted', 'Unweighted', 'Metadata', 'Multilayer']
url = ['https://iwdb.nceas.ucsb.edu/',
[entries] Merge duplicate entries and add cross-references between related ones 9bc6033
- Removed duplicates, merged into the entries holding the same data: dblp_coauthor_snap (soc_net_comms), cattle and bison (dom; bison's breeding data move there, as do the wolves' age and sex), football_tsevans (football, with both conference assignments), eu_procurements_alt (eu_procurements), foursquare_friendships (foursquare_global). - software_dependencies: colt and scolt are one network; ambassador: the duplicate 2001 network is dropped and the three same-edge networks combined; dom: the dataset count corrected (436). - macaque_neural: Young's 71-area network added (young71; the 47-area one is now cocomac47), both from archived copies. - collins_yeast, celegans_interactomes: from archived copies of the dead CCSB site (byte-identical files). - Cross-references between entries holding versions of the same data (food webs, Wikipedia, Slashdot, physicians, SNAP/Mislove, CCSB). - ICON ids of duplicate records added; macaque_neural's corrected. - prosper, dbpedia_all: string properties given in edge-index order (needs graph-tool with the fixed vals ordering).
diff --git a/entries/iwdb/__init__.py b/entries/iwdb/__init__.py
index 9a71602..fac8ff1 100644
--- a/entries/iwdb/__init__.py
+++ b/entries/iwdb/__init__.py
@@ -88,8 +88,8 @@ The networks are named `<type>_<author>`, after the kind of interaction and the
**Predator-prey networks.** These are directed food webs.
-- `food_web_lafferty` (Lafferty et al. 2006): the food web of the Carpinteria Salt Marsh Reserve, Santa Barbara County, California, USA, including both free-living species and parasites, compiled by K. D. Lafferty and collaborators to study the effect of parasites on food-web topology. Nodes are taxa (species or groups of species, e.g. "Oligochaete"), basal resources such as detritus, carrion and primary producers, free-living animals, and parasites (larval and adult parasite stages, mostly trematodes and other helminths). The web consists of four subwebs: predator-prey, parasite-host, predator-parasite (predation on parasites, e.g. on free-living stages or on parasites inside eaten hosts) and parasite-parasite. The links come from a combination of published reports, direct observations, and logical but presumed interactions. A directed edge points from a resource (prey or host) to its consumer (predator or parasite), and is labelled by the type of trophic interaction, coded in the source as follows (a value N.1 marks a proposed or presumed link of type N): 1, first intermediate host (1.2: first and second intermediate host; 1.25: first and second intermediate host, with excystment outside the second intermediate host); 2, second intermediate host (2.5: second intermediate host, with an external, non-trophic cyst); 3, final host; 4, predator-prey (4.2: egg predator; 4.11 is the same as 4.1); 5, predation on free-living cercarial stage of a trematode; 6, micropredation (mosquito); 7, predation on a parasite in a host; 8, predation on a parasite in a host, with possible transmission to the predator; 9, parasite-parasite (mostly intraguild predation). This is an early version of the web, which was later updated and extended (Hechinger et al. 2011). Nodes: `name`, the name of the taxon or resource; `kind`, whether it is a basal resource ("Basal"), a free-living species ("Freeliving") or a parasite ("Parasite"); `group`, a one-letter taxonomic group code given in the source (not explained there, but apparently: "D" detritus, "K" carrion, "P" primary producers, "A" annelids, "B" birds, "C" crustaceans, "F" fishes, "G" gastropods, "I" insects, "V" bivalves, "R" mammals (raccoon), "L" leeches, "N" nematodes, "T" trematodes, "W" cestodes, "O" other parasites). Edges: `link_type`, the code of the type of interaction (see above).
-- `food_web_thompson_<stream>` (Thompson and Townsend 2003, and related studies): 26 food webs of streams in New Zealand and in Maine and North Carolina (USA), compiled by R. M. Thompson, C. R. Townsend and collaborators in a series of studies on the effects of land use (e.g. native versus exotic forest), disturbance, resource supply, taxonomic resolution and season on stream food web structure. Nodes are taxa (algae, aquatic invertebrates, mostly insects, and fish), and a directed edge $(i, j)$ indicates that taxon $j$ feeds on taxon $i$. Each network is named after the stream; some streams were sampled in several seasons, indicated by the suffixes `Sp` (spring), `Su` (summer) and `Au` (autumn), and `AkatoreA` and `AkatoreB` are two webs from the Akatore stream. The IWDB distributes these data as binary interaction matrices without taxon names, so the networks carry no node metadata."""
+- `food_web_lafferty` (Lafferty et al. 2006): the food web of the Carpinteria Salt Marsh Reserve, Santa Barbara County, California, USA, including both free-living species and parasites, compiled by K. D. Lafferty and collaborators to study the effect of parasites on food-web topology. Nodes are taxa (species or groups of species, e.g. "Oligochaete"), basal resources such as detritus, carrion and primary producers, free-living animals, and parasites (larval and adult parasite stages, mostly trematodes and other helminths). The web consists of four subwebs: predator-prey, parasite-host, predator-parasite (predation on parasites, e.g. on free-living stages or on parasites inside eaten hosts) and parasite-parasite. The links come from a combination of published reports, direct observations, and logical but presumed interactions. A directed edge points from a resource (prey or host) to its consumer (predator or parasite), and is labelled by the type of trophic interaction, coded in the source as follows (a value N.1 marks a proposed or presumed link of type N): 1, first intermediate host (1.2: first and second intermediate host; 1.25: first and second intermediate host, with excystment outside the second intermediate host); 2, second intermediate host (2.5: second intermediate host, with an external, non-trophic cyst); 3, final host; 4, predator-prey (4.2: egg predator; 4.11 is the same as 4.1); 5, predation on free-living cercarial stage of a trematode; 6, micropredation (mosquito); 7, predation on a parasite in a host; 8, predation on a parasite in a host, with possible transmission to the predator; 9, parasite-parasite (mostly intraguild predation). This is an early version of the web, which was later updated and extended (Hechinger et al. 2011): the later version, resolved by life stage, is the network `carpinteria` of the entry `california_estuaries`, and a version of it aggregated by species is the network `carpinteria` of `coastal_parasite_webs`; this 2006 version is also included in `gateway_foodwebs`. Nodes: `name`, the name of the taxon or resource; `kind`, whether it is a basal resource ("Basal"), a free-living species ("Freeliving") or a parasite ("Parasite"); `group`, a one-letter taxonomic group code given in the source (not explained there, but apparently: "D" detritus, "K" carrion, "P" primary producers, "A" annelids, "B" birds, "C" crustaceans, "F" fishes, "G" gastropods, "I" insects, "V" bivalves, "R" mammals (raccoon), "L" leeches, "N" nematodes, "T" trematodes, "W" cestodes, "O" other parasites). Edges: `link_type`, the code of the type of interaction (see above).
+- `food_web_thompson_<stream>` (Thompson and Townsend 2003, and related studies): 26 food webs of streams in New Zealand and in Maine and North Carolina (USA), compiled by R. M. Thompson, C. R. Townsend and collaborators in a series of studies on the effects of land use (e.g. native versus exotic forest), disturbance, resource supply, taxonomic resolution and season on stream food web structure. Nodes are taxa (algae, aquatic invertebrates, mostly insects, and fish), and a directed edge $(i, j)$ indicates that taxon $j$ feeds on taxon $i$. Each network is named after the stream; some streams were sampled in several seasons, indicated by the suffixes `Sp` (spring), `Su` (summer) and `Au` (autumn), and `AkatoreA` and `AkatoreB` are two webs from the Akatore stream. The IWDB distributes these data as binary interaction matrices without taxon names, so the networks carry no node metadata. Ten of the New Zealand webs (Blackrock, Broad, Canton, Dempsters, German, Healy, Kyeburn, LilKyeburn, Stony and Sutton) are also contained in `gateway_foodwebs` (as Townsend et al. 1998), with taxon names and the same or nearly the same number of links."""
tags = ['Biological', 'Food web', 'Weighted', 'Unweighted', 'Metadata', 'Multilayer']
url = ['https://iwdb.nceas.ucsb.edu/',
'https://iwdb.nceas.ucsb.edu/html/arroyo_1982.html',
[entries] Merge the IWDB data sets into a single entry, iwdb 139182c
All the data sets of the Interaction Web Database become networks of one entry (115 networks, identical to the ones of the former entries), which replaces fresh_webs, plant_pol_kato, plant_pol_robertson and plant_pol_vazquez; the API page's example now uses iwdb/food_web_thompson_AkatoreA.
diff --git a/entries/iwdb/__init__.py b/entries/iwdb/__init__.py
new file mode 100644
index 0000000..9a71602
--- /dev/null
+++ b/entries/iwdb/__init__.py
@@ -0,0 +1,1625 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# 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
+# 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/>.
+
+from .. import *
+from openpyxl import load_workbook
+import pandas
+import re
+import shutil
+import subprocess
+import tempfile
+
+title = "Interaction Web Database (IWDB) ecological networks (1923-2011)"
+description = r"""A collection of ecological interaction networks from the Interaction Web Database (IWDB), a nonprofit, cooperative database of published data on species interaction networks, hosted for many years by the National Center for Ecological Analysis and Synthesis (NCEAS) at the University of California, Santa Barbara, USA, and since December 2020 by the Department of Ecology of the University of São Paulo, Brazil. The IWDB compiles data sets from the literature on several kinds of interactions: plant-pollinator, plant-ant, plant-herbivore, seed dispersal (plant-frugivore), anemone-fish, host-parasite and predator-prey. Each data set is documented on its own IWDB page (with the location, the type of data and the source), and is distributed as an interaction matrix, mostly as Excel spreadsheets with the species lists. The IWDB states that its data sets are freely available and reusable. This entry includes one or more networks for each of the IWDB data sets described below, from studies published between 1923 and 2011; since the IWDB server refuses automated requests, the files are obtained from snapshots of the Internet Archive.
+
+The networks are named `<type>_<author>`, after the kind of interaction and the first author of the source, followed by `_<variant>` for data sets with several networks (sites, years, plots, etc.). Except for the two predator-prey data sets, the networks are bipartite and undirected, with the nodes of one kind marked by a boolean vertex property `is_<kind>` (e.g. `is_pollinator`). Unless stated otherwise, nodes have a `name` property, the taxon name (genus and species as given in the source, where "sp." denotes an unidentified species and "sp. 1" etc. a morphospecies), with `genus` and `species` the two parts of the name; for weighted networks, the edge property `count` is the number of observations given in the source (e.g. visits, or individuals caught). Unweighted networks record only the presence of an interaction.
+
+**Plant-pollinator networks.** An edge connects a plant species to an animal species recorded visiting its flowers. Many studies caught the flower visitors on the flowers of each plant species, in which case `count` is the number of individuals caught, a rough estimate of the level of visitation.
+
+- `pollination_arroyo_I`, `pollination_arroyo_II`, `pollination_arroyo_III` (Arroyo et al. 1982): plants and insect flower visitors in the high Andes of central Chile (Cordón del Cepo), from a community-level study of pollination mechanisms and how they change with altitude; one network for each of the three elevation levels of the study, each with its own set of species. Unweighted. Nodes: `name`, `genus`, `species` (with morphospecies labels such as "sp. 1" or "n.i." for unidentified taxa), `is_pollinator`.
+- `pollination_barrett` (Barrett and Helenurm 1987): understory herbs and their insect flower visitors in the boreal forest of central New Brunswick, Canada, observed from May to September of 1978, 1979 and 1980, in a study of the breeding systems, pollination biology and phenology of boreal forest herbs. Nodes: `name`, `genus`, `species`, `is_pollinator`. Edges: `count`, the number of insect individuals caught on the flowers of the plant species.
+- `pollination_bartomeus_<plot>` (Bartomeus et al. 2008): twelve quantitative networks of plants and insect flower visitors in Mediterranean shrublands of the Natural Park of Cap de Creus, Catalonia, Spain, from a study of how two invasive plants with large, showy flowers, *Carpobrotus* affine *acinaciformis* and *Opuntia stricta*, affect the structure of plant-pollinator networks. Plots of 50 x 50 m, at least 300 m apart, were either invaded or not by one of the invaders; they were sampled every two weeks during the flowering period of the invader (April to June for *Carpobrotus* and June to July for *Opuntia*), and each plant species was observed for 6 minutes per sampling round, with the flower visitors collected. Each network corresponds to one plot, named with the code of the source, made of a site abbreviation, a plot number, and the invasive species of the site (`CA` for *Carpobrotus*, `OP` for *Opuntia*); the source does not indicate which plots are invaded. (Two records with plot codes "SEL10P" and "SEL1P", evidently misspellings of "SEL1OP", are included in that plot.) Plant species without any visits are not included. Nodes: `name`, the taxon name (species, genus, or a morphospecies code, as given in the source, where "?" marks an identification that is not verified); `code`, the plant or insect identifier in the source (the same name may correspond to several insect morphospecies); `family`, the taxonomic family (as spelled in the source); `order`, the insect order (empty for plants); `is_pollinator`. Edges: `visits`, the total number of visits over all sampling rounds; `rounds`, the number of sampling rounds in which the interaction was recorded.
+- `pollination_bezerra` (Bezerra et al. 2009): oil-flowers of the family Malpighiaceae and the oil-collecting bees visiting them in the caatinga (a semi-arid vegetation) of the Parque Nacional do Catimbau, Pernambuco State, Brazil. Bee visits were recorded on 138 individual plants in natural clumps of 13 Malpighiaceae species during the flowering peak of each species, over four consecutive days from 5:00 to 17:00, for a total of 1392 h of observation. Nodes: `name`, the species name; `is_pollinator` (bees). Edges: `count`, the number of visits.
+- `pollination_clements` (Clements and Long 1923): plants and their insect flower visitors on Pikes Peak, Colorado, USA, from the observations of F. E. Clements and F. L. Long in the early 1920s, published in their book on experimental pollination, with the insect visitors of 96 plant species (94 native and two exotic). Unweighted. Nodes: `name`, `genus`, `species`; `code`, the short code of the flower visitor in the source (empty for plants); `is_pollinator`.
+- `pollination_dupont` (Dupont et al. 2003): plants and all flower-visiting animals in the high-altitude sub-alpine desert of Las Cañadas, Tenerife, Canary Islands. Unweighted. Nodes: `name`, `genus`, `species`; `origin`, the biogeographic status of the species as coded in the source ("end" for endemic, "nat" for native, "int" for introduced); `is_pollinator`.
+- `pollination_elberling` (Elberling and Olesen 1999): plants and their insect flower visitors in the subarctic alpine zone of Latnjajaure, northern Sweden, observed from 21 May to 23 August 1994, in a study of the structure of a high-latitude plant-flower visitor system and of the role of flies as flower visitors. All insects found on flowers were counted as flower visitors, whether they foraged for nectar or pollen or were sun-basking. Nodes: `name`, `genus`, `species`, `is_pollinator`. Edges: `count`, the number of visits.
+- `pollination_hocking` (Hocking 1968): plants and their flower visitors (insects, and also spiders and mites) on Ellesmere Island, Northwest Territories (now Nunavut), Canada, from a study of the composition of the assemblage of flower visitors in the high Arctic and its relationship to nectar production. Unweighted. Nodes: `name`, `genus`, `species` (or a higher taxon such as a family when not identified further), `is_pollinator`.
+- `pollination_inouye` (Inouye and Pyke 1988): alpine plants and their insect flower visitors in Kosciusko National Park, Snowy Mountains, New South Wales, Australia, observed from December 1983 to March 1984, in a community-level study of alpine pollination biology compared with montane Colorado, USA. The source lists 20 further plant species without any visitation data; they are not included. Nodes: `name`, `genus`, `species` (some insects are distinguished by sex); `order`, the insect order (Diptera, Hymenoptera or Lepidoptera; empty for plants); `is_pollinator`. Edges: `count`, the number of insect individuals caught on the flowers of the plant species.
+- `pollination_kaiser_bunbury_control`, `pollination_kaiser_bunbury_restored` (Kaiser-Bunbury et al. 2009, 2010): quantitative networks of plants and their flower visitors (insects, birds and lizards) in the upland heathland of Mauritius, comparing an area heavily invaded by introduced plant species (`control`) with an area from which the non-native plants had been removed (`restored`). Interactions were recorded by static observations ("sit-and-observe") of flowers, with varying numbers of flowers and observation times; to account for these differences, visitation rates were computed as visits per flower per hour and averaged over the total observation time. For each edge, the visitation rate and the interaction strength (which in addition accounts for the floral abundance of the plant at the site) are given; a few interactions have a nonzero value in only one of the two matrices of the source. Plant species without any recorded visit appear as isolated nodes. Nodes: `name`, the species name (for animals with the authority, as given in the source); `family`, the taxonomic family; `origin`, the origin of the species as a numeric code (the codes are not explained in the data file); `flower_colour` and `flower_category`, numeric codes for the flower colour and flower type of the plants (not explained in the data file; zero for animals); `floral_abundance`, the floral abundance of the plants at the site (zero for animals); `probed_flowers`, the number of flowers probed by the animal species (zero for plants); `is_pollinator`. Edges: `visitation_rate`, the visitation rate (visits per flower per hour); `interaction_strength`, the interaction strength.
+- `pollination_kato` (Kato et al. 1990): plants and flower-visiting insect species (or morphospecies) in the primary beech forest of the Kyoto University Forest of Ashu, at the northeastern boundary of Kyoto Prefecture, Japan, studied by M. Kato, T. Makutani, T. Inoue and T. Itino between 1984 and 1987; the study recorded the flowering phenology of 91 plant species and collected the insects visiting their flowers. An edge connects an insect to a plant on whose flowers it was caught. Nodes: `is_pollinator`, whether the node is an insect (otherwise a plant); `idx`, the index of the species in the source matrix; `pol_ge_sp`, the name of the insect species, followed by abbreviations of its family and order in parentheses (as in "Actina jezoensis (Str. : Dip. )"; empty for plants); `plant_ge`, `plant_sp`, the genus and species of the plant (empty for insects). Edges: `count`, the number of individuals of the insect species collected on the plant species.
+- `pollination_kevan` (Kevan 1970): plants and the arthropods visiting their flowers at Hazen Camp, near Lake Hazen on northern Ellesmere Island (81°49'N, 71°18'W), in the Canadian high Arctic, observed in 1967 for P. G. Kevan's PhD thesis on the importance of insect-flower relations for arctic plants and insects. For some interactions the source gives only a qualitative indication instead of a number ("few", "several", "many", "eggs", or "?"). The willow *Salix arctica* is split into three nodes, for its staminate, pistillate and undetermined catkins. Nodes: `name`, `genus`, `species` (or a higher taxon such as a family when not identified further), `is_pollinator`. Edges: `count`, the number of individuals caught (NaN if only a qualitative indication is given); `note`, the qualitative indication given instead of a number (empty otherwise).
+- `pollination_mcmullen` (McMullen 1993): plants and their insect flower visitors in the Galápagos Islands, compiled by C. K. McMullen from records of plant-flower visitor interactions in the literature, together with a field study on Pinta Island of the flower visitors of six plant species (the IWDB spells the author's name "McCullen"). Unweighted. Nodes: `name`, `genus`, `species` (or a higher group such as "Beetles" when not identified further), `is_pollinator`.
+- `pollination_medan_LD`, `pollination_medan_RB` (Medan et al. 2002): plants and their flower visitors at two sites at different altitudes in the Andes of Mendoza, Argentina: Laguna del Diamante (`LD`, xeric scrub) and Río Blanco (`RB`, woody riverine vegetation and xeric scrub), from a study comparing the structure of plant-pollinator networks between altitudes. Unweighted. Nodes: `name`, the scientific name of the taxon (for plants with the authority, for flower visitors a species or morphospecies name, as given in the source); `family`, the taxonomic family (given for all plants but only for some flower visitors); `order`, the order of the flower visitor, as a code (e.g. "D" for Diptera; given only for some flower visitors); `code`, the code of the species in the source (a number for plants, letters for flower visitors); `is_pollinator`.
+- `pollination_memmott` (Memmott 1999): plants and their insect flower visitors in a 150 x 250 m meadow plot near Bristol, UK, observed in July 1997, in a study of the structure of a plant-pollinator web that took into account the abundances of the species and the frequency of their interactions. The insects are identified only by a number and their order in the source. Nodes: `name`, the common name of the plant, or, for insects, their order code and number (e.g. "DIP 31"); `code`, the number of the plant or insect in the source; `order`, the insect order as coded in the source ("COL" Coleoptera, "DIP" Diptera, "HY" Hymenoptera, "L" Lepidoptera; empty for plants); `is_pollinator`. Edges: `count`, the number of visits.
+- `pollination_mosquin` (Mosquin and Martin 1967): plants and their insect flower visitors on Melville Island, Northwest Territories (now Nunavut), Canada, observed from 19 to 31 July 1965, while the authors collected plants and made observations on flower-visiting insects and on the scent and other attractive features of the flowers. Nodes: `name`, `genus`, `species`, `is_pollinator`. Edges: `count`, the number of insect individuals caught on the flowers of the plant species.
+- `pollination_motten` (Motten 1982, 1986): spring-flowering plants (herbs, shrubs and understory trees pollinated by insects) and their insect flower visitors in the deciduous forests of the piedmont of North Carolina, USA. Nodes: `name`, `genus`, `species` (for some bees the subgenus is given in parentheses); `code`, the abbreviation of the plant in the source (empty for insects); `is_pollinator`. Edges: `count`, the number of visits.
+- `pollination_olesen_aigrettes`, `pollination_olesen_flores` (Olesen et al. 2002): plants and their flower visitors on two oceanic islands, Ile aux Aigrettes (`aigrettes`), a small island off Mauritius with coastal forest, and Flores in the Azores (`flores`), with rocky cliff and open herb vegetation, from a study of the invasion of island pollination networks by introduced species. The visitors are insects, and on Ile aux Aigrettes also a gecko. Nodes: `name`, `genus`, `species`; `origin`, the status of the species on the island as coded in the source ("end" for endemic, "nat" for native, "intr" for introduced); `is_pollinator`. Edges: `count`, the number of visits.
+- `pollination_ollerton` (Ollerton et al. 2003): nine asclepiads (milkweeds, Apocynaceae: Asclepiadoideae) and their flower visitors at an upland grassland site in KwaZulu-Natal, South Africa, studied during three months of fieldwork, which documented, among others, pollination by fruit chafers and by pompilid wasps. Flower visitors were observed and/or caught on each plant species. (A note in the source states that bold cells mark insects found carrying pollinaria, but this formatting is not present in the distributed file.) Nodes: `name`, `genus`, `species` (or a morphospecies or higher group); `authority`, the taxonomic authority of the insect species (when given); `order`, the insect order (empty for plants); `is_pollinator`. Edges: `count`, the number of insect individuals observed or caught.
+- `pollination_ramirez` (Ramirez and Brito 1992): plants and their flower visitors (insects and hummingbirds) in a "morichal", a palm swamp community dominated by *Mauritia flexuosa*, in the central plains of Guárico State, Venezuela, from field observations made in 1983, 1984 and 1989, in a study of the floral biology and pollination spectrum of the community. Five plant species (sedges and grasses) are listed without any recorded visitor, and appear as isolated nodes. Nodes: `name`, `genus`, `species`, `is_pollinator`. Edges: `pollen_load`, whether the visitors were found carrying a pollen load of the plant (value 1 in the source matrix, as opposed to 2; the interactions with a pollen load form what the source calls the pollination matrix).
+- `pollination_robertson` (Robertson 1929): plants and their flower visitors, compiled by the naturalist C. Robertson, who recorded, over several decades around the turn of the 20th century, the animal species visiting the flowers of the plants that grew in a small area around Carlinville, in southwestern Illinois, USA (his methods are described by J. C. Marlin and W. E. LaBerge, Conserv. Ecol. 5, 2001). There are 456 plant species and 1,428 flower-visiting animal species (mostly bees and other insects, and a few birds). Unweighted; the source lists ten plant-visitor pairs twice, which appear as parallel edges. Nodes: `name`, the species name; `family`, the family of the species; `order`, the order of the animal (or "Aves" for birds; empty for plants); `is_pollinator`.
+- `pollination_santos` (Santos et al. 2010): plants and the social bees and social wasps visiting them for nectar in the caatinga at Itatim, Bahia State, Brazil (12°42'S, 39°46'W). Samples were collected monthly from November 1996 to November 1997 along a transect 3 km long and 20 m wide, where two collectors inspected each flowering plant for 5 minutes and caught the flower-visiting bees and wasps with entomological nets; only legitimate visitors were considered. The plants are identified only by codes, which are listed in an appendix of the paper. Unweighted. Nodes: `name`, the species name of the bee or wasp, or the code of the plant; `group`, "wasp" or "bee" for the flower visitors (empty for plants); `is_pollinator`.
+- `pollination_schemske` (Schemske et al. 1978): seven early-flowering, low-growing perennial woodland herbs and their insect flower visitors in Brownfield Woods, a 24 ha maple-oak woodland near Urbana, Illinois, USA. The sequence and variety of flowers visited by individual insects were recorded for the first foraging insect observed in randomly selected 1 m² quadrats within a 10 x 10 m grid. Nodes: `name`, `genus`, `species`, `is_pollinator`. Edges: `count`, the number of visits.
+- `pollination_small` (Small 1976): the major insect-pollinated plants of the Mer Bleue peat bog near Ottawa, Canada, and their insect flower visitors, observed in 1973 in a preliminary evaluation of the pollination relationships in the bog. Nodes: `name`, `genus`, `species`, `is_pollinator`. Edges: `count`, the number of insect individuals caught on the flowers of the plant species.
+- `pollination_vazquez_<site>` (Vázquez and Simberloff 2003): plants and their flower visitors from eight forest sites dominated by *Nothofagus dombeyi*, in and around Nahuel Huapi National Park, Río Negro, Argentina, studied from September 1999 to February 2000. Four of the sites were grazed by introduced cattle and four were not, and the study analyzed the effects of this disturbance on plants, pollinators and their interactions. There is one network for each site (`Llao_Llao`, `Cerro_Lopez`, `Safariland`, `Arroyo_Goye`, `Mascardi_nc`, `Mascardi_c`, `Quetrihue_nc`, `Quetrihue_c`, where "nc" and "c" are the parts of the site without and with cattle), plus `All_sites_pooled`, which aggregates all sites. All of them share the same set of nodes (all plant and visitor species of the study, including species that are isolated at a given site), and an edge connects a visitor species to a plant species whose flowers it visited, weighted by the interaction frequency; according to the IWDB, the weights are the number of visits, while the source spreadsheet labels the matrices as "effective visitation frequency (Matrix 1*Table A4.1)". Nodes: `is_pollinator`, whether the node is a flower visitor (otherwise a plant); `idx`, the species number in the source data; `Family`, the family of the species; `Plant species`, `Common name`, `Life form`, `Origin`: for plants, the species name, the local common name, the life form (e.g. herb, shrub, understory tree), and its origin ("Native" or "Exotic"); `Order`, `Species name`, `Catalog number`: for visitors, the order, the species name (or "—" if not identified to species), and the catalog number of the specimen. Edges: `count`, the interaction frequency.
+
+**Plant-ant networks.**
+
+- `ant_plant_bluthgen` (Blüthgen et al. 2004): ants and the plants whose nectaries they attend, in the rainforest at the Australian Canopy Crane site in Cape Tribulation, Far North Queensland, Australia (16°07'S, 145°27'E, 80 m a.s.l.), and in adjacent forests within 5 km of the crane, including patches of open secondary forest. Ant colonies attending extrafloral nectaries (EFN) and floral nectaries (FN) of plants were recorded, and an edge connects an ant species to a plant nectary type, weighted by the number of ant individuals of the species collected on the plant species. Plant species with both kinds of nectaries are represented by two nodes, one for each nectary type. The data also include independent abundance estimates of the ant species from sugar-bait experiments (Blüthgen and Fiedler 2004) and of the plants. Nodes: `name`, the species name; `family`, the plant family, or `subfamily`, the ant subfamily (each empty for the other kind of node); `nectaries`, the nectary type of the plant node ("EFN" extrafloral, "FN" floral; empty for ants); `life_form`, the life form of the plant ("cl" climber, "he" herb, "sh" shrub, "tr" tree, "pa" palm; empty for ants); `abundance`, for ants the abundance of colonies estimated from sugar-bait experiments (zero for ants not recorded at the baits), and for plants the number of plant individuals on whose nectaries any insect was recorded; `is_ant`. Edges: `count`, the number of ant individuals collected.
+- `ant_plant_davidson` (Davidson et al. 1989): ants and eight myrmecophytes (plants housing ant colonies) in the tropical moist forests of western Amazonia, Peru, surveyed in September, October and November of 1985 and 1986, in a study of the variation in the ant associates of the myrmecophytes, of competition among ants for host plants and of the significance of plant trichomes. Species listed in the source without any recorded association appear as isolated nodes. Nodes: `name`, `genus`, `species`, `is_ant`. Edges: `count`, the number of recorded associations, as given in the source.
+- `ant_plant_davidson_fisher` (Davidson and Fisher 1991): six *Cecropia* trees and the four ant species inhabiting them, from a study of the symbiosis of ants with *Cecropia* as a function of the light regime, in which the authors discuss how different kinds of asymmetry in specialization lead to different forms of coevolution. Nodes: `name`, `genus`, `species`, `is_ant`. Edges: `count`, the number of recorded associations, as given in the source.
+- `ant_plant_fonseca` (Fonseca and Ganade 1996): ants and myrmecophytes in the Central Amazonian rainforest north of Manaus, Amazonas, Brazil, studied from June to August 1990, to describe the ant-myrmecophyte matrix quantitatively, search for patterns of compartmentalization, and compare the ant-plant system with other mutualistic systems. Ants not identified to species are labelled with letter codes. Nodes: `name`, `genus`, `species`, `is_ant`. Edges: `count`, the number of recorded associations, as given in the source.
+
+**Plant-herbivore networks.**
+
+- `herbivory_joern_altuda`, `herbivory_joern_marathon` (Joern 1979): grasshoppers (Orthoptera: Acrididae) and the plants they feed on, in two arid grassland communities of the Trans-Pecos region of Texas, USA, near Altuda (`altuda`) and Marathon (`marathon`), from a study of the feeding patterns and diet specialization of grasshoppers, carried out from May to November in 1974 and 1975. An edge connects a grasshopper species to a plant taxon it was found to feed on. Plants not identified to genus are labelled "Unknown Forb" with a letter. Unweighted. Nodes: `name`, `genus`, `species`, `is_herbivore`.
+- `herbivory_leather_britain`, `herbivory_leather_finland` (Leather 1991): plum and cherry species (genus *Prunus*) and the macrolepidoptera (moths and butterflies) whose larvae feed on them, in Britain (`britain`) and Finland (`finland`), compiled at the scale of the whole country, from a study of the influence of host plant range and history on the diet breadth of the insects and on insect species richness. An edge connects a *Prunus* species to a lepidopteran species feeding on it. Unweighted. Nodes: `name`, `genus`, `species`, `is_herbivore` (lepidopterans).
+
+**Seed dispersal (plant-frugivore) networks.** An edge connects a frugivore species to a plant species whose fruits it was seen eating.
+
+- `seed_dispersal_beehler` (Beehler 1983): fruiting plants and frugivorous birds in a forest on the southwest slopes of Mount Missim, north-northeast of Wau, Morobe Province, Papua New Guinea, observed from July 1978 to November 1980 during a study of the behaviour and ecology of four species of birds of paradise; the data cover the birds of paradise and other bird species sharing their fruit resources. The plants are identified by genus or species (some only to family), and the birds by their common names. Nodes: `name`, the common name of the bird, or the name of the plant taxon (as given in the source, with abbreviated genera such as "S. sogerensis"); `is_bird`. Edges: `count`, the number of feeding visits.
+- `seed_dispersal_poulin_miconia`, `seed_dispersal_poulin_psychotria` (Poulin et al. 1999): bird-dispersed plants of the genera *Miconia* (`miconia`) and *Psychotria* (`psychotria`) and the birds eating their fruits, in the semideciduous tropical forest of Soberanía National Park, central Panama, from a study of the synchrony of fruiting phenologies of congeneric bird-dispersed plants (which also used phenological data from nearby Barro Colorado Island). The diet of the birds was determined from birds mist-netted in the national park. Nodes: `name`, `genus`, `species` (genus abbreviations of the source, such as "P. mentalis", are expanded using the full genus names given elsewhere in the file); `is_bird`. Edges: `count`, the number of fruits of the plant taken by the bird species.
+- `seed_dispersal_schleuning` (Schleuning et al. 2011): fleshy-fruited plants and the frugivorous birds and mammals feeding on them in the northern Kakamega Forest, Kenya, a tropical montane rain forest. All plant species with fleshy fruits in an area of about 250 ha were studied from December 2007 to March 2008, covering species of different forest strata (canopy, midstory and understory) and forest types (primary and secondary forest). For each plant species, two to four individuals bearing many ripe fruits were each observed once from 7:00 to 14:00 by five ornithologists, standardizing the sampling effort to 28 hours per plant species, and all fruit-eating individuals (birds and monkeys) were recorded and identified to species. The source also provides the subnetworks of each forest stratum and forest type, which can be obtained from this network with the plant properties. Nodes: `name`, the scientific name of the species; `common_name`, the English name of the frugivores (empty for plants); `code`, the abbreviation of the plant species in the source (empty for frugivores); `forest_type`, the forest type of the plant ("Prim" primary or "Sec" secondary; empty for frugivores); `stratum`, the forest stratum of the plant ("C" canopy, "M" midstory, "U" understory; empty for frugivores); `height`, the plant height in metres (NaN for frugivores); `diet`, the diet specialization of the frugivore on fruits ("Ob" obligate, "Pt" partial, "Op" opportunistic; empty for plants); `forest_dependence`, the forest dependence of the frugivore ("F" forest species, "V" visitor species; empty for plants); `is_frugivore`. Edges: `count`, the interaction frequency, the number of fruit-eating individuals of the frugivore species recorded on the plant species (regardless of whether fruits were swallowed, pecked or dropped).
+- `seed_dispersal_snow` (Snow and Snow 1988): fruiting plants and the birds eating their fruits in England, from the observations reported in the book "Birds and Berries". Species listed in the source without any recorded interaction appear as isolated nodes. Nodes: `name`, the common name of the species; `genus` and `species`, the scientific genus and species names (empty for some species without them in the source); `is_bird`. Edges: `count`, the number of feeding visits.
+- `seed_dispersal_sorensen` (Sorensen 1981): fruiting plants and the birds eating their fruits in Wytham Woods, near Oxford, UK, from a study of the feeding preferences of frugivorous birds in relation to the seasonality, abundance, growth form and nutritive and energetic value of the fruits. Species listed in the source without any recorded interaction appear as isolated nodes. Nodes: `name`, the common name of the species (as spelled in the source); `is_bird`. Edges: `count`, the number of feeding visits.
+
+**Anemone-fish networks.** An edge connects an anemonefish species (Pomacentridae: Amphiprioninae) to a sea anemone species in which it has been found living; the data record only the presence of the association.
+
+- `anemone_fish_ollerton` (Ollerton et al. 2007): the anemonefishes (genera *Amphiprion* and *Premnas*) and the sea anemones that host them, across the whole distributional range of this mutualism, from coral reefs of the east coast of Africa and the Red Sea through the Indian Ocean to the western Pacific, and from southeastern Australia to the latitude of Tokyo. The data were taken from the monograph of Fautin and Allen (1997), supplemented by later observations by D. G. Fautin, and include the correction that the anemone *Macrodactyla doreensis* hosts *Amphiprion chrysopterus*, not *A. chrysogaster* as recorded in that monograph. All records are of natural occurrences (in captivity, anemonefishes can live with many more anemones). Nodes: `name`, the species name (as spelled in the source); `distribution`, the extent of the distributional range of the species ("widespread", "regional" or "local"); `is_fish`.
+- `anemone_fish_ricciardi_<site>` (Ricciardi et al. 2010): anemonefishes and their host sea anemones (Stichodactylidae and Actiniidae) at 16 sites of the Manado region of Sulawesi, Indonesia, a marine biodiversity hotspot, from a study of the structure of the anemonefish-anemone mutualism at local and regional scales. The data are based on field records of 233 anemones and 772 anemonefish individuals observed during SCUBA dives of 45-60 min at depths between 1 and 40 m; the sites were chosen to cover a wide range of habitats (vertical slopes, patch reefs and sandy bottoms). There is one network per site (named as in the source, with spaces and dots replaced by underscores: `Bahowo`, `Bajo`, `Batu_Kapal`, `Bualo`, `Fukui`, `Jalan_m`, `Johnson`, `Kasegaran`, `Likuan_1`, `Mandolin`, `Mapia`, `Mike`, `Sachiko`, `T_Kopi`, `T_Pisok`, `Timur`), and `anemone_fish_ricciardi_regional` with the union of all sites. Nodes: `name`, the species name; `is_fish`. Edges (only in `regional`): `sites`, the number of sites where the association was recorded.
+
+**Host-parasite networks.**
+
+- `host_parasite_canada_<site>` (compiled by the IWDB): freshwater fish species and their metazoan parasites in Canadian lakes and rivers in which most fish species were surveyed for parasites, from six parasitological surveys: Aishihik Lake, Yukon (`aishihik`; Arthur et al. 1976); Cold Lake, Alberta (`cold`; Leong and Holmes 1981); Lake of the Woods, Ontario (`woods`; Dechtiar 1972); the headwaters of the McGregor (`mcgregor`) and Parsnip (`parsnip`) rivers, British Columbia (Arai and Mudry 1983); Lake Huron and Manitoulin Island, Ontario (`huron`; Bangham 1955); and the Smallwood Reservoir, Labrador (`smallwood`; Chinniah and Threlfall 1978). Only fish species with at least 5 individuals examined at a locality are included, since infection levels are inaccurate for smaller samples. All internal and external metazoan parasites are considered (nematodes, acanthocephalans, cestodes, trematodes, monogeneans, leeches, copepods and branchiurans); when a species of internal worm occurred both as larva and as adult, the two forms are treated as distinct parasite nodes, since they often have different modes of transmission and infect different hosts and organs. An edge connects a fish species to a parasite found in it, with the prevalence of infection (the percentage of examined host individuals harbouring the parasite) and, for five of the localities, the mean intensity of infection (the average number of parasite individuals per host). Fish species without any recorded parasite appear as isolated nodes. Nodes: `name`, the species name (for parasites, "(L)" marks larval forms, as in the source); `genus` and `species`, the two parts of the parasite name (empty for hosts); `sample_size`, the number of host individuals examined (zero for parasites); `relative_abundance`, an independent estimate of the relative abundance of the host species, from Leong and Holmes (1981) (only in `cold`; NaN for parasites); `is_parasite`. Edges: `prevalence`, the prevalence of infection, in percent; `intensity`, the intensity of infection (NaN if not available; absent in `woods` and `huron`).
+
+**Predator-prey networks.** These are directed food webs.
+
+- `food_web_lafferty` (Lafferty et al. 2006): the food web of the Carpinteria Salt Marsh Reserve, Santa Barbara County, California, USA, including both free-living species and parasites, compiled by K. D. Lafferty and collaborators to study the effect of parasites on food-web topology. Nodes are taxa (species or groups of species, e.g. "Oligochaete"), basal resources such as detritus, carrion and primary producers, free-living animals, and parasites (larval and adult parasite stages, mostly trematodes and other helminths). The web consists of four subwebs: predator-prey, parasite-host, predator-parasite (predation on parasites, e.g. on free-living stages or on parasites inside eaten hosts) and parasite-parasite. The links come from a combination of published reports, direct observations, and logical but presumed interactions. A directed edge points from a resource (prey or host) to its consumer (predator or parasite), and is labelled by the type of trophic interaction, coded in the source as follows (a value N.1 marks a proposed or presumed link of type N): 1, first intermediate host (1.2: first and second intermediate host; 1.25: first and second intermediate host, with excystment outside the second intermediate host); 2, second intermediate host (2.5: second intermediate host, with an external, non-trophic cyst); 3, final host; 4, predator-prey (4.2: egg predator; 4.11 is the same as 4.1); 5, predation on free-living cercarial stage of a trematode; 6, micropredation (mosquito); 7, predation on a parasite in a host; 8, predation on a parasite in a host, with possible transmission to the predator; 9, parasite-parasite (mostly intraguild predation). This is an early version of the web, which was later updated and extended (Hechinger et al. 2011). Nodes: `name`, the name of the taxon or resource; `kind`, whether it is a basal resource ("Basal"), a free-living species ("Freeliving") or a parasite ("Parasite"); `group`, a one-letter taxonomic group code given in the source (not explained there, but apparently: "D" detritus, "K" carrion, "P" primary producers, "A" annelids, "B" birds, "C" crustaceans, "F" fishes, "G" gastropods, "I" insects, "V" bivalves, "R" mammals (raccoon), "L" leeches, "N" nematodes, "T" trematodes, "W" cestodes, "O" other parasites). Edges: `link_type`, the code of the type of interaction (see above).
+- `food_web_thompson_<stream>` (Thompson and Townsend 2003, and related studies): 26 food webs of streams in New Zealand and in Maine and North Carolina (USA), compiled by R. M. Thompson, C. R. Townsend and collaborators in a series of studies on the effects of land use (e.g. native versus exotic forest), disturbance, resource supply, taxonomic resolution and season on stream food web structure. Nodes are taxa (algae, aquatic invertebrates, mostly insects, and fish), and a directed edge $(i, j)$ indicates that taxon $j$ feeds on taxon $i$. Each network is named after the stream; some streams were sampled in several seasons, indicated by the suffixes `Sp` (spring), `Su` (summer) and `Au` (autumn), and `AkatoreA` and `AkatoreB` are two webs from the Akatore stream. The IWDB distributes these data as binary interaction matrices without taxon names, so the networks carry no node metadata."""
+tags = ['Biological', 'Food web', 'Weighted', 'Unweighted', 'Metadata', 'Multilayer']
+url = ['https://iwdb.nceas.ucsb.edu/',
+ 'https://iwdb.nceas.ucsb.edu/html/arroyo_1982.html',
+ 'https://iwdb.nceas.ucsb.edu/html/barrett_helenurm_1987.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/bartomeus_2008.html',
+ 'https://iwdb.nceas.ucsb.edu/html/bezerra-et-al-2009.html',
+ 'https://iwdb.nceas.ucsb.edu/html/clements_1923.html',
+ 'https://iwdb.nceas.ucsb.edu/html/dupont_et_al.html',
+ 'https://iwdb.nceas.ucsb.edu/html/elberling_olesen_1999.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/hocking_1968.html',
+ 'https://iwdb.nceas.ucsb.edu/html/inouye_1988.html',
+ 'https://iwdb.nceas.ucsb.edu/html/kaiser-bunbury_2009.html',
+ 'https://iwdb.nceas.ucsb.edu/html/kato_1990.html',
+ 'https://iwdb.nceas.ucsb.edu/html/kevan_1970.html',
+ 'https://iwdb.nceas.ucsb.edu/html/mcmullen_1993.html',
+ 'https://iwdb.nceas.ucsb.edu/html/medan_et_al_2002.html',
+ 'https://iwdb.nceas.ucsb.edu/html/memmott_1999.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/mosquin_1967.html',
+ 'https://iwdb.nceas.ucsb.edu/html/motten_1982.html',
+ 'https://iwdb.nceas.ucsb.edu/html/olesen_et_al_2002.html',
+ 'https://iwdb.nceas.ucsb.edu/html/ollerton_et_al_2003.html',
+ 'https://iwdb.nceas.ucsb.edu/html/ramirez_1992.html',
+ 'https://iwdb.nceas.ucsb.edu/html/robertson_1929.html',
+ 'https://iwdb.nceas.ucsb.edu/html/santos-et-al-2010.html',
+ 'https://iwdb.nceas.ucsb.edu/html/schemske_1978.html',
+ 'https://iwdb.nceas.ucsb.edu/html/small_1976.html',
+ 'https://iwdb.nceas.ucsb.edu/html/vazquez_2002.html',
+ 'https://iwdb.nceas.ucsb.edu/html/bluthgen_2004.html',
+ 'https://iwdb.nceas.ucsb.edu/html/davidson_et_al_1989.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/davidson_fisher_1991.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/fonseca_ganade_1996.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/joern_1979.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/leather_1991.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/beehler_1983.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/poulin_1999.html',
+ 'https://iwdb.nceas.ucsb.edu/html/schleuning-et-al-2010.html',
+ 'https://iwdb.nceas.ucsb.edu/html/snow_snow_1988.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/sorensen_1981.htm',
+ 'https://iwdb.nceas.ucsb.edu/html/ollerton_et_al_2007.html',
+ 'https://iwdb.nceas.ucsb.edu/html/ricciardi-et-al-2010.html',
+ 'https://iwdb.nceas.ucsb.edu/html/canadian_fish.html',
+ 'https://iwdb.nceas.ucsb.edu/html/carpinteria.html',
+ 'https://iwdb.nceas.ucsb.edu/html/thomps_towns.html']
+citation = [('Interaction Web Database (IWDB), National Center for Ecological Analysis and Synthesis, University of California, Santa Barbara (now hosted by the University of São Paulo)', 'https://iwdb.nceas.ucsb.edu/'),
+ ('M. T. K. Arroyo, R. Primack, J. Armesto, "Community studies in pollination ecology in the high temperate Andes of central Chile. I. Pollination mechanisms and altitudinal variation." American Journal of Botany 69(1), 82-97 (1982)', 'https://doi.org/10.1002/j.1537-2197.1982.tb13237.x'),
+ ('S. C. H. Barrett, K. Helenurm, "The reproductive biology of boreal forest herbs. I. Breeding systems and pollination." Canadian Journal of Botany 65(10), 2036-2046 (1987)', 'https://doi.org/10.1139/b87-278'),
+ ('I. Bartomeus, M. Vilà, L. Santamaría, "Contrasting effects of invasive plants in plant-pollinator networks." Oecologia 155(4), 761-770 (2008)', 'https://doi.org/10.1007/s00442-007-0946-1'),
+ ('E. L. S. Bezerra, I. C. Machado, M. A. R. Mello, "Pollination networks of oil-flowers: a tiny world within the smallest of all worlds." Journal of Animal Ecology 78(5), 1096-1101 (2009)', 'https://doi.org/10.1111/j.1365-2656.2009.01567.x'),
+ ('F. E. Clements, F. L. Long, "Experimental pollination: an outline of the ecology of flowers and insects." Carnegie Institution of Washington, Washington, D.C. (1923)', 'https://doi.org/10.5962/bhl.title.20274'),
+ ('Y. L. Dupont, D. M. Hansen, J. M. Olesen, "Structure of a plant-flower-visitor network in the high-altitude sub-alpine desert of Tenerife, Canary Islands." Ecography 26(3), 301-310 (2003)', 'https://doi.org/10.1034/j.1600-0587.2003.03443.x'),
+ ('H. Elberling, J. M. Olesen, "The structure of a high latitude plant-flower visitor system: the dominance of flies." Ecography 22(3), 314-323 (1999)', 'https://doi.org/10.1111/j.1600-0587.1999.tb00507.x'),
+ ('B. Hocking, "Insect-flower associations in the high Arctic with special reference to nectar." Oikos 19(2), 359-388 (1968)', 'https://doi.org/10.2307/3565022'),
+ ('D. W. Inouye, G. H. Pyke, "Pollination biology in the Snowy Mountains of Australia: comparisons with montane Colorado, USA." Australian Journal of Ecology 13(2), 191-205 (1988)', 'https://doi.org/10.1111/j.1442-9993.1988.tb00968.x'),
+ ('C. N. Kaiser-Bunbury, J. Memmott, C. B. Müller, "Community structure of pollination webs of Mauritian heathland habitats." Perspectives in Plant Ecology, Evolution and Systematics 11(4), 241-254 (2009)', 'https://doi.org/10.1016/j.ppees.2009.04.001'),
+ ('C. N. Kaiser-Bunbury, S. Muff, J. Memmott, C. B. Müller, A. Caflisch, "The robustness of pollination networks to the loss of species and interactions: a quantitative approach incorporating pollinator behaviour." Ecology Letters 13(4), 442-452 (2010)', 'https://doi.org/10.1111/j.1461-0248.2009.01437.x'),
+ ('M. Kato, T. Makutani, T. Inoue, T. Itino, "Insect-flower relationship in the primary beech forest of Ashu, Kyoto: an overview of the flowering phenology and seasonal pattern of insect visits." Contributions from the Biological Laboratory, Kyoto University 27, 309-375 (1990)', 'http://hdl.handle.net/2433/156101'),
+ ('P. G. Kevan, "High arctic insect-flower relations: the inter-relationships of arthropods and flowers at Lake Hazen, Ellesmere Island, Northwest Territories, Canada." PhD thesis, University of Alberta (1970)', 'https://iwdb.nceas.ucsb.edu/html/kevan_1970.html'),
+ ('C. K. McMullen, "Flower-visiting insects of the Galapagos Islands." Pan-Pacific Entomologist 69(1), 95-106 (1993)', 'https://iwdb.nceas.ucsb.edu/html/mcmullen_1993.html'),
+ ('D. Medan, N. H. Montaldo, M. Devoto, A. Mantese, V. Vasellati, G. G. Roitman, N. H. Bartoloni, "Plant-pollinator relationships at two altitudes in the Andes of Mendoza, Argentina." Arctic, Antarctic, and Alpine Research 34(3), 233-241 (2002)', 'https://doi.org/10.1080/15230430.2002.12003490'),
+ ('J. Memmott, "The structure of a plant-pollinator food web." Ecology Letters 2(5), 276-280 (1999)', 'https://doi.org/10.1046/j.1461-0248.1999.00087.x'),
+ ('T. Mosquin, J. E. H. Martin, "Observations on the pollination biology of plants on Melville Island, N.W.T., Canada." Canadian Field-Naturalist 81, 201-205 (1967)', 'https://iwdb.nceas.ucsb.edu/html/mosquin_1967.html'),
+ ('A. F. Motten, "Pollination ecology of the spring wildflower community in the deciduous forests of piedmont North Carolina." PhD thesis, Duke University, Durham, North Carolina, USA (1982)', 'https://iwdb.nceas.ucsb.edu/html/motten_1982.html'),
+ ('A. F. Motten, "Pollination ecology of the spring wildflower community of a temperate deciduous forest." Ecological Monographs 56(1), 21-42 (1986)', 'https://doi.org/10.2307/2937269'),
+ ('J. M. Olesen, L. I. Eskildsen, S. Venkatasamy, "Invasion of pollination networks on oceanic islands: importance of invader complexes and endemic super generalists." Diversity and Distributions 8(3), 181-192 (2002)', 'https://doi.org/10.1046/j.1472-4642.2002.00148.x'),
+ ('J. Ollerton, S. D. Johnson, L. Cranmer, S. Kellie, "The pollination ecology of an assemblage of grassland asclepiads in South Africa." Annals of Botany 92(6), 807-834 (2003)', 'https://doi.org/10.1093/aob/mcg206'),
+ ('N. Ramirez, Y. Brito, "Pollination biology in a palm swamp community in the Venezuelan Central Plains." Botanical Journal of the Linnean Society 110(4), 277-302 (1992)', 'https://doi.org/10.1111/j.1095-8339.1992.tb00294.x'),
+ ('C. Robertson, "Flowers and insects: lists of visitors of four hundred and fifty-three flowers." Carlinville, Illinois, USA (1929)', 'https://doi.org/10.5962/bhl.title.11538'),
+ ('G. M. M. Santos, C. M. L. Aguiar, M. A. R. Mello, "Flower-visiting guild associated with the Caatinga flora: trophic interaction networks formed by social bees and social wasps with plants." Apidologie 41(4), 466-475 (2010)', 'https://doi.org/10.1051/apido/2009081'),
+ ('D. W. Schemske, M. F. Willson, M. N. Melampy, L. J. Miller, L. Verner, K. M. Schemske, L. B. Best, "Flowering ecology of some spring woodland herbs." Ecology 59(2), 351-366 (1978)', 'https://doi.org/10.2307/1936379'),
+ ('E. Small, "Insect pollinators of the Mer Bleue peat bog of Ottawa." Canadian Field-Naturalist 90, 22-28 (1976)', 'https://iwdb.nceas.ucsb.edu/html/small_1976.html'),
+ ('D. P. Vázquez, D. Simberloff, "Changes in interaction biodiversity induced by an introduced ungulate." Ecology Letters 6(12), 1077-1083 (2003)', 'https://doi.org/10.1046/j.1461-0248.2003.00534.x'),
+ ('N. Blüthgen, N. E. Stork, K. Fiedler, "Bottom-up control and co-occurrence in complex communities: honeydew and nectar determine a rainforest ant mosaic." Oikos 106(2), 344-358 (2004)', 'https://doi.org/10.1111/j.0030-1299.2004.12687.x'),
+ ('N. Blüthgen, K. Fiedler, "Preferences for sugars and amino acids and their conditionality in a diverse nectar-feeding ant community." Journal of Animal Ecology 73(1), 155-166 (2004)', 'https://doi.org/10.1111/j.1365-2656.2004.00789.x'),
+ ('D. W. Davidson, R. R. Snelling, J. T. Longino, "Competition among ants for myrmecophytes and the significance of plant trichomes." Biotropica 21(1), 64-73 (1989)', 'https://doi.org/10.2307/2388444'),
+ ('D. W. Davidson, B. L. Fisher, "Symbiosis of ants with Cecropia as a function of light regime." In C. R. Huxley, D. F. Cutler (eds.), Ant-Plant Interactions, pp. 289-309, Oxford University Press, Oxford (1991)', 'https://iwdb.nceas.ucsb.edu/html/davidson_fisher_1991.htm'),
+ ('C. R. Fonseca, G. Ganade, "Asymmetries, compartments and null interactions in an Amazonian ant-plant community." Journal of Animal Ecology 65(3), 339-347 (1996)', 'https://doi.org/10.2307/5880'),
+ ('A. Joern, "Feeding patterns in grasshoppers (Orthoptera: Acrididae): factors influencing diet specialization." Oecologia 38(3), 325-347 (1979)', 'https://doi.org/10.1007/BF00345192'),
+ ('S. R. Leather, "Feeding specialisation and host distribution of British and Finnish Prunus feeding macrolepidoptera." Oikos 60(1), 40-48 (1991)', 'https://doi.org/10.2307/3544990'),
+ ('B. Beehler, "Frugivory and polygamy in birds of paradise." The Auk 100(1), 1-12 (1983)', 'https://doi.org/10.1093/auk/100.1.1'),
+ ('B. Poulin, S. J. Wright, G. Lefebvre, O. Calderón, "Interspecific synchrony and asynchrony in the fruiting phenologies of congeneric bird-dispersed plants in Panama." Journal of Tropical Ecology 15(2), 213-227 (1999)', 'https://doi.org/10.1017/S0266467499000760'),
+ ('M. Schleuning, N. Blüthgen, M. Flörchinger, J. Braun, H. M. Schaefer, K. Böhning-Gaese, "Specialization and interaction strength in a tropical plant-frugivore network differ among forest strata." Ecology 92(1), 26-36 (2011)', 'https://doi.org/10.1890/09-1842.1'),
+ ('B. K. Snow, D. W. Snow, "Birds and Berries: a study of an ecological interaction." T. & A. D. Poyser, Calton, England (1988)', 'https://books.google.com/books?id=AHTtmx4f8y8C'),
+ ('A. E. Sorensen, "Interactions between birds and fruit in a temperate woodland." Oecologia 50(2), 242-249 (1981)', 'https://doi.org/10.1007/BF00348046'),
+ ('J. Ollerton, D. McCollin, D. G. Fautin, G. R. Allen, "Finding NEMO: nestedness engendered by mutualistic organization in anemonefish and their hosts." Proceedings of the Royal Society B: Biological Sciences 274(1609), 591-598 (2007)', 'https://doi.org/10.1098/rspb.2006.3758'),
+ ('D. G. Fautin, G. R. Allen, "Anemonefishes and their host sea anemones." Revised edition, Western Australian Museum, Perth (1997)', 'https://iwdb.nceas.ucsb.edu/html/ollerton_et_al_2007.html'),
+ ('F. Ricciardi, M. Boyer, J. Ollerton, "Assemblage and interaction structure of the anemonefish-anemone mutualism across the Manado region of Sulawesi, Indonesia." Environmental Biology of Fishes 87(4), 333-347 (2010)', 'https://doi.org/10.1007/s10641-010-9606-0'),
+ ('J. R. Arthur, L. Margolis, H. P. Arai, "Parasites of fishes of Aishihik and Stevens Lakes, Yukon Territory, and potential consequences of their interlake transfer through a proposed water diversion for hydroelectrical purposes." Journal of the Fisheries Research Board of Canada 33(11), 2489-2499 (1976)', 'https://doi.org/10.1139/f76-294'),
+ ('T. S. Leong, J. C. Holmes, "Communities of metazoan parasites in open water fishes of Cold Lake, Alberta." Journal of Fish Biology 18(6), 693-713 (1981)', 'https://doi.org/10.1111/j.1095-8649.1981.tb03811.x'),
+ ('A. O. Dechtiar, "Parasites of fish from Lake of the Woods, Ontario." Journal of the Fisheries Research Board of Canada 29(3), 275-283 (1972)', 'https://doi.org/10.1139/f72-046'),
+ ('H. P. Arai, D. R. Mudry, "Protozoan and metazoan parasites of fishes from the headwaters of the Parsnip and McGregor Rivers, British Columbia: a study of possible parasite transfaunations." Canadian Journal of Fisheries and Aquatic Sciences 40(10), 1676-1684 (1983)', 'https://doi.org/10.1139/f83-194'),
+ ('R. V. Bangham, "Studies on fish parasites of Lake Huron and Manitoulin Island." American Midland Naturalist 53(1), 184-194 (1955)', 'https://doi.org/10.2307/2422308'),
+ ('V. C. Chinniah, W. Threlfall, "Metazoan parasites of fish from the Smallwood Reservoir, Labrador, Canada." Journal of Fish Biology 13(2), 203-213 (1978)', 'https://doi.org/10.1111/j.1095-8649.1978.tb03427.x'),
+ ('K. D. Lafferty, A. P. Dobson, A. M. Kuris, "Parasites dominate food web links." Proceedings of the National Academy of Sciences 103(30), 11211-11216 (2006)', 'https://doi.org/10.1073/pnas.0604755103'),
+ ('K. D. Lafferty, R. F. Hechinger, J. C. Shaw, K. L. Whitney, A. M. Kuris, "Food webs and parasites in a salt marsh ecosystem." In S. K. Collinge, C. Ray (eds.), Disease Ecology: Community Structure and Pathogen Dynamics, pp. 119-134, Oxford University Press, Oxford (2006)', 'https://doi.org/10.1093/acprof:oso/9780198567080.003.0009'),
+ ('R. M. Thompson, C. R. Townsend, "Impacts on stream food webs of native and exotic forest: an intercontinental comparison." Ecology 84(1), 145-161 (2003)', 'https://doi.org/10.1890/0012-9658(2003)084[0145:iosfwo]2.0.co;2')]
+icon_hash = ['56a85c8e26855e083a2f78f7', '56a85c8e26855e083a2f78f8',
+ '56a85c8e26855e083a2f78f9', '56a85c8e26855e083a2f78fa',
+ '56a85c8e26855e083a2f78fb', '56a85c8e26855e083a2f78fc',
+ '56a85c8e26855e083a2f78fd', '56a85c8e26855e083a2f78fe',
+ '56a85c8e26855e083a2f7902', '56a85c8e26855e083a2f78ff',
+ '56a85c8e26855e083a2f7900', '56a85c8e26855e083a2f7901',
+ '56a85c8e26855e083a2f7903', '56a85c8e26855e083a2f7904',
+ '56a85c8e26855e083a2f7905', '56a85c8e26855e083a2f7906',
+ '56a85c8e26855e083a2f7907', '56a85c8e26855e083a2f7908',
+ '56a85c8e26855e083a2f7909', '56a85c8e26855e083a2f790a',
+ '56a85c8e26855e083a2f790b', '56a85c8e26855e083a2f790c',
+ '56a85c8e26855e083a2f790d', '56a85c8e26855e083a2f790e',
+ '56a85c8e26855e083a2f790f', '56a85c8e26855e083a2f7912',
+ '56a85c8e26855e083a2f7913', '56a85c8e26855e083a2f7914',
+ '56a85c8e26855e083a2f7915', '56a85c8e26855e083a2f7910',
+ '56a85c8e26855e083a2f7911', '56a85c8e26855e083a2f78f2',
+ '56a85c8e26855e083a2f78f3', '56a85c8e26855e083a2f78f4',
+ '56a85c8e26855e083a2f78f5', '56a85c8e26855e083a2f78f6',
+ '56a85c8e26855e083a2f791c', '56a85c8e26855e083a2f791d',
+ '56a85c8e26855e083a2f7917', '56a85c8e26855e083a2f791b',
+ '56a85c8e26855e083a2f791a', '56a85c8e26855e083a2f7916',
+ '56a85c8e26855e083a2f7918', '56a85c8e26855e083a2f7919',
+ '56a85c8e26855e083a2f78cf', '56a85c8e26855e083a2f78f1']
+upstream_license = None
+upstream_prefix = 'https://iwdb.nceas.ucsb.edu/data'
+
+# The Interaction Web Database (iwdb.nceas.ucsb.edu) refuses automated
+# requests, so the files are obtained from snapshots of the Internet Archive
+# (some of them under earlier locations of the IWDB, www.nceas.ucsb.edu).
+#
+# Each data set is parsed by its own function, registered with
+# @dataset(key, files, urls), where `files` lists the upstream files of the
+# data set as (file name, network, format), with the network names of the
+# data set (None if it has a single network), and `urls` maps the file names
+# to their archived URLs. The networks of the entry are named `key`, or
+# `key_<network>` (see alt_name()).
+
+datasets = {}
+archived_urls = {}
+
+def dataset(key, dfiles, urls):
+ def register(f):
+ datasets[key] = (f, dfiles)
+ archived_urls.update(urls)
+ return f
+ return register
+
+def alt_name(key, alt):
+ if alt is None:
+ return key
+ return key + "_" + re.sub(r"[^A-Za-z0-9]+", "_", alt).strip("_")
+
+# Arroyo plant-pollinator webs (1982)
+# (formerly the entry `plant_pol_arroyo`)
+@dataset('pollination_arroyo',
+ [('arroyo_I.xls', 'I', None),
+ ('arroyo_II.xls', 'II', None),
+ ('arroyo_III.xls', 'III', None)],
+ {'arroyo_I.xls':
+ 'https://web.archive.org/web/20240723020842id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/arroyo_I.xls',
+ 'arroyo_II.xls':
+ 'https://web.archive.org/web/20240723114643id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/arroyo_II.xls',
+ 'arroyo_III.xls':
+ 'https://web.archive.org/web/20240723011805id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/arroyo_III.xls'})
+def parse_pollination_arroyo(name, files, alts):
+ for fname, alt, fmt in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = list(read_xls(f).values())[0]
+ # plant genus and species in rows 0-1, pollinator genus and species
+ # in columns 0-1, binary matrix from row 3 and column 3 (cells are
+ # empty or 0 if there is no interaction)
+ r1 = max(i for i, r in enumerate(rows) if cell_str(r[0])) + 1
+ c1 = max(j for j, x in enumerate(rows[0]) if cell_str(x)) + 1
+ g = sheet_matrix_graph(rows, 3, r1, 3, c1,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_pollinator", True, cell=cell_presence)
+ yield alt, g
+
+# Barrett & Helenurm plant-pollinator web (1978-1980)
+# (formerly the entry `plant_pol_barrett`)
+@dataset('pollination_barrett',
+ [('barrett_helenurm_1987.xls', None, None)],
+ {'barrett_helenurm_1987.xls':
+ 'https://web.archive.org/web/20240723070652id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/barret&helenurm_1987.xls'})
+def parse_pollination_barrett(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant genus and species in rows 0-1, pollinator genus and species
+ # in columns 0-1, matrix of counts from row 3 and column 3
+ g = sheet_matrix_graph(rows, 3, 105, 3, 15,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_pollinator", True)
+ yield alt, g
+
+# Bartomeus plant-pollinator webs in invaded and uninvaded plots (2008)
+# (formerly the entry `plant_pol_bartomeus`)
+bartomeus_plots = ['BAT1CA', 'BAT2CA', 'MED1CA', 'MED2CA', 'MED3CA', 'MED4CA',
+ 'FRA1OP', 'FRA2OP', 'MIQ1OP', 'MIQ2OP', 'SEL1OP', 'SEL2OP']
+@dataset('pollination_bartomeus',
+ [('Bartomeus_Ntw_nceas.xls', plot, None) for plot in bartomeus_plots],
+ {'Bartomeus_Ntw_nceas.xls':
+ 'https://web.archive.org/web/20240819144019id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/Bartomeus_Ntw_nceas.xls'})
+def parse_pollination_bartomeus(name, files, alts):
+ for fname, alt, fmt in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Ntw_raw_data"]
+ # columns: site, round, plant id, plant family, plant name, insect id,
+ # insect order, insect family, insect name, number of visits
+ assert rows[0][:10] == ['Site', 'Round', 'Plant_id', 'Plant_Family',
+ 'Plant_Gen_Sp', 'Insect_id', 'Insect_Order',
+ 'Insect_Family', 'Insect_Gen_Sp',
+ 'Number_of_visits_per6min']
+ g = Graph(directed=False)
+ g.vp.name = g.new_vp("string")
+ g.vp.code = g.new_vp("int")
+ g.vp.family = g.new_vp("string")
+ g.vp.order = g.new_vp("string")
+ g.vp.is_pollinator = g.new_vp("bool")
+ g.ep.visits = g.new_ep("int")
+ g.ep.rounds = g.new_ep("int")
+ vs = {}
+ es = {}
+ def get_v(key, vname, family, order):
+ v = vs.get(key)
+ if v is None:
+ v = vs[key] = g.add_vertex()
+ g.vp.name[v] = cell_str(vname).replace("_", " ")
+ g.vp.code[v] = key[1]
+ g.vp.family[v] = cell_str(family)
+ g.vp.order[v] = cell_str(order)
+ g.vp.is_pollinator[v] = key[0]
+ return v
+ for r in rows[1:]:
+ if r[0] is None:
+ continue
+ plot = {"SEL10P": "SEL1OP", "SEL1P": "SEL1OP"}.get(r[0], r[0])
+ if plot != alt:
+ continue
+ u = get_v((False, r[2]), r[4], r[3], "")
+ v = get_v((True, r[5]), r[8], r[7], r[6])
+ e = es.get((u, v))
+ if e is None:
+ e = es[(u, v)] = g.add_edge(u, v)
+ g.ep.visits[e] += r[9]
+ g.ep.rounds[e] += 1
+ yield alt, g
+
+# Bezerra oil-flower and oil-collecting bee web (2009)
+# (formerly the entry `plant_pol_bezerra`)
+@dataset('pollination_bezerra',
+ [('bezerra-et-al-2009.xls', None, None)],
+ {'bezerra-et-al-2009.xls':
+ 'https://web.archive.org/web/20240723111328id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/bezerra-et-al-2009.xls'})
+def parse_pollination_bezerra(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["matrix"]
+ # plant names in row 0, bee names in column 0, matrix of counts from
+ # row 1 and column 1
+ g = sheet_matrix_graph(rows, 1, 14, 1, 14,
+ lambda i: dict(name=cell_str(rows[i][0])),
+ lambda j: dict(name=cell_str(rows[0][j])),
+ "is_pollinator", True)
+ yield alt, g
+
+# Clements & Long plant-pollinator web (1923)
+# (formerly the entry `plant_pol_clements`)
+@dataset('pollination_clements',
+ [('clements_1923.xls', None, None)],
+ {'clements_1923.xls':
+ 'https://web.archive.org/web/20240723040910id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/clements_1923.xls'})
+def parse_pollination_clements(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["cle_matr"]
+ # plant genus and species in rows 1-2, pollinator code, genus and
+ # species in columns 0-2, binary matrix from row 4 and column 4
+ g = sheet_matrix_graph(rows, 4, 279, 4, 100,
+ lambda i: dict(name=join_cells(rows[i][1], rows[i][2]),
+ genus=cell_str(rows[i][1]),
+ species=cell_str(rows[i][2]),
+ code=cell_str(rows[i][0])),
+ lambda j: dict(name=join_cells(rows[1][j], rows[2][j]),
+ genus=cell_str(rows[1][j]),
+ species=cell_str(rows[2][j]),
+ code=""),
+ "is_pollinator", True, cell=cell_presence)
+ yield alt, g
+
+# Dupont plant-pollinator web (2003)
+# (formerly the entry `plant_pol_dupont`)
+@dataset('pollination_dupont',
+ [('dupont_et_al_2003.xls', None, None)],
+ {'dupont_et_al_2003.xls':
+ 'https://web.archive.org/web/20240723231633id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/dupont_et_al_2003.xls'})
+def parse_pollination_dupont(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant origin, genus and species in rows 0-2, pollinator origin,
+ # genus and species in columns 0-2, binary matrix from row 4 and
+ # column 4
+ g = sheet_matrix_graph(rows, 4, 42, 4, 15,
+ lambda i: dict(name=join_cells(rows[i][1], rows[i][2]),
+ genus=cell_str(rows[i][1]),
+ species=cell_str(rows[i][2]),
+ origin=cell_str(rows[i][0])),
+ lambda j: dict(name=join_cells(rows[1][j], rows[2][j]),
+ genus=cell_str(rows[1][j]),
+ species=cell_str(rows[2][j]),
+ origin=cell_str(rows[0][j])),
+ "is_pollinator", True, cell=cell_presence)
+ yield alt, g
+
+# Elberling & Olesen plant-pollinator web (1994)
+# (formerly the entry `plant_pol_elberling`)
+@dataset('pollination_elberling',
+ [('elberling_olesen_1999.xls', None, None)],
+ {'elberling_olesen_1999.xls':
+ 'https://web.archive.org/web/20240723190511id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/elberling&olesen_1999.xls'})
+def parse_pollination_elberling(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant genus and species in rows 0-1, pollinator genus and species
+ # in columns 0-1, matrix of counts from row 3 and column 3 (the
+ # sheet also has summary statistics outside the matrix)
+ g = sheet_matrix_graph(rows, 3, 121, 3, 26,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_pollinator", True)
+ yield alt, g
+
+# Hocking plant-pollinator web (1968)
+# (formerly the entry `plant_pol_hocking`)
+@dataset('pollination_hocking',
+ [('hocking_1968.xls', None, None)],
+ {'hocking_1968.xls':
+ 'https://web.archive.org/web/20240723212822id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/hocking_1968.xls'})
+def parse_pollination_hocking(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant genus and species in rows 0-1, pollinator genus and species
+ # in columns 0-1, binary matrix from row 3 and column 3
+ g = sheet_matrix_graph(rows, 3, 89, 3, 32,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_pollinator", True, cell=cell_presence)
+ yield alt, g
+
+# Inouye & Pyke plant-pollinator web (1983-1984)
+# (formerly the entry `plant_pol_inouye`)
+@dataset('pollination_inouye',
+ [('inouye_1988.xls', None, None)],
+ {'inouye_1988.xls':
+ 'https://web.archive.org/web/20240722120607id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/inouye_1988.xls'})
+def parse_pollination_inouye(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["ino_matr"]
+ # plant genus and species in rows 0-1 (from column 4), pollinator
+ # order, genus and species in columns 0-2, matrix of counts from row 3
+ # and column 4; the plants in columns 46-65 have no data
+ assert all(sheet_cell(rows, i, j) is None for i in range(3, 94) for j in range(46, 66))
+ g = sheet_matrix_graph(rows, 3, 94, 4, 46,
+ lambda i: dict(name=join_cells(rows[i][1], rows[i][2]),
+ genus=cell_str(rows[i][1]),
+ species=cell_str(rows[i][2]),
+ order=cell_str(rows[i][0])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j]),
+ order=""),
+ "is_pollinator", True)
+ yield alt, g
+
+# Kaiser-Bunbury Mauritian heathland pollination webs (2009)
+# (formerly the entry `plant_pol_kaiser_bunbury`)
+@dataset('pollination_kaiser_bunbury',
+ [('kaiser-bunbury_2009.xls', 'control', ('Control', 107, 69)),
+ ('kaiser-bunbury_2009.xls', 'restored', ('Restored', 142, 79))],
+ {'kaiser-bunbury_2009.xls':
+ 'https://web.archive.org/web/20240722103338id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/kaiser-bunbury_2009.xls'})
+def parse_pollination_kaiser_bunbury(name, files, alts):
+ for fname, alt, (site, r1, c1) in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fname, "rb") as f:
+ sheets = read_xls(f)
+ # plant name, family, origin, flower colour, flower category and
+ # floral abundance in rows 0-5 (from column 5), animal name, family,
+ # origin, number of probed flowers and total in columns 0-4, matrix
+ # from row 7 and column 5; one sheet with visitation rates and
+ # another with interaction strengths
+ rows = sheets[f"{site}_visitation rate"]
+ srows = sheets[f"{site}_interact strength"]
+ for i in range(7, r1):
+ assert rows[i][:4] == srows[i][:4]
+ for i in range(6):
+ assert rows[i][5:c1] == srows[i][5:c1]
+
+ def cell(i, j):
+ x, y = rows[i][j], srows[i][j]
+ if not x and not y:
+ return None
+ return dict(visitation_rate=x or 0, interaction_strength=y or 0)
+
+ ri = list(range(7, r1))
+ cj = list(range(5, c1))
+ g = interaction_graph([dict(name=cell_str(rows[i][0]), family=cell_str(rows[i][1]),
+ origin=rows[i][2], flower_colour=0,
+ flower_category=0, floral_abundance=0,
+ probed_flowers=rows[i][3]) for i in ri],
+ [dict(name=cell_str(rows[0][j]), family=cell_str(rows[1][j]),
+ origin=rows[2][j], flower_colour=rows[3][j],
+ flower_category=rows[4][j],
+ floral_abundance=rows[5][j],
+ probed_flowers=0) for j in cj],
+ lambda i, j: cell(ri[i], cj[j]), "is_pollinator", True,
+ vtypes=dict(origin="int", flower_colour="int",
+ flower_category="int",
+ floral_abundance="double",
+ probed_flowers="int"),
+ etypes=dict(visitation_rate="double",
+ interaction_strength="double"))
+ yield alt, g
+
+# Kato plant-pollinator web
+# (formerly the entry `plant_pol_kato`)
+@dataset('pollination_kato',
+ [('kato_et_al_1990.xls', None, None)],
+ {'kato_et_al_1990.xls':
+ 'https://web.archive.org/web/20240123030138id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/kato_et_al_1990.xls'})
+def parse_pollination_kato(name, files, alts):
+ 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, "rb")) for fn in fnames]
+ with tempfile.TemporaryDirectory(dir="./cache/temp") as tdir:
+ with open(f"{tdir}/dump.xls", "wb") as fw:
+ shutil.copyfileobj(fs[0], fw)
+ subprocess.run(["localc", "--convert-to", "xlsx",
+ f"dump.xls"], cwd=tdir, check=True)
+ wb = load_workbook(f"{tdir}/dump.xlsx", read_only=True)
+
+ g = Graph(directed=False)
+ g.vp.idx = g.new_vp("int")
+ g.vp.pollinator = g.new_vp("bool")
+ g.ep.count = g.new_ep("int")
+
+ def add_bip_edges(m):
+ plts = {}
+ pols = {}
+ for i in range(1, m.shape[0]):
+ v = g.add_vertex()
+ g.vp.pollinator[v] = True
+ pols[m[i,0]] = v
+ g.vp.idx[v] = m[i,0]
+
+ for j in range(1, m.shape[1]):
+ u = plts.get(m[0, j], None)
+ if u is None:
+ u = g.add_vertex()
+ g.vp.pollinator[u] = False
+ plts[m[0, j]] = u
+ g.vp.idx[u] = m[0, j]
+
+ if m[i,j] is None:
+ continue
+ if numpy.isnan(float(m[i,j])):
+ continue
+ x = int(m[i, j])
+ if x > 0:
+ e = g.add_edge(v, u)
+ g.ep.count[e] = x
+ return plts, pols
+
+ m = pandas.DataFrame(wb["matr"].values).values
+ plts, pols = add_bip_edges(m[2:,1:])
+
+ for ti, (idxs, vals) in enumerate([(m[2:,1], m[2:,0]),
+ (m[2,1:].T, m[0,1:].T),
+ (m[2,1:].T, m[1,1:].T)]):
+ vs = pols if ti == 0 else plts
+ p = vals[0]
+ if p not in g.vp:
+ g.vp[p] = g.new_vp("string")
+ for i in range(1, len(vals)):
+ idx = idxs[i]
+ if idx is None:
+ continue
+ g.vp[p][vs[idx]] = vals[i]
+ yield alt, g
+
+# Kevan plant-pollinator web (1967)
+# (formerly the entry `plant_pol_kevan`)
+@dataset('pollination_kevan',
+ [('kevan_1970.xls', None, None)],
+ {'kevan_1970.xls':
+ 'https://web.archive.org/web/20240723100344id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/kevan_1970.xls'})
+def parse_pollination_kevan(name, files, alts):
+ def cell(x):
+ if isinstance(x, str) and x.strip() in ("few", "several", "many",
+ "eggs", "?"):
+ return dict(count=numpy.nan, note=x.strip())
+ d = cell_count(x)
+ if d is not None:
+ d["note"] = ""
+ return d
+
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant genus and species in rows 0-1 (genus marked with "*" for
+ # Salix, whose catkins are separated by sex), pollinator genus and
+ # species in columns 0-1, matrix of counts from row 3 and column 2
+ g = sheet_matrix_graph(rows, 3, 118, 2, 34,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(cell_str(rows[0][j]).lstrip("*"), rows[1][j]),
+ genus=cell_str(rows[0][j]).lstrip("*"),
+ species=cell_str(rows[1][j])),
+ "is_pollinator", True, cell=cell,
+ etypes=dict(count="double"))
+ yield alt, g
+
+# McMullen plant-pollinator web (1993)
+# (formerly the entry `plant_pol_mcmullen`)
+@dataset('pollination_mcmullen',
+ [('mcmullen_1993.xls', None, None)],
+ {'mcmullen_1993.xls':
+ 'https://web.archive.org/web/20240723024340id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/mcmullen_1993.xls'})
+def parse_pollination_mcmullen(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant genus and species in rows 0-1, pollinator genus and species
+ # in columns 0-1, binary matrix from row 3 and column 3
+ g = sheet_matrix_graph(rows, 3, 57, 3, 108,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_pollinator", True, cell=cell_presence)
+ yield alt, g
+
+# Medan plant-pollinator webs (2002)
+# (formerly the entry `plant_pol_medan`)
+@dataset('pollination_medan',
+ [('medan_et_al_2002.xls', 'LD', (48, 26)),
+ ('medan_et_al_2002.xls', 'RB', (75, 28))],
+ {'medan_et_al_2002.xls':
+ 'https://web.archive.org/web/20240724154217id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/medan_et_al_2002.xls'})
+def parse_pollination_medan(name, files, alts):
+ for fname, alt, (r1, c1) in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)[alt]
+ # plant name, family and code in rows 0-2 (from column 5), pollinator
+ # order, family, name and code in columns 0-3 (column 4 lists the
+ # codes of the plants visited), binary matrix from row 3 and column 5
+ g = sheet_matrix_graph(rows, 3, r1, 5, c1,
+ lambda i: dict(name=cell_str(rows[i][2]),
+ family=cell_str(rows[i][1]),
+ order=cell_str(rows[i][0]),
+ code=cell_str(rows[i][3])),
+ lambda j: dict(name=cell_str(rows[0][j]),
+ family=cell_str(rows[1][j]),
+ order="",
+ code=cell_str(rows[2][j])),
+ "is_pollinator", True, cell=cell_presence)
+ yield alt, g
+
+# Memmott plant-pollinator web (1997)
+# (formerly the entry `plant_pol_memmott`)
+@dataset('pollination_memmott',
+ [('memmott_1999.xls', None, None)],
+ {'memmott_1999.xls':
+ 'https://web.archive.org/web/20240723050043id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/memmott_1999.xls'})
+def parse_pollination_memmott(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["matrices"]
+ # plant number and common name (two words, "---" for none) in rows
+ # 0-2, pollinator number and order in columns 0-1 (columns 2-3 give a
+ # plant name for each pollinator, not used), matrix of counts from
+ # row 3 and column 4
+ g = sheet_matrix_graph(rows, 3, 82, 4, 29,
+ lambda i: dict(name=join_cells(rows[i][1], rows[i][0]),
+ code=cell_str(rows[i][0]),
+ order=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[1][j], cell_str(rows[2][j]).replace("---", "").replace("_", " ")),
+ code=cell_str(rows[0][j]),
+ order=""),
+ "is_pollinator", True)
+ yield alt, g
+
+# Mosquin & Martin plant-pollinator web (1965)
+# (formerly the entry `plant_pol_mosquin`)
+@dataset('pollination_mosquin',
+ [('mosquin_1967.xls', None, None)],
+ {'mosquin_1967.xls':
+ 'https://web.archive.org/web/20240723122540id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/mosquin_1967.xls'})
+def parse_pollination_mosquin(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # pollinator genus and species in rows 0-1, plant genus and species
+ # in columns 0-1, matrix of counts from row 3 and column 3
+ g = sheet_matrix_graph(rows, 3, 14, 3, 21,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_pollinator", False)
+ yield alt, g
+
+# Motten plant-pollinator web (1982)
+# (formerly the entry `plant_pol_motten`)
+@dataset('pollination_motten',
+ [('motten_1982.xls', None, None)],
+ {'motten_1982.xls':
+ 'https://web.archive.org/web/20240722101347id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/motten_1982.xls'})
+def parse_pollination_motten(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["mott_matr"]
+ # plant genus, species and code in rows 0-2, pollinator genus and
+ # species in columns 0-1, matrix of counts from row 3 and column 3
+ g = sheet_matrix_graph(rows, 3, 47, 3, 16,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1]),
+ code=""),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j]),
+ code=cell_str(rows[2][j])),
+ "is_pollinator", True)
+ yield alt, g
+
+# Olesen plant-pollinator webs on oceanic islands (2002)
+# (formerly the entry `plant_pol_olesen`)
+@dataset('pollination_olesen',
+ [('olesen_aigrettes.xls', 'aigrettes', None),
+ ('olesen_flores.xls', 'flores', None)],
+ {'olesen_aigrettes.xls':
+ 'https://web.archive.org/web/20240723053646id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/olesen_aigrettes.xls',
+ 'olesen_flores.xls':
+ 'https://web.archive.org/web/20240723054821id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/olesen_flores.xls'})
+def parse_pollination_olesen(name, files, alts):
+ for fname, alt, fmt in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = list(read_xls(f).values())[0]
+ # plant origin, genus and species in rows 0-2, pollinator origin,
+ # genus and species in columns 0-2, matrix of counts from row 4 and
+ # column 4
+ r1 = max(i for i, r in enumerate(rows) if cell_str(sheet_cell(rows, i, 1))) + 1
+ c1 = max(j for j, x in enumerate(rows[1]) if cell_str(x)) + 1
+ g = sheet_matrix_graph(rows, 4, r1, 4, c1,
+ lambda i: dict(name=join_cells(rows[i][1], rows[i][2]),
+ genus=cell_str(rows[i][1]),
+ species=cell_str(rows[i][2]),
+ origin=cell_str(rows[i][0])),
+ lambda j: dict(name=join_cells(rows[1][j], rows[2][j]),
+ genus=cell_str(rows[1][j]),
+ species=cell_str(rows[2][j]),
+ origin=cell_str(rows[0][j])),
+ "is_pollinator", True)
+ yield alt, g
+
+# Ollerton asclepiad-pollinator web (2003)
+# (formerly the entry `plant_pol_ollerton`)
+@dataset('pollination_ollerton',
+ [('ollerton_et_al_2003.xls', None, None)],
+ {'ollerton_et_al_2003.xls':
+ 'https://web.archive.org/web/20240723041110id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/ollerton_et_al_2003.xls'})
+def parse_pollination_ollerton(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["data"]
+ # plant genus and species in rows 0-1 (from column 5), pollinator
+ # order, genus, species and authority in columns 0-3, matrix of counts
+ # from row 3 and column 5
+ g = sheet_matrix_graph(rows, 3, 59, 5, 14,
+ lambda i: dict(name=join_cells(rows[i][1], rows[i][2]),
+ genus=cell_str(rows[i][1]),
+ species=cell_str(rows[i][2]),
+ authority=cell_str(rows[i][3]),
+ order=cell_str(rows[i][0])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j]),
+ authority="", order=""),
+ "is_pollinator", True)
+ yield alt, g
+
+# Ramirez & Brito plant-pollinator web (1983-1989)
+# (formerly the entry `plant_pol_ramirez`)
+@dataset('pollination_ramirez',
+ [('ramirez_1992.xls', None, None)],
+ {'ramirez_1992.xls':
+ 'https://web.archive.org/web/20240724221146id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/ramirez_1992.xls'})
+def parse_pollination_ramirez(name, files, alts):
+ def cell(x):
+ # 1: with pollen load, 2: without pollen load
+ d = cell_count(x)
+ if d is None:
+ return None
+ if x not in (1, 2):
+ raise ValueError(f"unexpected cell value: {x!r}")
+ return dict(pollen_load=(x == 1))
+
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["data"]
+ # "original matrix": pollinator genus and species in rows 0-1, plant
+ # genus and species in columns 0-1, matrix from row 3 and column 3
+ g = sheet_matrix_graph(rows, 3, 36, 3, 56,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_pollinator", False, cell=cell,
+ etypes=dict(pollen_load="bool"))
+ yield alt, g
+
+# Robertson plant-pollinator web
+# (formerly the entry `plant_pol_robertson`)
+@dataset('pollination_robertson',
+ [('robertson_1929.xls', None, None)],
+ {'robertson_1929.xls':
+ 'https://web.archive.org/web/20100810080125id_/http://www.nceas.ucsb.edu/interactionweb/data/plant_pollinator/excel/robertson_1929.xls'})
+def parse_pollination_robertson(name, files, alts):
+ 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, "rb")) for fn in fnames]
+
+
+ with tempfile.TemporaryDirectory(dir="./cache/temp") as tdir:
+ with open(f"{tdir}/dump.xls", "wb") as fw:
+ shutil.copyfileobj(fs[0], fw)
+ subprocess.run(["localc", "--convert-to", "xlsx",
+ f"dump.xls"], cwd=tdir, check=True)
+ wb = load_workbook(f"{tdir}/dump.xlsx", read_only=True)
+
+ g = Graph(directed=False)
+ g.vp.name = g.new_vp("string")
+ g.vp.family = g.new_vp("string")
+ g.vp.order = g.new_vp("string")
+ g.vp.is_pollinator = g.new_vp("bool")
+ vs = {}
+
+ m = pandas.DataFrame(wb.active.values).values
+ for i in range(0, 15265):
+ pname, pfam, polname, polorder, polfam = m[i + 1, :5]
+ if pname not in vs:
+ v = g.add_vertex()
+ g.vp.name[v] = pname
+ g.vp.family[v] = pfam
+ vs[pname] = v
+ else:
+ v = vs[pname]
+ if polname not in vs:
+ u = g.add_vertex()
+ g.vp.name[u] = polname
+ g.vp.family[u] = polfam
+ g.vp.order[u] = polorder
+ g.vp.is_pollinator[u] = True
+ vs[polname] = u
+ else:
+ u = vs[polname]
+ e = g.add_edge(v, u)
+
+ yield alt, g
+
+# Santos social bee and wasp-plant web (1996-1997)
+# (formerly the entry `plant_pol_santos`)
+@dataset('pollination_santos',
+ [('santos-et-al-2010.xls', None, None)],
+ {'santos-et-al-2010.xls':
+ 'https://web.archive.org/web/20240723044216id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/santos-et-al-2010.xls'})
+def parse_pollination_santos(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["matrix"]
+ # plant codes in row 0 (from column 2), group ("WASPS", "BEES", only
+ # in the first row of each group) and species in columns 0-1, binary
+ # matrix from row 1 and column 2
+ group = {}
+ for i in range(1, 26):
+ group[i] = cell_str(rows[i][0]).lower().rstrip("s") or group[i - 1]
+ g = sheet_matrix_graph(rows, 1, 26, 2, 53,
+ lambda i: dict(name=cell_str(rows[i][1]), group=group[i]),
+ lambda j: dict(name=cell_str(rows[0][j]), group=""),
+ "is_pollinator", True, cell=cell_presence)
+ yield alt, g
+
+# Schemske plant-pollinator web (1978)
+# (formerly the entry `plant_pol_schemske`)
+@dataset('pollination_schemske',
+ [('schemske_et_al_1978.xls', None, None)],
+ {'schemske_et_al_1978.xls':
+ 'https://web.archive.org/web/20240722123509id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/schemske_et_al_1978.xls'})
+def parse_pollination_schemske(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant genus and species in rows 0-1, pollinator genus and species
+ # in columns 0-1, matrix of counts from row 3 and column 3
+ g = sheet_matrix_graph(rows, 3, 35, 3, 10,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_pollinator", True)
+ yield alt, g
+
+# Small plant-pollinator web (1973)
+# (formerly the entry `plant_pol_small`)
+@dataset('pollination_small',
+ [('small_1976.xls', None, None)],
+ {'small_1976.xls':
+ 'https://web.archive.org/web/20240724040517id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/small_1976.xls'})
+def parse_pollination_small(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant genus and species in rows 0-1, pollinator genus and species
+ # in columns 0-1, matrix of counts from row 3 and column 3
+ g = sheet_matrix_graph(rows, 3, 37, 3, 16,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_pollinator", True)
+ yield alt, g
+
+# Vazquez & Simberloff plant-pollinator webs
+# (formerly the entry `plant_pol_vazquez`)
+@dataset('pollination_vazquez',
+ [('vazquez_2002.xls', 'Llao Llao', None),
+ ('vazquez_2002.xls', 'Cerro Lopez', None),
+ ('vazquez_2002.xls', 'Safariland', None),
+ ('vazquez_2002.xls', 'Arroyo Goye', None),
+ ('vazquez_2002.xls', 'Mascardi (nc)', None),
+ ('vazquez_2002.xls', 'Mascardi (c)', None),
+ ('vazquez_2002.xls', 'Quetrihue (nc)', None),
+ ('vazquez_2002.xls', 'Quetrihue (c)', None),
+ ('vazquez_2002.xls', 'All sites pooled', None)],
+ {'vazquez_2002.xls':
+ 'https://web.archive.org/web/20240123030314id_/https://iwdb.nceas.ucsb.edu/data/plant_pollinator/excel/vazquez_2002.xls'})
+def parse_pollination_vazquez(name, files, alts):
+ 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, "rb")) for fn in fnames]
+
+ with tempfile.TemporaryDirectory(dir="./cache/temp") as tdir:
+ with open(f"{tdir}/dump.xls", "wb") as fw:
+ shutil.copyfileobj(fs[0], fw)
+ subprocess.run(["localc", "--convert-to", "xlsx",
+ f"dump.xls"], cwd=tdir, check=True)
+ wb = load_workbook(f"{tdir}/dump.xlsx", read_only=True)
+
+ g = Graph(directed=False)
+ g.vp.idx = g.new_vp("int")
+ g.vp.pollinator = g.new_vp("bool")
+ g.ep.count = g.new_ep("int")
+
+ def add_bip_edges(m):
+ plts = {}
+ pols = {}
+ for i in range(1, m.shape[0]):
+ v = g.add_vertex()
+ g.vp.pollinator[v] = True
+ pols[m[i,0]] = v
+ g.vp.idx[v] = m[i,0]
+
+ for j in range(1, m.shape[1]):
+ u = plts.get(m[0, j], None)
+ if u is None:
+ u = g.add_vertex()
+ g.vp.pollinator[u] = False
+ plts[m[0, j]] = u
+ g.vp.idx[u] = m[0, j]
+
+ if m[i,j] is None:
+ continue
+ if numpy.isnan(float(m[i,j])):
+ continue
+ x = int(m[i, j])
+ if x > 0:
+ e = g.add_edge(v, u)
+ g.ep.count[e] = x
+ return plts, pols
+
+ m = pandas.DataFrame(wb[alt].values).values
+ plts, pols = add_bip_edges(m[1:-3,:-2])
+
+ for ti, t in enumerate(["Plant sp", "Pollinator sp"]):
+ m = pandas.DataFrame(wb[t].values).values
+ vs = plts if ti == 0 else pols
+
+ for j in range(1, m.shape[1]):
+ p = m[0, j]
+ if p not in g.vp:
+ g.vp[p] = g.new_vp("string")
+ for i in range(1, m.shape[0]):
+ idx = m[i, 0]
+ if idx is None:
+ continue
+ g.vp[p][vs[idx]] = m[i, j]
+
+ yield alt, g
+
+# Blüthgen ant-nectary web in the Australian rainforest (2004)
+# (formerly the entry `plant_ant_bluthgen`)
+@dataset('ant_plant_bluthgen',
+ [('bluthgen_2004.xls', None, None)],
+ {'bluthgen_2004.xls':
+ 'https://web.archive.org/web/20240722160710id_/https://iwdb.nceas.ucsb.edu/data/ant_plant/excel_matrices/bluthgen_2004.xls'})
+def parse_ant_plant_bluthgen(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Tabelle1"]
+ # plant name, family, nectary type, life form and abundance in rows
+ # 0-4 (from column 4), ant name, subfamily and abundance in columns
+ # 0-2 (column 3 has row totals), matrix of counts from row 6 and
+ # column 4
+ g = sheet_matrix_graph(rows, 6, 47, 4, 55,
+ lambda i: dict(name=cell_str(rows[i][0]), family="",
+ subfamily=cell_str(rows[i][1]),
+ nectaries="", life_form="",
+ abundance=rows[i][2]),
+ lambda j: dict(name=cell_str(rows[0][j]),
+ family=cell_str(rows[1][j]), subfamily="",
+ nectaries=cell_str(rows[2][j]),
+ life_form=cell_str(rows[3][j]),
+ abundance=rows[4][j]),
+ "is_ant", True, vtypes=dict(abundance="int"))
+ yield alt, g
+
+# Davidson ant-myrmecophyte web (1985-1986)
+# (formerly the entry `plant_ant_davidson`)
+@dataset('ant_plant_davidson',
+ [('davidson_et_al_1989.xls', None, None)],
+ {'davidson_et_al_1989.xls':
+ 'https://web.archive.org/web/20240723194736id_/https://iwdb.nceas.ucsb.edu/data/ant_plant/excel_matrices/davidson_et_al_1989.xls'})
+def parse_ant_plant_davidson(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant genus and species in rows 0-1 (from column 3), ant genus and
+ # species in columns 0-1, matrix of counts from row 3 and column 3
+ g = sheet_matrix_graph(rows, 3, 21, 3, 11,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_ant", True)
+ yield alt, g
+
+# Davidson & Fisher ant-Cecropia web (1991)
+# (formerly the entry `plant_ant_davidson_fisher`)
+@dataset('ant_plant_davidson_fisher',
+ [('davidson_fisher_1991.xls', None, None)],
+ {'davidson_fisher_1991.xls':
+ 'https://web.archive.org/web/20240722103151id_/https://iwdb.nceas.ucsb.edu/data/ant_plant/excel_matrices/davidson&fisher_1991.xls'})
+def parse_ant_plant_davidson_fisher(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # ant genus and species in rows 0-1 (from column 2), plant genus and
+ # species in columns 0-1, matrix of counts from row 2 and column 2
+ g = sheet_matrix_graph(rows, 2, 8, 2, 6,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_ant", False)
+ yield alt, g
+
+# Fonseca & Ganade ant-myrmecophyte web (1990)
+# (formerly the entry `plant_ant_fonseca`)
+@dataset('ant_plant_fonseca',
+ [('fonseca_ganade.xls', None, None)],
+ {'fonseca_ganade.xls':
+ 'https://web.archive.org/web/20240723014624id_/https://iwdb.nceas.ucsb.edu/data/ant_plant/excel_matrices/fonseca&ganade.xls'})
+def parse_ant_plant_fonseca(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["All"]
+ # plant genus and species in rows 0-1 (from column 2), ant genus and
+ # species in columns 0-1, matrix of counts from row 3 and column 2
+ g = sheet_matrix_graph(rows, 3, 28, 2, 18,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_ant", True)
+ yield alt, g
+
+# Joern grasshopper-plant webs (1974-1975)
+# (formerly the entry `plant_herb_joern`)
+@dataset('herbivory_joern',
+ [('joern_1979_altuda.xls', 'altuda', (25, 54)),
+ ('joern_1979_marathon.xls', 'marathon', (27, 56))],
+ {'joern_1979_altuda.xls':
+ 'https://web.archive.org/web/20240724034641id_/https://iwdb.nceas.ucsb.edu/data/plant_herbivore/excel_matrices/joern_1979_altuda.xls',
+ 'joern_1979_marathon.xls':
+ 'https://web.archive.org/web/20240724173434id_/https://iwdb.nceas.ucsb.edu/data/plant_herbivore/excel_matrices/joern_1979_marathon.xls'})
+def parse_herbivory_joern(name, files, alts):
+ for fname, alt, (r1, c1) in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = list(read_xls(f).values())[0]
+ # plant genus and species in rows 0-1 (from column 2), herbivore
+ # genus and species in columns 0-1, binary matrix from row 3 and
+ # column 2
+ g = sheet_matrix_graph(rows, 3, r1, 2, c1,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_herbivore", True, cell=cell_presence)
+ yield alt, g
+
+# Leather Prunus-macrolepidoptera webs of Britain and Finland (1991)
+# (formerly the entry `plant_herb_leather`)
+@dataset('herbivory_leather',
+ [('leather_1991_britain.xls', 'britain', (91, 9)),
+ ('leather_1991_finland.xls', 'finland', (67, 8))],
+ {'leather_1991_britain.xls':
+ 'https://web.archive.org/web/20240723222521id_/https://iwdb.nceas.ucsb.edu/data/plant_herbivore/excel_matrices/leather_1991_britain.xls',
+ 'leather_1991_finland.xls':
+ 'https://web.archive.org/web/20240723224927id_/https://iwdb.nceas.ucsb.edu/data/plant_herbivore/excel_matrices/leather_1991_finland.xls'})
+def parse_herbivory_leather(name, files, alts):
+ for fname, alt, (r1, c1) in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = list(read_xls(f).values())[0]
+ # plant genus and species in rows 0-1 (from column 3), herbivore
+ # genus and species in columns 0-1, binary matrix from row 3 and
+ # column 3
+ g = sheet_matrix_graph(rows, 3, r1, 3, c1,
+ lambda i: dict(name=join_cells(rows[i][0], rows[i][1]),
+ genus=cell_str(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_herbivore", True, cell=cell_presence)
+ yield alt, g
+
+# Beehler bird-fruit web (1978-1980)
+# (formerly the entry `seed_disp_beehler`)
+@dataset('seed_dispersal_beehler',
+ [('beehler_1983.xls', None, None)],
+ {'beehler_1983.xls':
+ 'https://web.archive.org/web/20240723075726id_/https://iwdb.nceas.ucsb.edu/data/seed_dispersal/excel_matrices/beehler_1983.xls'})
+def parse_seed_dispersal_beehler(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant names in row 0 (from column 4), bird common names in column
+ # 0, matrix of counts from row 4 and column 4
+ g = sheet_matrix_graph(rows, 4, 13, 4, 35,
+ lambda i: dict(name=cell_str(rows[i][0])),
+ lambda j: dict(name=cell_str(rows[0][j])),
+ "is_bird", True)
+ yield alt, g
+
+# Poulin bird-fruit webs of Miconia and Psychotria (1999)
+# (formerly the entry `seed_disp_poulin`)
+@dataset('seed_dispersal_poulin',
+ [('poulin_1999.xls', 'miconia', 'Miconia'),
+ ('poulin_1999.xls', 'psychotria', 'Psychotria')],
+ {'poulin_1999.xls':
+ 'https://web.archive.org/web/20240723014200id_/https://iwdb.nceas.ucsb.edu/data/seed_dispersal/excel_matrices/poulin_1999.xls'})
+def parse_seed_dispersal_poulin(name, files, alts):
+ for fname, alt, sheet in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fname, "rb") as f:
+ sheets = read_xls(f)
+ # full bird genus names in both sheets, by initial
+ genera = {}
+ for rows in sheets.values():
+ for r in rows[3:]:
+ x = cell_str(r[0])
+ if x and not x.endswith("."):
+ genera.setdefault(x[0], set()).add(x)
+ def genus(x):
+ x = cell_str(x)
+ if x.endswith("."):
+ assert len(genera[x[0]]) == 1
+ x = list(genera[x[0]])[0]
+ return x
+ rows = sheets[sheet]
+ # plant genus and species in rows 0-1 (from column 2), bird genus and
+ # species in columns 0-1, matrix of counts from row 3 and column 2
+ r1 = max(i for i, r in enumerate(rows) if cell_str(r[0])) + 1
+ c1 = max(j for j, x in enumerate(rows[1]) if cell_str(x)) + 1
+ g = sheet_matrix_graph(rows, 3, r1, 2, c1,
+ lambda i: dict(name=join_cells(genus(rows[i][0]), rows[i][1]),
+ genus=genus(rows[i][0]),
+ species=cell_str(rows[i][1])),
+ lambda j: dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]),
+ species=cell_str(rows[1][j])),
+ "is_bird", True)
+ yield alt, g
+
+# Schleuning plant-frugivore web in Kakamega Forest (2007-2008)
+# (formerly the entry `seed_disp_schleuning`)
+@dataset('seed_dispersal_schleuning',
+ [('schleuning-et-al-2010.xls', None, None)],
+ {'schleuning-et-al-2010.xls':
+ 'https://web.archive.org/web/20240723061133id_/https://iwdb.nceas.ucsb.edu/data/seed_dispersal/excel_matrices/schleuning-et-al-2010.xls'})
+def parse_seed_dispersal_schleuning(name, files, alts):
+ import re
+
+ def same_name(ab, full):
+ # common names in the matrix are abbreviated (e.g. "Yellow-whisk.
+ # Greenbul" for "Yellow-whiskered Greenbul")
+ a = [t for t in re.split(r"[ \-]+", ab.lower()) if t]
+ f = [t for t in re.split(r"[ \-]+", full.lower()) if t]
+ if len(a) == len(f) and all(x == y or (x.endswith(".") and y.startswith(x[:-1]))
+ for x, y in zip(a, f)):
+ return True
+ return re.sub(r"[ \-]", "", ab.lower()) == re.sub(r"[ \-]", "", full.lower())
+
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["overall"]
+ # plant code, forest type, stratum and height in rows 4-7 (columns
+ # 5-37); frugivore common name, diet specialization and forest
+ # dependence in columns 1-3 (rows 9-96); matrix of interaction
+ # frequencies from row 9 and column 5; tables of scientific names in
+ # columns 40-42 (plants) and 47-52 (frugivores)
+ plants = {cell_str(rows[i][40]): cell_str(rows[i][42])
+ for i in range(6, len(rows)) if cell_str(sheet_cell(rows, i, 40))}
+ animals = [(cell_str(rows[i][47]), cell_str(rows[i][52]))
+ for i in range(6, len(rows)) if cell_str(sheet_cell(rows, i, 47))]
+ def animal(i):
+ ab = cell_str(rows[i][1])
+ m = [x for x in animals if same_name(ab, x[0])]
+ assert len(m) == 1, ab
+ return dict(name=m[0][1], common_name=m[0][0], code="",
+ forest_type="", stratum="", height=numpy.nan,
+ diet=cell_str(rows[i][2]),
+ forest_dependence=cell_str(rows[i][3]))
+ g = sheet_matrix_graph(rows, 9, 97, 5, 38, animal,
+ lambda j: dict(name=plants[cell_str(rows[4][j])],
+ common_name="", code=cell_str(rows[4][j]),
+ forest_type=cell_str(rows[5][j]),
+ stratum=cell_str(rows[6][j]),
+ height=rows[7][j], diet="",
+ forest_dependence=""),
+ "is_frugivore", True, vtypes=dict(height="double"))
+ yield alt, g
+
+# Snow & Snow bird-fruit web (1988)
+# (formerly the entry `seed_disp_snow`)
+@dataset('seed_dispersal_snow',
+ [('snow_snow_1988.xls', None, None)],
+ {'snow_snow_1988.xls':
+ 'https://web.archive.org/web/20240722142254id_/https://iwdb.nceas.ucsb.edu/data/seed_dispersal/excel_matrices/snow&snow_1988.xls'})
+def parse_seed_dispersal_snow(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant common name, genus and species in rows 0-2 (from column 4),
+ # bird common name, genus and species in columns 0-2, matrix of counts
+ # from row 4 and column 4
+ g = sheet_matrix_graph(rows, 4, 24, 4, 39,
+ lambda i: dict(name=cell_str(rows[i][0]),
+ genus=cell_str(rows[i][1]),
+ species=cell_str(rows[i][2])),
+ lambda j: dict(name=cell_str(rows[0][j]),
+ genus=cell_str(rows[1][j]),
+ species=cell_str(rows[2][j])),
+ "is_bird", True)
+ yield alt, g
+
+# Sorensen bird-fruit web (1981)
+# (formerly the entry `seed_disp_sorensen`)
+@dataset('seed_dispersal_sorensen',
+ [('sorensen_1981.xls', None, None)],
+ {'sorensen_1981.xls':
+ 'https://web.archive.org/web/20240723180151id_/https://iwdb.nceas.ucsb.edu/data/seed_dispersal/excel_matrices/sorensen_1981.xls'})
+def parse_seed_dispersal_sorensen(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Sheet1"]
+ # plant common names in row 0 (from column 4), bird common names in
+ # column 0, matrix of counts from row 4 and column 4
+ g = sheet_matrix_graph(rows, 4, 18, 4, 16,
+ lambda i: dict(name=cell_str(rows[i][0])),
+ lambda j: dict(name=cell_str(rows[0][j])),
+ "is_bird", True)
+ yield alt, g
+
+# Anemonefish-sea anemone web (2007)
+# (formerly the entry `anemone_fish_ollerton`)
+@dataset('anemone_fish_ollerton',
+ [('anemonefish.xls', None, None)],
+ {'anemonefish.xls':
+ 'https://web.archive.org/web/20100807065224id_/http://www.nceas.ucsb.edu/interactionweb/data/anemone_fish/anemonefish.xls'})
+def parse_anemone_fish_ollerton(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ sheets = read_xls(f)
+ rows = sheets["Anemonefish-anemone interaction"]
+ drows = sheets["Distributional range"]
+ # anemone names in row 13 (from column 3); fish genus (given only in
+ # the row labelled "Amphiprion spp:" and for Premnas) and species in
+ # columns 1-2; binary matrix from row 14 and column 3
+ dist = {}
+ for r in drows[3:]:
+ if cell_str(r[1]):
+ genus = "Premnas" if cell_str(r[0]) == "Premnas" else "Amphiprion"
+ dist[join_cells(genus, r[1])] = cell_str(r[2])
+ if cell_str(sheet_cell([r], 0, 4)):
+ dist[cell_str(r[4])] = cell_str(r[5])
+ def fish(i):
+ genus = "Premnas" if cell_str(rows[i][1]) == "Premnas" else "Amphiprion"
+ n = join_cells(genus, rows[i][2])
+ return dict(name=n, distribution=dist[n])
+ g = sheet_matrix_graph(rows, 14, 40, 3, 13, fish,
+ lambda j: dict(name=cell_str(rows[13][j]),
+ distribution=dist[cell_str(rows[13][j])]),
+ "is_fish", True, cell=cell_presence)
+ yield alt, g
+
+# Anemonefish-sea anemone webs in the Manado region (2010)
+# (formerly the entry `anemone_fish_ricciardi`)
+ricciardi_sites = ['Bahowo', 'Bajo', 'Batu Kapal', 'Bualo', 'Fukui', 'Jalan m.',
+ 'Johnson', 'Kasegaran', 'Likuan 1', 'Mandolin', 'Mapia', 'Mike',
+ 'Sachiko', 'T. Kopi', 'T. Pisok', 'Timur']
+@dataset('anemone_fish_ricciardi',
+ [('ricciardi-et-al-2010.xls', site, None) for site in ricciardi_sites + ['regional']],
+ {'ricciardi-et-al-2010.xls':
+ 'https://web.archive.org/web/20240723113907id_/https://iwdb.nceas.ucsb.edu/data/anemone_fish/ricciardi-et-al-2010.xls'})
+def parse_anemone_fish_ricciardi(name, files, alts):
+ for fname, alt, fmt in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = list(read_xls(f).values())[0]
+ # one block per site, after the line "Sites:": a header row with the
+ # site name in column 0 and the fish species from column 2, followed
+ # by one row per anemone species (name in column 1) with a binary
+ # vector, and an empty row
+ start = [i for i, r in enumerate(rows) if cell_str(r[0]) == "Sites:"][0]
+ edges = {}
+ i = start + 1
+ found = set()
+ while i < len(rows):
+ site = cell_str(rows[i][0])
+ fish = [(j, cell_str(x)) for j, x in enumerate(rows[i]) if j >= 2 and cell_str(x)]
+ i += 1
+ while i < len(rows) and cell_str(sheet_cell(rows, i, 1)):
+ anemone = cell_str(rows[i][1])
+ for j, fname_ in fish:
+ if cell_presence(rows[i][j]) is not None and (alt == "regional" or site == alt):
+ k = (fname_, anemone)
+ edges[k] = edges.get(k, 0) + 1
+ i += 1
+ found.add(site)
+ while i < len(rows) and not cell_str(sheet_cell(rows, i, 0)):
+ i += 1
+ assert found == set(ricciardi_sites)
+ g = Graph(directed=False)
+ g.vp.name = g.new_vp("string")
+ g.vp.is_fish = g.new_vp("bool")
+ if alt == "regional":
+ g.ep.sites = g.new_ep("int")
+ vs = {}
+ def get_v(n, is_fish):
+ if n not in vs:
+ v = vs[n] = g.add_vertex()
+ g.vp.name[v] = n
+ g.vp.is_fish[v] = is_fish
+ return vs[n]
+ for (f_, a), c in edges.items():
+ e = g.add_edge(get_v(f_, True), get_v(a, False))
+ if alt == "regional":
+ g.ep.sites[e] = c
+ yield alt, g
+
+# Canadian freshwater fish-parasite webs (1955-1983)
+# (formerly the entry `fish_parasites_canada`)
+@dataset('host_parasite_canada',
+ [('aishihik_lake.xls', 'aishihik', None),
+ ('cold_lake.xls', 'cold', None),
+ ('lake_of_the_woods.xls', 'woods', None),
+ ('mcgregor_river.xls', 'mcgregor', None),
+ ('parsnip_river.xls', 'parsnip', None),
+ ('sbay_lake_huron.xls', 'huron', None),
+ ('smallwood_reservoir.xls', 'smallwood', None)],
+ {'aishihik_lake.xls':
+ 'https://web.archive.org/web/20240724192137id_/https://iwdb.nceas.ucsb.edu/data/host_parasite/excel_matrices/aishihik_lake.xls',
+ 'cold_lake.xls':
+ 'https://web.archive.org/web/20240724150440id_/https://iwdb.nceas.ucsb.edu/data/host_parasite/excel_matrices/cold_lake.xls',
+ 'lake_of_the_woods.xls':
+ 'https://web.archive.org/web/20240724191140id_/https://iwdb.nceas.ucsb.edu/data/host_parasite/excel_matrices/lake_of_the_woods.xls',
+ 'mcgregor_river.xls':
+ 'https://web.archive.org/web/20240724173210id_/https://iwdb.nceas.ucsb.edu/data/host_parasite/excel_matrices/mcgregor_river.xls',
+ 'parsnip_river.xls':
+ 'https://web.archive.org/web/20240724151832id_/https://iwdb.nceas.ucsb.edu/data/host_parasite/excel_matrices/parsnip_river.xls',
+ 'sbay_lake_huron.xls':
+ 'https://web.archive.org/web/20240724145013id_/https://iwdb.nceas.ucsb.edu/data/host_parasite/excel_matrices/sbay_lake_huron.xls',
+ 'smallwood_reservoir.xls':
+ 'https://web.archive.org/web/20240724173001id_/https://iwdb.nceas.ucsb.edu/data/host_parasite/excel_matrices/smallwood_reservoir.xls'})
+def parse_host_parasite_canada(name, files, alts):
+ for fname, alt, fmt in files:
+ if alts is not None and alt not in alts:
+ continue
+ with open_upstream_file(name, fname, "rb") as f:
+ sheets = read_xls(f)
+ # parasite genus and species in rows 0-1, host name and sample size
+ # in columns 0-1 (in Cold Lake: name, relative abundance and sample
+ # size in columns 0-2), prevalence matrix from row 3 and the column
+ # after the parasite numbers; the intensity matrix, if present, has
+ # the same layout ("NA": not available)
+ rows = sheets["prevalence"]
+ irows = sheets.get("intensity")
+ cold = alt == "cold"
+ c0 = 4 if cold else 3
+ r1 = max(i for i, r in enumerate(rows) if cell_str(r[0])) + 1
+ c1 = max(j for j, x in enumerate(rows[0]) if cell_str(x)) + 1
+ if irows is not None:
+ for i in range(r1):
+ assert irows[i][:c1] == rows[i][:c1] or i >= 3
+ assert irows[i][:c0] == rows[i][:c0]
+
+ def cell(i, j):
+ d = cell_count(rows[i][j], "prevalence")
+ if d is not None and irows is not None:
+ x = irows[i][j]
+ d["intensity"] = numpy.nan if x == "NA" else x
+ assert x == "NA" or (is_number(x) and x > 0)
+ return d
+
+ ri = list(range(3, r1))
+ cj = list(range(c0, c1))
+ def host(i):
+ d = dict(name=cell_str(rows[i][0]), genus="", species="",
+ sample_size=rows[i][c0 - 2])
+ if cold:
+ d["relative_abundance"] = rows[i][1]
+ return d
+ def parasite(j):
+ d = dict(name=join_cells(rows[0][j], rows[1][j]),
+ genus=cell_str(rows[0][j]), species=cell_str(rows[1][j]),
+ sample_size=0)
+ if cold:
+ d["relative_abundance"] = numpy.nan
+ return d
+ g = interaction_graph([host(i) for i in ri], [parasite(j) for j in cj],
+ lambda i, j: cell(ri[i], cj[j]), "is_parasite", False,
+ vtypes=dict(sample_size="int",
+ relative_abundance="double"),
+ etypes=dict(prevalence="double", intensity="double"))
+ yield alt, g
+
+# Carpinteria Salt Marsh food web with parasites (2006)
+# (formerly the entry `foodweb_carpinteria`)
+@dataset('food_web_lafferty',
+ [('carpinteria.xls', None, None)],
+ {'carpinteria.xls':
+ 'https://web.archive.org/web/20240723024657id_/https://iwdb.nceas.ucsb.edu/data/predator_prey/excel_matrices/carpinteria.xls'})
+def parse_food_web_lafferty(name, files, alts):
+ for fname, alt, fmt in files:
+ with open_upstream_file(name, fname, "rb") as f:
+ rows = read_xls(f)["Matrix"]
+ # consumers in columns 2-129 (group code in row 1, name in row 2),
+ # resources in rows 3-130 (kind in column 0, name in column 1), in the
+ # same order; nonzero cells give the link type
+ n = 128
+ for k in range(n):
+ assert cell_str(rows[3 + k][1]) == cell_str(rows[2][2 + k])
+ g = Graph(directed=True)
+ g.add_vertex(n)
+ g.vp.name = g.new_vp("string")
+ g.vp.kind = g.new_vp("string")
+ g.vp.group = g.new_vp("string")
+ g.ep.link_type = g.new_ep("double")
+ for k in range(n):
+ g.vp.name[k] = cell_str(rows[2][2 + k])
+ g.vp.kind[k] = cell_str(rows[3 + k][0])
+ g.vp.group[k] = cell_str(rows[1][2 + k])
+ for i in range(n):
+ for j in range(n):
+ x = rows[3 + i][2 + j]
+ if cell_count(x) is None:
+ continue
+ e = g.add_edge(i, j)
+ g.ep.link_type[e] = x
+ yield alt, g
+
+# Freshwater stream webs
+# (formerly the entry `fresh_webs`)
+@dataset('food_web_thompson',
+ [('thomps_towns_text.zip:AkatoreAtxt.txt', 'AkatoreA', 'matrix'),
+ ('thomps_towns_text.zip:AkatoreBtxt.txt', 'AkatoreB', 'matrix'),
+ ('thomps_towns_text.zip:Berwicktxt.txt', 'Berwick', 'matrix'),
+ ('thomps_towns_text.zip:Blackrocktxt.txt', 'Blackrock', 'matrix'),
+ ('thomps_towns_text.zip:Broadtxt.txt', 'Broad', 'matrix'),
+ ('thomps_towns_text.zip:Cantontxt.txt', 'Canton', 'matrix'),
+ ('thomps_towns_text.zip:Catlinstxt.txt', 'Catlins', 'matrix'),
+ ('thomps_towns_text.zip:Coweeta1txt.txt', 'Coweeta1', 'matrix'),
+ ('thomps_towns_text.zip:Coweeta17txt.txt', 'Coweeta17', 'matrix'),
+ ('thomps_towns_text.zip:DempstersAutxt.txt', 'DempstersAu', 'matrix'),
+ ('thomps_towns_text.zip:DempstersSptxt.txt', 'DempstersSp', 'matrix'),
+ ('thomps_towns_text.zip:DempstersSutxt.txt', 'DempstersSu', 'matrix'),
+ ('thomps_towns_text.zip:Germantxt.txt', 'German', 'matrix'),
+ ('thomps_towns_text.zip:Healytxt.txt', 'Healy', 'matrix'),
+ ('thomps_towns_text.zip:Kyeburntxt.txt', 'Kyeburn', 'matrix'),
+ ('thomps_towns_text.zip:LilKyeburntxt.txt', 'LilKyeburn', 'matrix'),
+ ('thomps_towns_text.zip:Martinstxt.txt', 'Martins', 'matrix'),
+ ('thomps_towns_text.zip:Narrowdaletxt.txt', 'Narrowdale', 'matrix'),
+ ('thomps_towns_text.zip:NorthColtxt.txt', 'NorthCol', 'matrix'),
+ ('thomps_towns_text.zip:Powdertxt.txt', 'Powder', 'matrix'),
+ ('thomps_towns_text.zip:Stonytxt.txt', 'Stony', 'matrix'),
+ ('thomps_towns_text.zip:SuttonAutxt.txt', 'SuttonAu', 'matrix'),
+ ('thomps_towns_text.zip:SuttonSptxt.txt', 'SuttonSp', 'matrix'),
+ ('thomps_towns_text.zip:SuttonSutxt.txt', 'SuttonSu', 'matrix'),
+ ('thomps_towns_text.zip:Troytxt.txt', 'Troy', 'matrix'),
+ ('thomps_towns_text.zip:Venlawtxt.txt', 'Venlaw', 'matrix')],
+ {'thomps_towns_text.zip':
+ 'https://web.archive.org/web/20060109082720id_/http://www.nceas.ucsb.edu:80/interactionweb/data/predator_prey/text_matrices/thomps_towns_text.zip'})
+def parse_food_web_thompson(name, files, alts):
+ 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, "rb")) for fn in fnames]
+ g = parse_graph(fs, fmt, directed=True)
+ yield alt, g
+
+files = [(fname, alt_name(key, alt), fmt)
+ for key, (f, dfiles) in datasets.items()
+ for fname, alt, fmt in dfiles]
+
+# robertson_1929.xls is an old (BIFF4) Excel file, which lacks the header
+# that fetch_archived_files() checks for .xls files
+unchecked = ['robertson_1929.xls']
+
+def fetch_upstream(force=False):
+ name = __name__.split(".")[-1]
+ fetch_archived_files(name, {k: v for k, v in archived_urls.items()
+ if k not in unchecked}, force, tries=3)
+ for fname in unchecked:
+ prefix = archived_urls[fname].rsplit("/", 1)[0]
+ fetch_upstream_files(name, prefix, [(fname, None, None)], force)
+
+# (`relative_abundance` and `intensity` exist only in host_parasite_canada_*)
+coerce = dict(vforce=dict(relative_abundance='double'),
+ eforce=dict(intensity='double'))
+
+@cache_network()
+@coerce_props(**coerce)
+@annotate()
+def parse(alts=None):
+ name = __name__.split(".")[-1]
+ for key, (f, dfiles) in datasets.items():
+ dfiles = [x for x in dfiles if alts is None or alt_name(key, x[1]) in alts]
+ if not dfiles:
+ continue
+ for alt, g in f(name, dfiles, [x[1] for x in dfiles]):
+ # The partition property of bipartite networks is `is_<kind>`
+ if "pollinator" in g.vp and "is_pollinator" not in g.vp:
+ g.vp.is_pollinator = g.vp.pollinator
+ del g.vp["pollinator"]
+ yield alt_name(key, alt), g