BEGIN PROGRAM CHROMOFLOW():
// Set default program parameters
READ_SIMULATION_PARAMETERS();
READ_GENOME_MAP();
READ_ALLELE_FREQUENCIES();
READ_PEDIGREE_DATA();
INIT_SIMULATION();
SIMULATE();
// Produce reports with results
END PROGRAM CHROMOFLOW()
BEGIN FUNCTION READ_SIMULATION_PARAMETERS():
// Open command file or read commands from keyboard
// Get filenames for population, genome map and allele frequencies
Read in RareAlleleFrequency // Default = 0.05
Read in SimRecombination? // Simulate recombination
Read in SimCensus? // Simulate for census years. Default is generation
Read in FirstYear // First census year
Read in LastYear // Last census year
Read in Runs // Number of runs (iterations)
END FUNCTION READ_SIMULATION_PARAMETERS()
BEGIN FUNCTION READ_GENOME_MAP();
// Create data structure to store chromosome information
FOR (each Chromosome):
FOR (each Locus on Chromosome):
Read in LocusSite // in centi-Morgans
END FOR (Locus) LOOP
END FOR (Chromosome) LOOP
END FUNCTION READ_GENOME_MAP()
BEGIN FUNCTION READ_ALLELE_FREQUENCIES();
// Create data structure to store allelic variants per locus
FOR (each Locus):
FOR (each Allele):
Read in Frequency
END FOR (Allele) LOOP
END FOR (Locus) LOOP
END FUNCTION READ_ALLELE_FREQUENCIES()
BEGIN FUNCTION READ_PEDIGREE_DATA():
// Read number of individuals from Master file
// Create data structure to store pedigree records
FOR (each Individual):
Read in StudbookID // Unique ID for each individual
Read in SireID // Studbook ID of sire, wild or unknown
Read in DamID // Studbook ID of dam, wild or unknown
Read in Sex // Male, female or unknown
Read in Origin // Wild, captive or unknown
Read in BirthDate
Read in DeathDate // Empty if alive
END FOR (Individual) LOOP
// Read number of move records from Move file
// Create data structure to store records with move data
FOR (each Move):
Read in StudbookID // See Master loop
Read in MoveDate
Read in NewLocation // Breeding group or population
END FOR (Move) LOOP
// Sort move records on date
END FUNCTION READ_PEDIGREE_DATA()
BEGIN FUNCTION INIT_SIMULATION():
// Sort pedigree data on date of birth
COMPUTE_GENERATION();
IF (SimCensus?):
COMPUTE_CENSUS();
END IF (SimCensus?)
WILD_GENETIC_VARIATION(); // Genetic variation in source population
CREATE_LIBRARY_WITH_HOMOLOGUES();
CREATE_INDIVIDUAL_GENOMES();
END FUNCTION INIT_SIMULATION()
BEGIN FUNCTION COMPUTE_GENERATION();
FOR (each Individual):
// Individual is a (potential) founder
IF (Animals is born in source population):
Set Generation = 0
CONTINUE (Individual) LOOP
END IF(Potential founder)
IF (Sire is UNKNOWN):
Set Generation = 0
ELSE
Set Generation = Generation of Sire
END IF (Sire)
IF (Dam unequals UNKNOWN) AND
(Generation of Dam is larger than generation of Sire):
Set Generation = Generation of Dam
END IF (Dam)
Add 1 to Generation // Individual with unknown parents is F1
Add 1 to GenerationGroup->Size
END FOR (Individual) LOOP
END FUNCTION COMPUTE_GENERATION()
BEGIN FUNCTION COMPUTE_CENSUS();
Set CensusYears = (LastYear - FirstYear) + 1
// Create data structure to store living animals for each census year
FOR (each Year):
FOR (each Individual):
IF (Alive at the end of Year)
Add 1 to YearGroup->Size
END IF (Alive)
END FOR (Individual) LOOP
END FOR (Year) LOOP
END FUNCTION COMPUTE_CENSUS()
BEGIN FUNCTION WILD_GENETIC_VARIATION();
FOR (each Locus):
FOR (each Allele): // Allelic variant at locus
IF (Frequency is larger than 0):
Add 1 to WildAlleles // Total number of alleles in source
Add (Frequency ^ 2) to Locus->GeneIdentity
END IF (Frequency)
// Test if locus is polymorphic
IF (Frequency equals or is larger than RareAlleleFrequency) AND
(Allele->Frequency equals or is smaller than (1 - RareAlleleFrequency):
Set Locus->Polymorphic? = TRUE
END IF (Frequency)
END FOR (Allele) LOOP
IF (Locus->Polymorphic?):
Add 1 to WildPolymorpishm // Number of polymorphic loci in source
END IF (Locus is polymorphic)
Add Locus->GeneIdentity to WildGeneIdentity
END FOR (Locus) LOOP
Set WildPolymorphism = WildPolymorphism / Loci
Set WildGeneIdentity = WildGeneIdentity / Loci
Set WildGeneDiversity = 1 - WildGeneIdentity
Set WildHeterozygosity = WildGenediversity // Assume H - W equilibrium
END FUNCTION WILD_GENETIC_VARIATION()
BEGIN FUNCTION CREATE_LIBRARY_WITH_HOMOLOGUES():
IF (SimRecombination?):
// Create data structure to store diploid set for each individual
ELSE
// Create data structure to store diploid set of chromosomes
// for each founder
END IF/ELSE (SimRecombination?)
END FUNCTION CREATE_LIBRARY_WITH_HOMOLOGUES()
BEGIN FUNCTION CREATE_INDIVIDUAL_GENOMES():
FOR (each Individual):
// Create data structure to store ID's of diploid set of chromosomes
(homologues)
IF (Animal is born in source population): // Potential founder
// Link homologue ID's in library to individual according sequence of
creation
END IF (Potential founder)
END FOR (Individual) LOOP
END FUNCTION CREATE_INDIVIDUAL_GENOMES()
BEGIN FUNCTION SIMULATE():
FOR (each Run):
// Initialize pseudo random generator
ASSIGN_ALLELES_TO_FOUNDERS();
ASSIGN_ALLELES_TO_DESCENDANTS();
RUN_RESULTS();
END FOR (Run) LOOP
SIMULATION_RESULTS();
END FUNCTION SIMULATE()
BEGIN FUNCTION ASSIGN_ALLELES_TO_FOUNDERS():
FOR (each Founder):
FOR (each Homologue):
FOR (each Locus at homologue):
Set Allele = SAMPLE_WILD_ALLELE(Locus);
END FOR (Locus at homologue ) LOOP
END FOR (Homologue) LOOP
END FOR (Founder) LOOP
END FUNCTION ASSIGN_ALLELES_TO_FOUNDERS()
BEGIN FUNCTION SAMPLE_WILD_ALLELE(Locus):
// Get number of allelic variants for locus in source population
IF (not Locus->Polymorphic?):
RETURN(1) // Only one allellic variant
END IF (Locus->Polymorphic)
// Temporary variables
Set RandomFrequency = RANDOM(0..1)
Set LowerFrequency = 0
Set UpperFrequency = 0
FOR (each Allele): // Allelic variants at locus
Add Locus->Allele->Frequency to UpperFrequency
IF (RandomFrequency equals or is larger than LowerFrequency) AND
(RandomFrequency is smaller than UpperFrequency) :
RETURN(Allele number) // Number in range 1 .. Locus->Alleles
END IF (RandomFrequency)
Set LowerFrequency = Upper frequency
END FOR (Allele) LOOP
END FUNCTION SAMPLE_WILD_ALLELE()
BEGIN FUNCTION ASSIGN_ALLELES_TO_DESCENDANTS():
FOR (each Individual):
IF (Generation > 0):
FOR (each Chromosome):
IF (SimRecombination?):
Set Homologue1->ID = CROSS_OVER(Chromosome,
SireID->Chromosome);
Set Homologue2->ID = CROSS_OVER(Chromosome,
DamID->Chromosome);
ELSE
Set Homologue1->ID = MENDELIAN(SireID->Chromosome);
Set Homologue2->ID = MENDELIAN(DamID->Chromosome);
END IF/ELSE (SimRecombination?)
END FOR (Chromosome) LOOP
END IF (Generation)
END FOR (Individual) LOOP
END FUNCTION ASSIGN_ALLELES_TO_DESCENDANTS()
BEGIN FUNCTION CROSS_OVER(Chromosome, ParentChromosome):
// Retrieve data on locus map of chromosome
// Make copies of both homologues of parental chromosome
// Chromatids 1 and 2 refer to homologue 1, chromatids 3 and 4 to
homologue 2
FOR (each Locus on chromosome starting at second)
// Get map site of previous locus in centi-Morgans from top
// Get map site of locus in centi-Morgans of top
Set Frequency = MORGANS_TO_FREQUENCY( LocusSite - PreviousLocusSite) *
2
IF (RANDOM(0..1) is smaller than Frequency):
Set Recombination? = TRUE
// Select randomly which chromatids 1 or 2 interact with chromatids 3 or
4
FOR (each Locus after chiasma):
// Swap alleles between selected chromatids
END FOR (Locus after chiasma) LOOP
END IF (Recombination?)
END FOR (Locus on chromosome) LOOP
IF (Recombination?):
Set Chromatid = RANDOM_INTEGER(1..4)
// Add selected chromatid to library with homologues and assign
HomologueID
ELSE
Set HomologueID = MENDELIAN(ParentChromosome);
END IF/ELSE (Recombination?)
RETURN( HomologueID )
END FUNCTION CROSS_OVER()
BEGIN FUNCTION MORGANS_TO_FREQUENCY( centiMorgans ):
// Computes for double-strand model
r = 0.5 * (1.0 - EXPONENTIAL( -2.0 * centiMorgans ) )
RETURN ( r )
END FUNCTION MORGANS_TO_FREQUENCY()
BEGIN FUNCTION MENDELIAN(ParentChromosome):
IF (RANDOM_INTEGER(1..2) is 1):
RETURN(ParentChromosome->Homologue1->ID)
ELSE
RETURN(ParentChromosome->Homologue2->ID)
END IF/ELSE (Homologue)
END FUNCTION MENDELIAN()
BEGIN FUNCTION RUN_RESULTS():
// Type of group depends on simulation settings (generation or census)
FOR (each Group):
FOR (each Individual in Group):
FOR (each Chromosome):
// Get both homologues of individual
FOR (each Locus on Chromosome):
// Get alleles at both homologues
IF (Allele1 <> Allele2):
Add 1 to Group->Heterozygosity
END IF (Different alleles)
Add 1 to Allele1->Frequency
Add 1 to Allele2->Frequency
END FOR (Locus at chromosome) LOOP
END FOR (Chromosome) LOOP
END FOR (Individidual) LOOP
FOR (each Locus):
FOR (each Allelelic variant at locus)
Set Allele->Frequency = Allele->Frequency / ( 2 * Group->Size)
Add (Allele->Frequency^2) to Group->GeneIdentity
IF (Allele->Frequency equals or is larger than RareAlleleFrequency) AND
(Allele->Frequency equals or is smaller than (1 - RareAlleleFrequency)
):
Set Locus->Polymorphic = TRUE;
END IF (Allele->Frequency)
IF (Allele->Frequency > 0):
Add 1 to Group->Allele->Number
END IF (Allele frequency)
END FOR (Allelic variant at locus) LOOP
IF (Locus->Polymorphic?):
Add 1 to Group->Polymorphism
END IF (Locus->Polymorphic?)
END FOR (Locus) LOOP
// Compute averages per group:
// observed heterozygosity, gene identity (and gene diversity) over all loci,
polymorphism
// Store values as fractions of values in the source (wild) population
END FOR (Group) LOOP
END FUNCTION RUN_RESULTS()
BEGIN FUNCTION SIMULATION_RESULTS();
FOR (each Group):
// Compute average and variance over runs:
// proportion of heterozygous loci, gene diversity, polymorphism, number of
alleles
// fraction of runs where value < (0.95 * average) for previous measures
END FOR (Group) LOOP
END FUNCTION SIMULATION_RESULTS()