Electronic SupplementaryMaterial
Title: Frugivorous fish: Extremely long-distance seed dispersal by a species at risk
Authors: Jill T. Anderson1,2,*, Tim Nuttle3, Joe S. Saldaña Rojas4, Thomas H. Pendergast5, Alexander S. Flecker1
1Department of Ecology and Evolutionary Biology, Corson Hall, Cornell University, Ithaca, NY 14853. Email address for Alex Flecker: .
2Current address: Department of Biology, PO Box 90338, Duke University, Durham, NC, 27708
3Department of Biology, Indiana University of Pennsylvania, 114 Weyandt Hall, Indiana, PA 15705. Email:
4 Red Ambiental Loretana, RAL, Pasaje Buena Vista 190, Iquitos, Perú. Email:
5Department of Biological Sciences, University of Pittsburgh, A234 Langley Hall, 4249 Fifth Avenue, Pittsburgh, PA 15260. Email:
* Corresponding author
E-mail:
Tel: +1-919-668-6590
Fax: +1-919-660-7293
1
Appendix Figure S1: Cumulative gut retention times for 5 species of seeds fed to captive Colossoma macropomum. Gut
retention differed significantly by seed species (Cox Proportional Hazards Model; χ2=404.7, d.f.=4 ; p<0.0001).
Appendix Figure S2: Seed dispersal by Colossoma for four species of Amazonian plants: (A) Annona muricata;(B)
Cayaponia tubulosa; (C) Cayaponia cruegeri; (D) Duroia duckei. Compare with Figure 1 in main text.Note that the scale of the y-
axis differs slightly in each panel.
AppendixTable S1: Duration of radiotelemetry follows and total distance tracked, as well as the final distance from the point of release, which is of key importance in modeling seed dispersal kernels. Standard length and weight were only measured for fish in 2005 and 2006.
year / fish number / Standard length (cm) / Weight (g) / length of follow (hours) / Total distance moved (m) / Distance moved from the origin (m)2004 / 543 / 22.35 / 120.5 / 70.2
2004 / 503 / 121.4 / 2306.9 / 165.7
2004 / 403 / 46.5 / 552.0 / 504.7
2004 / 603 / 111.3 / 7680.1 / 2937.2
2004 / 323 / 117.3 / 6258.7 / 2287.7
2005 / 524 / 26 / 750 / 706 / 18269.1 / 1892.6
2005 / 423 / 26 / 850 / 226 / 18750.3 / 2098.8
2005 / 363 / 26 / 900 / 130 / 8746.9 / 280.0
2005 / 302 / 29 / 1150 / 226 / 12100.4 / 1675.5
2005 / 483 / 27 / 825 / 226 / 5701.3 / 102.4
2005 / 383 / 26 / 800 / 130 / 4184.4 / 286.5
2005 / 583 / 25 / 750 / 202 / 9079.0 / 1069.3
2006 / 16 / 41 / 2700 / 333 / 24159.0 / 5452.2
2006 / 34 / 36 / 2000 / 291 / 16109.3 / 2074.5
2006 / 55 / 37 / 2000 / 350 / 25699.7 / 562.8
2006 / 98 / 40 / 2900 / 2 / 93.5 / 58.3
2006 / 117 / 40 / 2300 / 363.5 / 25340.2 / 1196.8
2006 / 155 / 45 / 2900 / 100 / 9336.4 / 2561.1
2006 / 175 / 47 / 2900 / 52.25 / 1030.3 / 58.5
2006 / 195 / 38 / 1700 / 340.5 / 16893.7 / 5950.1
2006 / 645 / 42 / 2300 / 81.5 / 4685.2 / 32.2
2006 / 744 / 39 / 1900 / 342.5 / 9864.2 / 2037.8
2006 / 994 / 43 / 2600 / 122 / 13744.8 / 1344.4
2006 / 974 / 28 / 1800 / 234 / 10579.4 / 1852.9
AppendixTable S2: Number of seeds of each species fed to each fish in the gut retention time trials, and the percentage of seeds defecated intact. Sample sizes of Colossoma fish for each species of seed: n=5 in 2005, n= 3-5 adults and 4–5 juveniles in 2006. For the 2006 individuals, adults (3436.7 ±2030 g, mean ± SE, n=6 total) were more than twice as large as juveniles (548.9 ± 20.9 g, n = 9 total).
Species of seed / year / Replicate number / fish identification / Life history stage of fish / Number of days of trial / Number of seeds fed to fish / Number of seeds defecated intact / Percentage of seeds defecated intactCayaponia cruegeri / 2005 / 1 / Cm1 / adult / 3 / 15 / 15 / 100 %
Cayaponia cruegeri / 2005 / 1 / Cm2 / adult / 3 / 15 / 15 / 100 %
Cayaponia cruegeri / 2005 / 1 / Cm3 / adult / 3 / 15 / 15 / 100 %
Cayaponia cruegeri / 2005 / 1 / Cm4 / adult / 3 / 15 / 15 / 100 %
Cayaponia cruegeri / 2005 / 1 / Cm5 / adult / 3 / 15 / 15 / 100 %
Cayaponia cruegeri / 2005 / 2 / Cm1 / adult / 3 / 15 / 15 / 100 %
Cayaponia cruegeri / 2005 / 2 / Cm2 / adult / 3 / 15 / 15 / 100 %
Cayaponia cruegeri / 2005 / 2 / Cm3 / adult / 3 / 15 / 15 / 100 %
Cayaponia cruegeri / 2005 / 2 / Cm4 / adult / 3 / 15 / 15 / 100 %
Cayaponia cruegeri / 2005 / 2 / Cm5 / adult / 3 / 15 / 15 / 100 %
Cecropia latiloba / 2005 / 1 / Cm1 / adult / 6 / 204 / 204 / 100 %
Cecropia latiloba / 2005 / 1 / Cm2 / adult / 6 / 202 / 202 / 100 %
Cecropia latiloba / 2005 / 1 / Cm3 / adult / 6 / 200 / 141 / 70.5 %
Cecropia latiloba / 2005 / 1 / Cm4 / adult / 6 / 200 / 61 / 30.5 %
Cecropia latiloba / 2005 / 1 / Cm5 / adult / 6 / 200 / 150 / 75 %
Cecropia latiloba / 2005 / 2 / Cm1 / adult / 5 / 200 / 200 / 100 %
Cecropia latiloba / 2005 / 2 / Cm2 / adult / 5 / 200 / 200 / 100 %
Cecropia latiloba / 2005 / 2 / Cm3 / adult / 5 / 201 / 201 / 100 %
Cecropia latiloba / 2005 / 2 / Cm4 / adult / 5 / 201 / 201 / 100 %
Cecropia latiloba / 2005 / 2 / Cm5 / adult / 5 / 202 / 202 / 100 %
Cecropia latiloba / 2005 / 3 / Cm1 / adult / 6 / 202 / 202 / 100 %
Cecropia latiloba / 2005 / 3 / Cm2 / adult / 6 / 200 / 200 / 100 %
Cecropia latiloba / 2005 / 3 / Cm3 / adult / 6 / 200 / 200 / 100 %
Cecropia latiloba / 2005 / 3 / Cm4 / adult / 6 / 200 / 200 / 100 %
Cecropia latiloba / 2005 / 3 / Cm5 / adult / 6 / 202 / 202 / 100 %
Duroia duckei / 2005 / 1 / Cm1 / adult / 2 / 100 / 100 / 100 %
Duroia duckei / 2005 / 1 / Cm2 / adult / 2 / 100 / 100 / 100 %
Duroia duckei / 2005 / 1 / Cm3 / adult / 2 / 103 / 103 / 100 %
Duroia duckei / 2005 / 1 / Cm4 / adult / 2 / 101 / 101 / 100 %
Duroia duckei / 2005 / 1 / Cm5 / adult / 2 / 102 / 102 / 100 %
Duroia duckei / 2005 / 2 / Cm1 / adult / 2 / 100 / 100 / 100 %
Duroia duckei / 2005 / 2 / Cm2 / adult / 2 / 100 / 100 / 100 %
Duroia duckei / 2005 / 2 / Cm3 / adult / 2 / 100 / 100 / 100 %
Duroia duckei / 2005 / 2 / Cm4 / adult / 2 / 100 / 100 / 100 %
Duroia duckei / 2005 / 2 / Cm5 / adult / 2 / 100 / 100 / 100 %
Duroia duckei / 2005 / 3 / Cm1 / adult / 3 / 100 / 100 / 100 %
Duroia duckei / 2005 / 3 / Cm2 / adult / 3 / 101 / 101 / 100 %
Duroia duckei / 2005 / 3 / Cm3 / adult / 3 / 100 / 100 / 100 %
Duroia duckei / 2005 / 3 / Cm4 / adult / 3 / 101 / 101 / 100 %
Duroia duckei / 2005 / 3 / Cm5 / adult / 3 / 101 / 101 / 100 %
Annona muricata / 2006 / 1 / Cm1a / adult / 8 / 7 / 7 / 100 %
Annona muricata / 2006 / 1 / Cm2a / adult / 8 / 7 / 0 / 0
Annona muricata / 2006 / 1 / Cm6a / adult / 8 / 7 / 6 / 85.7 %
Annona muricata / 2006 / 1 / Cm8a / adult / 8 / 7 / 7 / 100 %
Annona muricata / 2006 / 1 / Cm2j / juvenile / 8 / 4 / 4 / 100%
Annona muricata / 2006 / 1 / Cm3j / juvenile / 8 / 4 / 4 / 100%
Annona muricata / 2006 / 1 / Cm7j / juvenile / 8 / 4 / 4 / 100 %
Annona muricata / 2006 / 1 / Cm8j / juvenile / 8 / 4 / 4 / 100 %
Annona muricata / 2006 / 1 / Cm9j / juvenile / 8 / 4 / 3 / 75 %
Cayaponia tubulosa / 2006 / 1 / Cm1a / adult / 12 / 5 / 4 / 80 %
Cayaponia tubulosa / 2006 / 1 / Cm2a / adult / 12 / 5 / 0 / 0 %
Cayaponia tubulosa / 2006 / 1 / Cm6a / adult / 12 / 5 / 3 / 60 %
Cayaponia tubulosa / 2006 / 1 / Cm7a / adult / 12 / 5 / 4 / 80 %
Cayaponia tubulosa / 2006 / 1 / Cm1j / juvenile / 11 / 3 / 3 / 100 %
Cayaponia tubulosa / 2006 / 1 / Cm4j / juvenile / 11 / 3 / 2 / 66.7%
Cayaponia tubulosa / 2006 / 1 / Cm6j / juvenile / 11 / 3 / 3 / 100 %
Cayaponia tubulosa / 2006 / 1 / Cm9j / juvenile / 11 / 3 / 2 / 66.7 %
Cecropia latiloba / 2006 / 1 / Cm1a / adult / 6 / 60 / 40 / 66.7 %
Cecropia latiloba / 2006 / 1 / Cm2a / adult / 6 / 60 / 60 / 100 %
Cecropia latiloba / 2006 / 1 / Cm4a / adult / 6 / 60 / 53 / 88.3 %
Cecropia latiloba / 2006 / 2 / Cm1a / adult / 6 / 60 / 60 / 100 %
Cecropia latiloba / 2006 / 2 / Cm2a / adult / 6 / 60 / 51 / 85 %
Cecropia latiloba / 2006 / 2 / Cm4a / adult / 6 / 60 / 59 / 98.3 %
Cecropia latiloba / 2006 / 3 / Cm1a / adult / 7 / 60 / 57 / 95 %
Cecropia latiloba / 2006 / 3 / Cm2a / adult / 7 / 70 / 70 / 100 %
Cecropia latiloba / 2006 / 3 / Cm4a / adult / 7 / 60 / 60 / 100 %
Duroia duckei / 2006 / 1 / Cm1a / adult / 6 / 60 / 60 / 100%
Duroia duckei / 2006 / 1 / Cm2a / adult / 6 / 60 / 55 / 91.7%
Duroia duckei / 2006 / 1 / Cm4a / adult / 6 / 60 / 44 / 73.3%
Duroia duckei / 2006 / 2 / Cm1a / adult / 6 / 70 / 70 / 100%
Duroia duckei / 2006 / 2 / Cm2a / adult / 6 / 70 / 69 / 98.6%
Duroia duckei / 2006 / 2 / Cm4a / adult / 6 / 70 / 65 / 92.9%
Duroia duckei / 2006 / 3 / Cm1a / adult / 6 / 60 / 60 / 100%
Duroia duckei / 2006 / 3 / Cm2a / adult / 6 / 60 / 60 / 100%
Duroia duckei / 2006 / 3 / Cm4a / adult / 6 / 60 / 55 / 91.7%
Duroia duckei / 2006 / 1 / Cm1j / juvenile / 6 / 60 / 42 / 70%
Duroia duckei / 2006 / 1 / Cm2j / juvenile / 6 / 60 / 60 / 100%
Duroia duckei / 2006 / 1 / Cm3j / juvenile / 6 / 60 / 57 / 95%
Duroia duckei / 2006 / 1 / Cm4j / juvenile / 6 / 60 / 58 / 96.7%
Duroia duckei / 2006 / 1 / Cm5j / juvenile / 6 / 60 / 23 / 38.3%
Duroia duckei / 2006 / 2 / Cm1j / juvenile / 6 / 60 / 58 / 96.7%
Duroia duckei / 2006 / 2 / Cm2j / juvenile / 6 / 60 / 56 / 93.3%
Duroia duckei / 2006 / 2 / Cm3j / juvenile / 6 / 60 / 56 / 93.3%
Duroia duckei / 2006 / 2 / Cm4j / juvenile / 6 / 60 / 60 / 100%
Duroia duckei / 2006 / 3 / Cm1j / juvenile / 6 / 60 / 56 / 93.3%
Duroia duckei / 2006 / 3 / Cm2j / juvenile / 6 / 60 / 55 / 91.7%
Duroia duckei / 2006 / 3 / Cm3j / juvenile / 6 / 60 / 52 / 86.7%
Duroia duckei / 2006 / 3 / Cm4j / juvenile / 6 / 60 / 59 / 98.3%
Duroia duckei / 2006 / 3 / Cm5j / juvenile / 6 / 60 / 60 / 100%
AppendixTable S3: Details on the studies used in the cumulative graph of seed dispersal distances
Fruigivore species / Plant species / Location / Figure from which data were extracted from the original study / Details about data and model / Citation3 birds: Myadestes melanops, Phainoptila melanoxantha and Semnornis frantzii / Phytolacca rivinoides, Witheringia solanacea and W. coccoloboides / Monteverde Cloud Forest Reserve, Costa Rica / Figure 8 / Matrix modeling using gut retention times from feeding trials and movement patterns from radiotelemetry data. / [1]
Ceratogymna cylindricus and C. atrata (hornbills) / 9 species (see their Figure 1) / Dja Reserve, Cameroon / average of species from Figure 1 / Matrix modeling using gut retention times from feeding trials and movement patterns from radiotelemetry data. / [2]
Odocoileus virginianus (white-tailed deer) / various / Figure 1 / Matrix modeling based on data culled from the literature of gut retention times and movement patterns from telemetry studies. / [3]
Cebus capucinus (white faced capuchin monkey) / gut retention time was unrelated to plant species / Barro Colorado Island, Panama / Figure 1 / Direct observations of individual monkeys, along with a gut retention time of 100 minutes, which was the time at which captive individuals defecated 75% of the seeds they consumed of various species. / [4]
Garrulus glandarius (European jay) / Quercus ilex / Sierra Nevada Protected Area, Spain / Figure 1: solid line, which represents dispersal distances averaged across microhabitat / Direct observations of jays dispersing acorns. / [5]
Casuarius casuarius (cassowary) / 11 species (listed in their Table 1) / Queensland, Australia / weighted model in Figure 6 / Matrix modeling using gut retention times from feeding trials and movement patterns from radiotelemetry data. / [6]
Ateles paniscus (spider monkey) / Virola calophylla / Manu National park, Peru / Data from Fig. 5 were provided by S. Russo / Simulation model based on movement pattern data (direct follows of foraging individuals). / [7]
Elephas maximus (Asian elephant) / Tamarindus indica / Myanmar and Sri Lanka / Figure 3 / Matrix modeling using gut retention times from feeding trials and movement patterns from radiotelemetry data. / [8]
Chelonoidis denticulata (tortoise) / a mixture of seeds, including Jacaratia spinosa and Genipa americana / Pará, Brazil / average of rainy and dry season dispersal in Figure 3 / Matrix modeling using gut retention times from feeding trials and movement patterns from radiotelemetry data and "spool-and-line-tracked" individuals. / [9]
Appendix Table S4: Average gut retention times of 5 species of seeds fed to captive Colossoma macropomum individuals. See Appendix Table S2 for details about gut retention time trials.
Species of seed / average gut retention time (hours) / Standard errorAnnona muricata / 88.6 / 7.6
Cayaponia cruegeri / 34.7 / 0.97
Cayaponia tubulosa / 147.3 / 10.3
Cecropia latiloba / 59.8 / 0.64
Duroia duckei / 39.7 / 0.55
AppendixTable S5: Effect of individual-level variation in movement patterns on modeled dispersal distances (n=15 wild-caught Colossoma individuals) for Cecropia latiloba seeds. Both the median and 95th percentile dispersal distances are provided.
Fish identification / Standard length (cm) / Weight (g) / 95th / Median (m)16 / 41 / 2700 / 5067.5 / 240.5
524 / 26 / 750 / 1810.8 / 79.1
34 / 36 / 2000 / 2190 / 175
55 / 37 / 2000 / 657.3 / 198.2
117 / 40 / 2300 / 1121.6 / 110.4
195 / 38 / 1700 / 364.4 / 127.9
302 / 29 / 1150 / 1559.2 / 119.8
363 / 26 / 900 / 457.1 / 90.7
423 / 26 / 850 / 2036.9 / 199.5
383 / 26 / 800 / 222.7 / 93.1
483 / 27 / 825 / 101.4 / 37.4
994 / 43 / 2600 / 1640.9 / 962.7
974 / 28 / 1800 / 527.4 / 215.6
744 / 39 / 1900 / 1135.9 / 149.2
583 / 25 / 750 / 1140.7 / 86.3
Mean / 1335.6 / 192.4
SE / 317.97 / 57.0
1
Simulation model code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define SCANLINE "%[^\n]\n" /* scanf format to read chars upto newline */
#define PI 3.1415953589
#define NUMFISH 10// 24 for Cecropia, 37 for Duoria, 10 for Cayoponia cruegeri,7 for Cayoponia tubulosa, 8 for Anonilla
#define NUMLOCS 5000// size of array for telemetry data
#define AVG_SE 12.0// the average telemetry error to use when telemetry error data are missing
#define min(t,u)(t < u ? t : u)
#define max(t,u)(t > u ? t : u)
/* Structure to put the fish telemetry data in */
#ifdef notdef
// Miracle C either doesn't like structures or I'm doing something wrong here
typedef struct FL{
int fishnum;
float utm_x, utm_y,time;
char habitat[12];
}FishLocation;
#endif
/* prototypes */
void disperse(int iteration);
FILE* OpenFilePrompt(char *name);
FILE* OpenFile(char *name, char *MODE, char *input);
void ReadControl(char controlfname[], char telemfilename[], char guttimefilename[],char outputfname[], char header[]);
void ReadTelem(char telemfilename[]);
void ReadGut(char guttimefile[]);
voidCalcCumulativeGutTime();
floatTrackFish(char start_patch, char end_patch); // pass back which patch the fish start and end up in
/* new random number generator */
/* define desired integer type */
/* external libraries */
/* in ranrotb file, which is included above
typedef unsigned int my_uint;
void RanrotAInit(my_uint seed);
float RanrotA(void);
int iRanrotA(int,int);
*/
/*------GLOBAL VARIABLES------*/
int seed; /*for the random number generator */
int iterations;/*number of iterations to run the model */
/* telemetry data */
int Fish_num[NUMLOCS];
float Fish_x[NUMLOCS], Fish_y[NUMLOCS], Fish_time[NUMLOCS], Fish_SEx[NUMLOCS], Fish_SEy{NUMLOCS];
char Fish_habitat[NUMLOCS][12];
char Fish_patch[NUMLOCS][12];
int LastTelem;
/*gut retention time data */
float gut[220][NUMFISH];
int LastTime;
/*------*/
/* MAIN */
/*------*/
int main(int argc, char *argv[])
{
FILE *outfile;
char controlfile[100],
header[120],// holds the header from the control file to put in the output file
telemfile[100],/* file names */
guttimefile[100],
outputfile[120];/* root then tree output */
char start_patch[10], end_pathc[10]
float distance;
int i = 0; //iteration counter
int j = 0; //iteration counter
int fishnum = -9999;// local variable to hold the fish number for output file
if(argc <= 1){/* if controlfile name was not enterred on command line */
printf("Enter control file name: ");
scanf("%s",controlfile);
printf("You entered: %s \n",controlfile);
/* printf("Enter year (e.g., 1978) of wind file to read: "); */
/* scanf("%d",&WindYear); */
}
else strcpy(controlfile,argv[1]);
ReadControl(controlfile,telemfile,guttimefile,outputfile,header);
srand(seed);// seed the random number generator;
ReadTelem(telemfile);
ReadGut(guttimefile);
CalcCumulativeGutTime();
outfile = OpenFile(outputfile,"w"," output");// open the output file
// Iterate the model
//for(i=0;i<iterations;i++){
//distance = TrackFish();
//printf("Distance seed travelled in fish was %f m.\n",distance);
//fprintf(outfile,"%f\n",distance);
//}
// format the output file in 4 columns
fprintf(outfile,"Ouput for: %s; %d iterations. Fish starting locations in River rejected, seeds landing in River flagged with -\n",header, iterations);
// excel now allows > 100K rows, so the nested for loops aren't necessary
//for(i=0;i<(iterations/4);i++){
//for(j=0;j<4;j++){
//distance = TrackFish(fishnum, start_patch, end_patch);
//printf("Distance seed travelled in fish was %f m.\n",distance);
//fprintf(outfile,"%.1f\t",distance);
//}fprintf(outfile,"\n");
//}
for(i=0;i<iterations);i++){
distance = TrackFish(fishnum, start_patch, end_patch);
//printf("Distance seed travelled in fish was %f m.\n",distance);
fprintf(outfile,"%fishnum\t%.1f\t%s\t%s\n",fishnum,distance,start_patch,end_patch);
//
fclose(outfile);
//if(argc>=3) strcpy(forestfile,argv[2]);/* in case forestfile was input on command line */
//if(argc>=4) strcpy(outputfile,argv[3]);/* in case outputfile was input on command line */
// RanrotAInit((my_uint)aseed);
/*------END SIMULATION ------*/
printf("\n\nOutput is in %s\n END SIMULATION.\n",outputfile); /* display to console that the simulation has ended */
return 0;
}
/* ------Input functions ------*/
/* ReadControl -- read file of simulation control parameters */
/*called by:
main()
calls:
OpenFilePrompt()
*/
void ReadControl(char controlfname[], char telemfile[], char guttimefile[],char outputfname[], char message[])
{
FILE *fc;
//char message[120];/* header in control file */
fc=OpenFilePrompt(controlfname);
fscanf(fc,SCANLINE,message);/* header info in control file */
fscanf(fc,"%*s%i",&seed);/* random number seed */
fscanf(fc,"%*s%i",&iterations);/* number of output iterations */
fscanf(fc,"%*s%s",telemfile);/* file that contains telemetry data from fish */
fscanf(fc,"%*s%s",guttimefile);/* file that contains gut retention times for different seed species*/
fscanf(fc,"%*s%s",outputfname);/* output base file name */
fclose(fc);
printf("Controlfile information: \n"
"\t Header = %s \n"
"\t Random number seed = %i \n"
"\t Number of iterations = %i \n"
"\t Telem file name = %s \n"
"\t Gut time file name = %s \n"
"\t Outfile name = %s \n",
message,seed,iterations,telemfile,guttimefile,outputfname);
fflush(stdout);
}
// This function reads the fish telemetry data
void ReadTelem(char telemfile[])
{
FILE *ft;
char message[120];
char headers[120];
int i = 0;
int filepos = 0;
printf("the telemetry file name is : %s\n",telemfile);
ft=OpenFile(telemfile, "r", "telemetry");
fscanf(ft,SCANLINE,message);/* header info in control file */
fscanf(ft,SCANLINE,headers);/* header info in control file */
//printf("%s\n%s\n",message, headers);
while(filepos != EOF){
//filepos = fscanf(ft,"%d%f%f%f%s",&Fish_num[i],&Fish_x[i],&Fish_y[i],&Fish_time[i],Fish_habitat[i]);
//Telemetry data file contains columns for FishID, x loc, y loc, elapsed time, habitat, year, SE_x, SE_y, patch ID
//read columns of telem file as follows: integer, float, float, float, string, ignore integer (year), float, float, string
filepos = fscanf(ft,"%d%f%f%f%s%*d%f%f%s",&Fish_num[i],&Fish_x[i],&Fish_y[i],&Fish_time[i],Fish_habitat[i],Fish_SEx[i],Fish_SEy[i],Fish_patch[i]);
// need to fill in SEx and SEy when they are missin
if (Fish_SEx[i] < 0) Fish_SEx[i] = AVG_SE;
if (Fish_SEy[i] < 0) Fish_SEy[i] = AVG_SE;
//printf("%d %f %f %f %s\n",Fish_num[i],Fish_x[i],Fish_y[i],Fish_time[i],Fish_habitat[i]);
++i;
}
LastTelem = i;
fclose(ft);
fflush(stdout);
}
// This function reads the gut retention time data file
// make sure that all columns are filled with zeros (no empty cells)
// The data file contains the proportion of seeds that passed the fish's gut IN THAT HOUR...
// ...not the cumulative proportion that had passed so far. That is calculated in the function CalcCumulativeGutTime()
void ReadGut(char guttimefile[])
{
FILE *fg;
char message[120];
char headers[500];
int i = 0, j = 0;
int filepos = 0, hour = 0;
printf("the gut retention file name is : %s\n",guttimefile);
fg=OpenFile(guttimefile, "r", "gut retention");
fscanf(fg,SCANLINE,message);/* header info in control file */
fscanf(fg,SCANLINE,headers);/* header info in control file */
//printf("%s\n%s\n",message, headers);
while((filepos = fscanf(fg,"%d",&hour)) != EOF){
//printf("%d ",hour);
for(j=0;j<NUMFISH;j++){// NUMFISH DEFINED IN HEADING
fscanf(fg,"%f",&gut[i][j]);
//printf("%f ",gut[i][j]);
}
//printf(" <%d> \n",i);
++i;
LastTime = i; //number of entries in the Telemetry File.
}
fclose(fg);
fflush(stdout);
}
// This function calculates the cumulative proportion of seeds that have passed a fish's gut by the given time
// i indicates the hour (i = 0 is the first hour)
// j indicates the fish by trial combination (some individual fish were used multiple times)
void CalcCumulativeGutTime()
{
int i, j;
for(j=0;j<NUMFISH;j++){// NUMFISH DEFINED IN HEADING
for(i=1;i<LastTime;i++){// skip index 0, start with the first row to calculate cumulative
gut[i][j] = gut[i][j] + gut[i-1][j];
//printf("%f ",gut[i][j]);
}//printf("%d %d\n",i,LastTime);
}
}
// Now we need to draw some fish at random from the gut retention times and then...
// ...we need to pick a starting point in the telemetry data and follow a fish for the elapsed time.
float TrackFish(int &OneFish, char start_patch[], char end_patch[])
{
int RandFish, hour = 0;
int LocIndex;// indexes the current location in the telemetry data
float RandomNumber,StartTime = 0, ElapsedTime = 0, Start_x, Start_y, End_x, End_y;
float distance = 0;
float adjustX = 0, adjustY = 0;// how much to adjust x and y location based on random deviate from error distribution;
float sign = 0;// pick a random sign to modify adjustX and adjustY
RandomNumber = float(rand())/float(RAND_MAX); // to pick a probability
RandFish = (rand() % (NUMFISH -1)); // there are NUMFISH fish, indexed 0 - (NUMFISH-1)
while((gut[hour][RandFish] < RandomNumber) & hour <= LastTime){// find the hour matching the probability. Some seeds are still in the gut--assume these go the max hours.
hour++;
}
hour++;//this makes the hours real hours, not array indices
//printf("For fish %d, by %d hours %f of seeds had passed.\n",RandFish,hour,RandomNumber);
//for(hour=0;hour< LastTime;hour++){
//printf("%f ",gut[hour][RandFish]);
//}
// Now need to pick a fish from the telmetry data at random and track it for the picked number of hours
// NB: this procedure goes to the telemetry data point just past the hour picked. Might want to go to the one just before.
do{
ElapsedTime = 0;
do{
LocIndex = (rand() % (LastTelem - 2)); // indices in the telemetry data go up to (LastTelem - 1) and I want to pick one before that a possible start
}while(strcmp(Fish_habitat[LocIndex],"River")==0); // reject draws where the fish starts in the River--can't pick up a seed in the river
StartTime = Fish_time[LocIndex];
// Calculate the starting location as the telemetry location modified by the telemetry error (SE)
// X location
if (float(rand())/float(RAND_MAX) < 0.5) sign = -1;
else sign = +1;
RandomNumber = float(rand())/float(RAND_MAX); // to pick a probability
adjustX = sign * Fish_SEx[LocIndex] * sqrt( -log(1 - float(rand())/float(RAND_MAX)));
Start_x = Fish_x[LocIndex] + adjustX;
// Y location
if (float(rand())/float(RAND_MAX) < 0.5) sign = -1;
else sign = +1;
RandomNumber = float(rand())/float(RAND_MAX); // to pick a probability
adjustY = sign * Fish_SEy[LocIndex] * sqrt( -log(1 - float(rand())/float(RAND_MAX)));
Start_y = Fish_y[LocIndex] + adjusty;
strcpy(start_patch,Fish_patch[LocIndex]);// record which patch the fish starts in
OneFish = Fish_num[LocIndex];// keep track to make sure we are only tracking one fish and don't skip fish_num to the next in the array
while((ElapsedTime < float(hour)) & (LocIndex < LastTelem)){
LocIndex++;
ElapsedTime = Fish_time[LocIndex] - StartTime;
//printf("x = %f y = %f\n", Fish_x[LocIndex],Fish_y[LocIndex]);
}
//printf("LocIndex = %d ",LocIndex);
//printf("OneFish = %d; Fish_num[LocIndex] = %d \n",OneFish,Fish_num[LocIndex]);
}while(OneFish != Fish_num[LocIndex]); // if it skips to the next fish, then try again/ do over
// NB: This do/while loop DOES NOT dump any still-digested seeds at the last telem location but rather skips any trajectories that cannot be completed. This may result in overly conservative dispersal distances
// ...then again, I think this last while is just a safeguard in case the preceeding while doesn't catch a mismatch.
// Caculate Euclidean distance between start point and end point:
//printf("Start x = %f y = %f, End x = %f y = %f\n", Start_x, Start_y,Fish_x[LocIndex],Fish_y[LocIndex]);
// Calculate the END location as the telemetry location modified by the telemetry error (SE)
// X location
if (float(rand())/float(RAND_MAX) < 0.5) sign = -1;
else sign = +1;
RandomNumber = float(rand())/float(RAND_MAX); // to pick a probability
adjustX = sign * Fish_SEx[LocIndex] * sqrt( -log(1 - float(rand())/float(RAND_MAX)));
End_x = Fish_x[LocIndex] + adjustX;
// Y location
if (float(rand())/float(RAND_MAX) < 0.5) sign = -1;
else sign = +1;
RandomNumber = float(rand())/float(RAND_MAX); // to pick a probability
adjustY = sign * Fish_SEy[LocIndex] * sqrt( -log(1 - float(rand())/float(RAND_MAX)));
End_y = Fish_y[LocIndex] + adjusty;
distance = sqrt((Start_x - End_x)*(Start_x - End_x) + (Start_y - End_y)*(Start_y - End_y));
if(strcmp(Fish_habitat[LocIndex],"River")==0) distance = -1*distance;// This flags seeds that land in the river (can't germinate); 0 means strings identical
// NB: this is the habitat of the UNDADJUSTED telemetry location!! If we want the habitat of the adjusted location, need a map of habitat types in an array!!
strcpy(end_patch, Fish_patch[LocIndex]);// record which patch the fish ends in
//printf("%s",Fish_habitat[LocIndex]);
return distance;