Pedigree Class Reference
Inheritance diagram for Pedigree:
[legend]
Collaboration diagram for Pedigree:
[legend]

## Public Member Functions

void | Prepare (IFILE &input)
void | Load (IFILE &input)
void | LoadMendel (IFILE &input)
void | Prepare (const char *input)
void | Load (const char *input, bool allowFailures=false)
int | TranslateSexCode (const char *code, bool &failure)
void | PrepareDichotomization ()
int | Dichotomize (int trait, double mean=_NAN_)
void | DichotomizeAll (double mean=_NAN_)
void | WriteDataFile (FILE *output)
void | WritePedigreeFile (FILE *output)
void | WriteDataFile (const char *output)
void | WritePedigreeFile (const char *output)
void | WritePerson (FILE *output, int who, const char *famid=NULL, const char *pid=NULL, const char *fatid=NULL, const char *motid=NULL)
void | WriteRecodedPerson (FILE *output, int who, MarkerInfo **markerInfo, const char *famid=NULL, const char *pid=NULL, const char *fatid=NULL, const char *motid=NULL)
void | Sort ()
Family * | FindFamily (const char *famid)
Person * | FindPerson (const char *famid, const char *pid)
int | CountAlleles (int marker)
void | LumpAlleles (double treshold, bool reorder=true)
void | EstimateFrequencies (int estimator, bool quiet=false)
Person & | operator[] (int i)
bool | InheritanceCheck (bool abortIfInconsistent=true)
bool | AutosomalCheck ()
bool | SexLinkedCheck ()
bool | TwinCheck ()
void | MergeTwins ()
void | Trim (bool quiet=false, int *informative=NULL)
void | AddPerson (const char *famid, const char *pid, const char *fatid, const char *motid, int sex, bool delay_sort=false)
void | ExtractFamily (int id, Pedigree &new_ped)
void | ExtractOnAffection (int a, Pedigree &new_ped, int target_status=2)
void | Filter (IntArray &filter)
void | ShowMemoryInfo ()

## Public Attributes

int | size
int | count
Person ** | persons
int | familyCount
Family ** | families
int | haveTwins
PedigreeDescription | pd
PedigreeDescription * | multiPd
int | multiFileCount

## Static Public Attributes

static bool | sexAsCovariate = false
static String | missing
Static Public Attributes inherited from PedigreeGlobals
static int | traitCount = 0
static int | markerCount = 0
static int | affectionCount = 0
static int | covariateCount = 0
static int | stringCount = 0
static bool | chromosomeX = false
static bool | sexSpecificMap = false
static StringArray | traitNames
static StringArray | covariateNames
static StringArray | affectionNames
static StringArray | markerNames
static StringArray | stringNames
static StringIntHash | markerLookup
static StringIntHash | traitLookup
static StringIntHash | affectionLookup
static StringIntHash | covariateLookup
static StringIntHash | stringLookup
static int | markerInfoCount = 0
static int | markerInfoSize = 0
static MarkerInfo ** | markerInfo = NULL
static StringHash | markerInfoByName
static MarkerInfo ** | markerInfoByInteger = NULL

## Additional Inherited Members

Static Public Member Functions inherited from PedigreeGlobals
static int | GetTraitID (const char *name)
static int | GetMarkerID (const char *name)
static int | GetCovariateID (const char *name)
static int | GetAffectionID (const char *name)
static int | GetStringID (const char *name)
static int | LookupTrait (const char *name)
static int | LookupMarker (const char *name)
static int | LookupCovariate (const char *name)
static int | LookupAffection (const char *name)
static int | LookupString (const char *name)
static void | GrowMarkerInfo ()
static MarkerInfo * | GetMarkerInfo (String &name)
static MarkerInfo * | GetMarkerInfo (int marker)
static int | SortMarkersInMapOrder (IntArray &markers, int chromosome=-1)
static void | GetOrderedMarkers (IntArray &markers)
static void | FlagMissingMarkers (IntArray &missingMarkers)
static bool | MarkerPositionsAvailable ()
static bool | AlleleFrequenciesAvailable ()
static void | VerifySexSpecificOrder ()
static void | LoadAlleleFrequencies (const char *filename, bool required=false)
static void | LoadAlleleFrequencies (IFILE &file)
static void | LoadMarkerMap (const char *filename, bool filter=false)
static void | LoadMarkerMap (IFILE &file, bool filter=false)
static void | LoadBasepairMap (const char *filename)
static void | LoadBasepairMap (IFILE &file)
static void | WriteMapFile (const char *filename)
static void | WriteMapFile (FILE *file)
static void | WriteFreqFile (const char *filename, bool old_format=false)
static void | WriteFreqFile (FILE *file, bool old_format=false)
static int | LoadAllele (int marker, String &label)
static int | LoadAllele (MarkerInfo *info, String &label)

## Detailed Description

Definition at line 32 of file Pedigree.h.

## Constructor & Destructor Documentation

## Pedigree()

Pedigree::Pedigree | ( |  | ) |

Definition at line 30 of file Pedigree.cpp.

: pd()
{
haveTwins = count = 0;
size = 10000;
persons = new Person *[size];
familyCount = 0;
families = new Family * [1];
multiPd = NULL;
multiFileCount = 0;
}
Family
Definition: PedigreeFamily.h:28
Person
Definition: PedigreePerson.h:32

## ~Pedigree()

Pedigree::~Pedigree | ( |  | ) |

Definition at line 41 of file Pedigree.cpp.

{
for (int i = 0; i < count; i++)
delete persons[i];
for (int i = 0; i < familyCount; i++)
delete families[i];
delete [] families;
delete [] persons;
if (multiPd != NULL)
delete [] multiPd;
}

## Member Function Documentation

## AddPerson()

void Pedigree::AddPerson | ( | const char * | famid,
|  | const char * | pid,
|  | const char * | fatid,
|  | const char * | motid,
|  | int | sex,
|  | bool | delay_sort = `false`
| ) |  |

Definition at line 921 of file Pedigree.cpp.

{
if (count == size) Grow();
persons[count] = new Person;
persons[count]->famid = famid;
persons[count]->pid = pid;
persons[count]->fatid = fatid;
persons[count]->motid = motid;
persons[count]->sex = sex;
count++;
if (!delay_sort) Sort();
}

## AutosomalCheck()

bool Pedigree::AutosomalCheck | ( |  | ) |

Definition at line 520 of file Pedigree.cpp.

{
// Arrays indicating which alleles and homozygotes occur
IntArray haplos, genos, counts, failedFamilies;
bool fail = false;
// For each marker ...
for (int m = 0; m < markerCount; m++)
{
MarkerInfo * info = GetMarkerInfo(m);
// Summary for marker
int alleleCount = CountAlleles(m);
int genoCount = alleleCount * (alleleCount + 1) / 2;
// Initialize arrays
haplos.Dimension(alleleCount + 1);
haplos.Set(-1);
genos.Dimension(genoCount + 1);
genos.Set(-1);
failedFamilies.Dimension(familyCount);
failedFamilies.Zero();
counts.Dimension(alleleCount + 1);
for (int f = 0; f < familyCount; f++)
for (int i = families[f]->first; i <= families[f]->last; i++)
if (!persons[i]->isFounder() && persons[i]->sibs[0] == persons[i])
{
// This loop runs once per sibship
Alleles fat = persons[i]->father->markers[m];
Alleles mot = persons[i]->mother->markers[m];
bool fgeno = fat.isKnown();
bool mgeno = mot.isKnown();
// Number of alleles, homozygotes and genotypes in this sibship
int haplo = 0, homo = 0, diplo = 0;
// No. of different genotypes per allele
counts.Zero();
// In general, there should be no more than 3 genotypes per allele
bool too_many_genos = false;
for (int j = 0; j < persons[i]->sibCount; j++)
if (persons[i]->sibs[j]->isGenotyped(m))
{
Alleles geno = persons[i]->sibs[j]->markers[m];
int fat1 = fat.hasAllele(geno.one);
int fat2 = fat.hasAllele(geno.two);
int mot1 = mot.hasAllele(geno.one);
int mot2 = mot.hasAllele(geno.two);
if ((fgeno && mgeno && !((fat1 && mot2) || (fat2 && mot1))) ||
(fgeno && !(fat1 || fat2)) || (mgeno && !(mot1 || mot2)))
{
printf("%s - Fam %s: Child %s [%s/%s] has ",
(const char *) markerNames[m],
(const char *) persons[i]->sibs[j]->famid,
(const char *) persons[i]->sibs[j]->pid,
(const char *) info->GetAlleleLabel(geno.one),
(const char *) info->GetAlleleLabel(geno.two));
if (!fgeno || !mgeno)
printf("%s [%s/%s]\n",
fgeno ? "father" : "mother",
(const char *) info->GetAlleleLabel(fgeno ? fat.one : mot.one),
(const char *) info->GetAlleleLabel(fgeno ? fat.two : mot.two));
else
printf("parents [%s/%s]*[%s/%s]\n",
(const char *) info->GetAlleleLabel(fat.one),
(const char *) info->GetAlleleLabel(fat.two),
(const char *) info->GetAlleleLabel(mot.one),
(const char *) info->GetAlleleLabel(mot.two));
fail = true;
failedFamilies[f] = true;
}
else
{
if (haplos[geno.one] != i)
{
haplo++;
haplos[geno.one] = i;
};
if (haplos[geno.two] != i)
{
haplo++;
haplos[geno.two] = i;
};
int index = geno.SequenceCoded();
if (genos[index] != i)
{
genos[index] = i;
diplo++;
counts[geno.one]++;
if (geno.isHomozygous())
homo++;
else
counts[geno.two]++;
if (counts[geno.one] > 2) too_many_genos = true;
if (counts[geno.two] > 2) too_many_genos = true;
}
}
}
if (fgeno)
{
if (haplos[fat.one] != i)
{
haplo++;
haplos[fat.one] = i;
}
if (haplos[fat.two] != i)
{
haplo++;
haplos[fat.two] = i;
}
homo += fat.isHomozygous();
}
if (mgeno)
{
if (haplos[mot.one] != i)
{
haplo++;
haplos[mot.one] = i;
}
if (haplos[mot.two] != i)
{
haplo++;
haplos[mot.two] = i;
}
homo += mot.isHomozygous();
}
if (diplo > 4 || haplo + homo > 4 || (haplo == 4 && too_many_genos))
{
printf("%s - Fam %s: ",
(const char *) markerNames[m],
(const char *) persons[i]->famid);
if (persons[i]->father->markers[m].isKnown())
printf("Father %s [%s/%s] has children [",
(const char *) persons[i]->father->pid,
(const char *) info->GetAlleleLabel(fat.one),
(const char *) info->GetAlleleLabel(fat.two));
else if (persons[i]->mother->markers[m].isKnown())
printf("Mother %s [%s/%s] has children [",
(const char *) persons[i]->mother->pid,
(const char *) info->GetAlleleLabel(mot.one),
(const char *) info->GetAlleleLabel(mot.two));
else
printf("Couple %s * %s has children [",
(const char *) persons[i]->mother->pid,
(const char *) persons[i]->father->pid);
for (int j = 0; j < persons[i]->sibCount; j++)
printf("%s%s/%s", j == 0 ? "" : " ",
(const char *) info->GetAlleleLabel(persons[i]->sibs[j]->markers[m].one),
(const char *) info->GetAlleleLabel(persons[i]->sibs[j]->markers[m].two));
printf("]\n");
fail = true;
failedFamilies[f] = true;
}
}
for (int f = 0; f < familyCount; f++)
if (!failedFamilies[f] &&
(families[f]->count > families[f]->founders + 1) &&
!families[f]->isNuclear())
fail |= !GenotypeList::EliminateGenotypes(*this, families[f], m);
}
if (fail)
printf("\nMendelian inheritance errors detected\n");
return fail;
}
Alleles
Definition: PedigreeAlleles.h:24
IntArray
Definition: IntArray.h:24
MarkerInfo
Definition: PedigreeGlobals.h:30

## CountAlleles()

int Pedigree::CountAlleles | ( | int | marker | ) |

Definition at line 225 of file Pedigree.cpp.

{
return ::CountAlleles(*this, marker);
}

## Dichotomize()

int Pedigree::Dichotomize | ( | int | trait,
|  | double | mean = `_NAN_`
| ) |  |

Definition at line 460 of file Pedigree.cpp.

{
String new_affection = traitNames[t] + "*";
int af = GetAffectionID(new_affection);
if (mean == _NAN_)
{
mean = 0.0;
double dcount = 0;
for (int i = 0; i < count; i++)
if (persons[i]->isPhenotyped(t) &&
!persons[i]->isFounder())
{
mean += persons[i]->traits[t];
dcount ++;
}
if (!dcount) return af;
mean /= dcount;
}
printf("Dichotomizing %s around mean of %.3f ...\n",
(const char *) traitNames[t], mean);
for (int i = 0; i < count; i++)
if (persons[i]->isPhenotyped(t) && !persons[i]->isFounder())
persons[i]->affections[af] = persons[i]->traits[t] > mean ? 2 : 1;
else
persons[i]->affections[af] = 0;
Sort();
return af;
}
String
Definition: StringBasics.h:39

## DichotomizeAll()

void Pedigree::DichotomizeAll | ( | double | mean = `_NAN_` | ) |

Definition at line 497 of file Pedigree.cpp.

{
for (int t = 0; t < traitCount; t++)
Dichotomize(t, mean);
}

## EstimateFrequencies()

void Pedigree::EstimateFrequencies | ( | int | estimator,
|  | bool | quiet = `false`
| ) |  |

Definition at line 239 of file Pedigree.cpp.

{
bool estimated = false;
int line = 3;
const char * estimators[] =
{ "using all genotypes", "using founder genotypes", "assumed equal" };
bool condensed = markerCount > 100;
int grain = markerCount / 50, estimates = 0;
for (int m=0; m < markerCount; m++)
if (::EstimateFrequencies(*this, m, estimator))
if (!quiet)
{
if (!estimated)
printf("Estimating allele frequencies... [%s]\n ",
estimators[estimator]), estimated = true;
if (condensed)
{
if (estimates++ % grain == 0)
{
printf(".");
fflush(stdout);
}
continue;
}
if (line + markerNames[m].Length() + 1 > 79)
printf("\n "), line = 3;
printf("%s ", (const char *) markerNames[m]);
line += markerNames[m].Length() + 1;
}
if (estimated)
printf(condensed ? "\nDone estimating frequencies for %d markers\n\n" : "\n\n", estimates);
}

## ExtractFamily()

void Pedigree::ExtractFamily | ( | int | id,
|  | Pedigree & | new_ped
| ) |  |

Definition at line 885 of file Pedigree.cpp.

{
for (int i = families[id]->first; i <= families[id]->last; i++)
single_fam_ped.Add(*persons[i]);
single_fam_ped.Sort();
}

## ExtractOnAffection()

void Pedigree::ExtractOnAffection | ( | int | a,
|  | Pedigree & | new_ped,
|  | int | target_status = `2`
| ) |  |

Definition at line 893 of file Pedigree.cpp.

{
for (int i = 0; i < count; i++)
if (persons[i]->affections[a] == target_status)
new_ped.Add(*persons[i]);
else
{
Person blank_person;
blank_person.CopyIDs(*persons[i]);
new_ped.Add(blank_person);
}
new_ped.Sort();
}

## Filter()

void Pedigree::Filter | ( | IntArray & | filter | ) |

Definition at line 908 of file Pedigree.cpp.

{
if (filter.Length() != count)
error("Pedigree:Size of pedigree filter doesn't match number of persons in pedigree");
for (int i = 0; i < count; i++)
if (filter[i] == 1)
{
persons[i]->WipePhenotypes();
persons[i]->filter = true;
}
}

## FindFamily()

Family * Pedigree::FindFamily | ( | const char * | famid | ) |

Definition at line 213 of file Pedigree.cpp.

{
PedigreeKey key;
key.famid = famid;
Family ** result = (Family **) BinarySearch
(&key, families, familyCount, sizeof(Family *),
COMPAREFUNC CompareKeyToFamily);
return (result == NULL) ? (Family *) NULL : *result;
}
PedigreeKey
Definition: Pedigree.cpp:167

## FindPerson()

Person * Pedigree::FindPerson | ( | const char * | famid,
|  | const char * | pid
| ) |  |

Definition at line 187 of file Pedigree.cpp.

{
PedigreeKey key;
key.famid = famid;
key.pid = pid;
Person ** result = (Person **) BinarySearch
(&key, persons, count, sizeof(Person *),
COMPAREFUNC CompareKeyToPerson);
return (result == NULL) ? (Person *) NULL : *result;
}

## InheritanceCheck()

bool Pedigree::InheritanceCheck | ( | bool | abortIfInconsistent = `true` | ) |

Definition at line 503 of file Pedigree.cpp.

{
bool fail = false;
if (haveTwins) fail |= TwinCheck();
if (chromosomeX)
fail |= SexLinkedCheck();
else
fail |= AutosomalCheck();
if (fail && abortIfInconsistent)
error("Mendelian inheritance errors detected\n");
return !fail;
}

## Load() [1/2]

void Pedigree::Load | ( | const char * | input,
|  | bool | allowFailures = `false`
| ) |  |

Definition at line 564 of file PedigreeLoader.cpp.

{
if (multiFileCount <= 1)
{
IFILE f = ifopen(filename, "rb");
if (f == NULL && allowFailures)
return;
if (f == NULL)
error(
"The pedigree file %s cannot be opened\n\n"
"Common causes for this problem are:\n"
" * You might not have used the correct options to specify input file names,\n"
" please check the program documentation for information on how to do this\n\n"
" * The file doesn't exist or the filename might have been misspelt\n\n"
" * The file exists but it is being used by another program which you will need\n"
" to close\n\n"
" * The file is larger than 2GB and you haven't compiled this application with\n"
" large file support.\n\n",
filename);
Load(f);
ifclose(f);
}
else
{
StringArray filenames;
filenames.AddColumns(filename, ',');
if (filenames.Length() != multiFileCount)
error("Different numbers of comma separated data and pedigree file names provided\n");
for (int i = 0; i < filenames.Length(); i++)
{
printf(" AUTOMATIC MERGE: Datafile '%s' matched to pedigree '%s' ...\n",
(const char *) multiPd[i].filename, (const char *) filenames[i]);
pd = multiPd[i];
IFILE f = ifopen(filenames[i], "rb");
if (f == NULL)
error("The pedigree file '%s' cannot be opened\n\n",
(const char *) filenames[i]);
Load(f);
ifclose(f);
}
printf("\n");
}
}
ifopen
IFILE ifopen(const char *filename, const char *mode, InputFile::ifileCompression compressionMode=InputFile::DEFAULT)
Open a file with the specified name and mode, using a filename of "-" to indicate stdin/stdout.
Definition: InputFile.h:562
ifclose
int ifclose(IFILE &file)
Close the file.
Definition: InputFile.h:580
InputFile
Class for easily reading/writing files without having to worry about file type (uncompressed,...
Definition: InputFile.h:37
StringArray
Definition: StringArray.h:24

## Load() [2/2]

void Pedigree::Load | ( | IFILE & | input | ) |

Definition at line 31 of file PedigreeLoader.cpp.

{
if (pd.mendelFormat)
{
LoadMendel(input);
return;
}
int sexCovariate = sexAsCovariate ? GetCovariateID("sex") : -1;
int textCols = pd.CountTextColumns() + 5;
int oldCount = count;
bool warn = true;
int line = 0;
String buffer;
StringArray tokens;
while (!ifeof(input))
{
int field = 0;
buffer.ReadLine(input);
tokens.Clear();
tokens.AddTokens(buffer, WHITESPACE);
if (tokens.Length() == 0) continue;
if (tokens[0].SlowCompare("end") == 0) break;
line++;
if (tokens.Length() < textCols)
{
if (buffer.Length() > 79)
{
buffer.SetLength(75);
buffer += " ...";
}
String description;
pd.ColumnSummary(description);
error("Loading Pedigree...\n\n"
"Expecting %d columns (%s),\n"
"but read only %d columns in line %d.\n\n"
"The problem line is transcribed below:\n%s\n",
textCols, (const char *) description,
tokens.Length(), line, (const char *) buffer);
}
if (tokens.Length() > textCols && warn && textCols > 5)
{
pd.ColumnSummary(buffer);
printf("WARNING -- Trailing columns in pedigree file will be ignored\n"
" Expecting %d data columns (%s)\n"
" However line %d, for example, has %d data columns\n\n",
textCols - 5, (const char *) buffer, line, tokens.Length() - 5);
warn = false;
}
Person * p;
// create a new person if necessary
if (oldCount==0 || (p = FindPerson(tokens[0], tokens[1], oldCount))==NULL)
{
if (count == size) Grow();
p = persons[count++] = new Person;
}
p->famid = tokens[field++]; // famid
p->pid = tokens[field++]; // pid
p->fatid = tokens[field++]; // fatid
p->motid = tokens[field++]; // motid
bool failure = false;
p->sex = TranslateSexCode(tokens[field++], failure);
if (failure)
error("Can't interpret the sex of individual #%d\n"
"Family: %s Individual: %s Sex Code: %s", count,
(const char *) p->famid, (const char *) p->pid,
(const char *) tokens[field-1]);
if (sexAsCovariate)
{
if (p->sex)
p->covariates[sexCovariate] = p->sex;
else
p->covariates[sexCovariate] = _NAN_;
}
for (int col = 0; col < pd.columnCount; col++)
switch (pd.columns[col])
{
case pcAffection :
{
int a = pd.columnHash[col];
int new_status;
const char * affection = tokens[field++];
switch (toupper(affection[0]))
{
case '1' :
case 'N' :
case 'U' :
new_status = 1;
break;
case '2' :
case 'D' :
case 'A' :
case 'Y' :
new_status = 2;
break;
default :
new_status = atoi(affection);
if (new_status < 0 || new_status > 2)
error("Incorrect formatting for affection status "
"Col %d, Affection %s\n"
"Family: %s Individual: %s Status: %s",
col, (const char *) affectionNames[a],
(const char *) p->famid, (const char *) p->pid,
affection);
}
if (new_status != 0 && p->affections[a] != 0 &&
new_status != p->affections[a])
error("Conflict with previous affection status - "
"Col %d, Affection %s\n"
"Family: %s Individual: %s Old: %d New: %d",
col, (const char *) affectionNames[a],
(const char *) p->famid, (const char *) p->pid,
p->affections[a], new_status);
if (new_status) p->affections[a] = new_status;
break;
}
case pcMarker :
{
int m = pd.columnHash[col];
Alleles new_genotype;
new_genotype[0] = LoadAllele(m, tokens[field++]);
new_genotype[1] = LoadAllele(m, tokens[field++]);
if (p->markers[m].isKnown() && new_genotype.isKnown() &&
new_genotype != p->markers[m])
{
MarkerInfo * info = GetMarkerInfo(m);
error("Conflict with previous genotype - Col %d, Marker %s\n"
"Family: %s Individual: %s Old: %s/%s New: %s/%s",
col, (const char *) markerNames[m],
(const char *) p->famid, (const char *) p->pid,
(const char *) info->GetAlleleLabel(p->markers[m][0]),
(const char *) info->GetAlleleLabel(p->markers[m][1]),
(const char *) info->GetAlleleLabel(new_genotype[0]),
(const char *) info->GetAlleleLabel(new_genotype[1]));
}
if (new_genotype.isKnown()) p->markers[m] = new_genotype;
break;
}
case pcTrait :
case pcUndocumentedTraitCovariate :
{
int t = pd.columnHash[col];
double new_pheno = _NAN_;
if (pd.columns[col] == pcUndocumentedTraitCovariate)
t = t / 32768;
const char * value = tokens[field++];
char * flag = NULL;
if (missing == (const char *) NULL || strcmp(value, missing) != 0)
new_pheno = strtod(value, &flag);
if (flag != NULL && *flag) new_pheno = _NAN_;
if (p->traits[t] != _NAN_ && new_pheno != _NAN_ &&
new_pheno != p->traits[t])
error("Conflict with previous phenotype - Col %d, Trait %s\n"
"Family: %s Individual: %s Old: %f New: %f",
col, (const char *) traitNames[t],
(const char *) p->famid, (const char *) p->pid,
p->traits[t], new_pheno);
if (new_pheno != _NAN_) p->traits[t] = new_pheno;
if (pd.columns[col] == pcTrait) break;
}
case pcCovariate :
{
int c = pd.columnHash[col];
double new_covar = _NAN_;
if (pd.columns[col] == pcUndocumentedTraitCovariate)
{
c = c % 32768;
field--;
}
const char * value = tokens[field++];
char * flag = NULL;
if (missing == (const char *) NULL || strcmp(value, missing) != 0)
new_covar = strtod(value, &flag);
if (flag != NULL && *flag) new_covar = _NAN_;
if (p->covariates[c] != _NAN_ && new_covar != _NAN_ &&
new_covar != p->covariates[c])
error("Conflict with previous value - Col %d, Covariate %s\n"
"Family: %s Individual: %s Old: %f New: %f",
col, (const char *) covariateNames[c],
(const char *) p->famid, (const char *) p->pid,
p->covariates[c], new_covar);
if (new_covar != _NAN_) p->covariates[c] = new_covar;
break;
}
case pcString :
{
int c = pd.columnHash[col];
if (!p->strings[c].IsEmpty() && p->strings[c] != tokens[field])
error("Conflict with previous value - Col %d, String %s\n"
"Family: %s Individual: %s Old: %s New: %s",
col, (const char *) stringNames[c],
(const char *) p->famid, (const char *) p->pid,
(const char *) p->strings[c], (const char *) tokens[field]);
p->strings[c] = tokens[field++];
break;
}
case pcSkip :
field++;
break;
case pcZygosity :
{
int new_zygosity;
const char * zygosity = tokens[field++];
switch (zygosity[0])
{
case 'D' :
case 'd' :
new_zygosity = 2;
break;
case 'M' :
case 'm' :
new_zygosity = 1;
break;
default :
new_zygosity = atoi(zygosity);
}
if (p->zygosity != 0 && new_zygosity != p->zygosity)
error("Conflict with previous zygosity - "
"Column %d in pedigree\n"
"Family: %s Individual: %s Old: %d New: %d\n",
col, (const char *) p->famid, (const char *) p->pid,
p->zygosity, new_zygosity);
p->zygosity = new_zygosity;
break;
}
case pcEnd :
break;
default :
error("Inconsistent Pedigree Description -- Internal Error");
}
}
Sort();
}
ifeof
int ifeof(IFILE file)
Check to see if we have reached the EOF (returns 0 if not EOF).
Definition: InputFile.h:654

## LoadMendel()

void Pedigree::LoadMendel | ( | IFILE & | input | ) |

Definition at line 306 of file PedigreeLoader.cpp.

{
// First, retrieve the two format statements from file
String familyHeader;
String individualRecord;
familyHeader.ReadLine(input);
individualRecord.ReadLine(input);
// Then create two FORTRAN input streams...
// One will be used for retrieving family labels and sizes, the other
// will be used for individual information
FortranFormat headers, records;
headers.SetInputFile(input);
headers.SetFormat(familyHeader);
records.SetInputFile(input);
records.SetFormat(individualRecord);
// Storage for key pieces of information
String famid;
String phenotype;
String affectionCode;
String affectionStem;
int familySize;
String allele1, allele2;
int sexCovariate = sexAsCovariate ? GetCovariateID("sex") : -1;
while (!ifeof(input))
{
if (count == size)
Grow();
// Retrieve header for next family
familySize = headers.GetNextInteger();
headers.GetNextField(famid);
headers.Flush();
if (famid.IsEmpty())
{
if (ifeof(input) && familySize == 0)
break;
else
error("Blank family id encountered\n");
}
// Retrieve each individual in the family
for (int i = 0; i < familySize; i++)
{
Person * p = persons[count++] = new Person;
// Retrieve basic pedigree structure
p->famid = famid;
records.GetNextField(p->pid);
records.GetNextField(p->fatid);
records.GetNextField(p->motid);
if (p->pid.IsEmpty())
error("No unique identifier for individual #%d in family %s\n",
i + 1, (const char *) famid);
if (p->pid.Compare(".") == 0)
error("Family %s has an individual named '.', but this code is\n"
"reserved to indicate missing parents\n");
if (p->fatid.IsEmpty()) p->fatid = ".";
if (p->motid.IsEmpty()) p->motid = ".";
// Retrieve and decode sex code
char sex = records.GetNextCharacter();
switch (sex)
{
case '0' :
case 'x' :
case 'X' :
case '?' :
case 0 :
p->sex = 0;
break;
case '1' :
case 'm' :
case 'M' :
p->sex = 1;
break;
case '2' :
case 'f' :
case 'F' :
p->sex = 2;
break;
default :
error("Can't interpret the sex of individual #%d\n"
"Family: %s Individual: %s Sex Code: %s", count,
(const char *) p->famid, (const char *) p->pid, sex);
};
if (sexAsCovariate)
{
if (p->sex)
p->covariates[sexCovariate] = p->sex;
else
p->covariates[sexCovariate] = _NAN_;
}
// Retrieve and decode zygosity
char zygosity = records.GetNextCharacter();
// Mendel uses a unique character to indicate each MZ pair,
// we use a unique odd number...
if (zygosity)
p->zygosity = (zygosity - ' ') * 2 - 1;
affectionStem.Clear();
for (int col = 0; col < pd.columnCount; col++)
switch (pd.columns[col])
{
case pcAffection :
{
int a = pd.columnHash[col];
// We expand each Mendel non-codominant trait into multiple
// affection status column... First, if this is not a
// continuation of a previous expansion we first retrieve
// and encode the affection status.
if (affectionStem.Length() == 0 ||
affectionNames[a].CompareToStem(affectionStem) != 0)
{
affectionStem.Copy(affectionNames[a], 0, affectionNames[a].FindChar('>') + 1);
records.GetNextField(phenotype);
affectionCode = affectionStem + phenotype;
}
// Then encode each phenotype appropriately
if (phenotype.IsEmpty())
p->affections[a] = 0;
else
p->affections[a] = affectionCode.Compare(affectionNames[a]) == 0 ? 2 : 1;
break;
}
case pcMarker :
{
int m = pd.columnHash[col];
records.GetNextField(phenotype);
if (phenotype.IsEmpty())
{
p->markers[m].one = p->markers[m].two = 0;
continue;
}
int separator = phenotype.FindChar('/');
if (separator == -1) separator = phenotype.FindChar('|');
if (separator == -1)
error("At marker %s, person %s in family %s has genotype %s.\n"
"This genotype is not in the 'al1/al2' format.\n",
(const char *) markerNames[m],
(const char *) p->pid,
(const char *) p->famid,
(const char *) phenotype);
allele1.Copy(phenotype, 0, separator);
allele1.Trim();
allele2.Copy(phenotype, separator + 1, 8);
allele2.Trim();
MarkerInfo * info = GetMarkerInfo(m);
int one = info->alleleNumbers.Integer(allele1);
if (one < 0)
{
if (info->freq.Length() == 0)
one = info->NewAllele(allele1);
else
error("At marker %s, person %s in family %s has genotype %s.\n"
"However, '%s' is not a valid allele for this marker.\n",
(const char *) markerNames[m],
(const char *) p->pid,
(const char *) p->famid,
(const char *) phenotype,
(const char *) allele1);
}
int two = info->alleleNumbers.Integer(allele2);
if (two < 0)
{
if (info->freq.Length() == 0)
two = info->NewAllele(allele2);
else
error("At marker %s, person %s in family %s has genotype %s.\n"
"However, '%s' is not a valid allele for this marker.\n",
(const char *) markerNames[m],
(const char *) p->pid,
(const char *) p->famid,
(const char *) phenotype,
(const char *) allele2);
}
p->markers[m].one = one;
p->markers[m].two = two;
break;
}
case pcEnd :
break;
case pcTrait :
case pcCovariate :
case pcSkip :
case pcZygosity :
default:
error("Inconsistent Pedigree Description -- Internal Error");
}
records.Flush();
}
}
Sort();
}
FortranFormat
Definition: FortranFormat.h:25

## LumpAlleles()

void Pedigree::LumpAlleles | ( | double | treshold,
|  | bool | reorder = `true`
| ) |  |

Definition at line 230 of file Pedigree.cpp.

{
if (min > 0.0)
printf("Lumping alleles with frequencies of %.2f or less...\n\n", min);
for (int m=0; m < markerCount; m++)
::LumpAlleles(*this, m, min, reorder);
}

## MergeTwins()

void Pedigree::MergeTwins | ( |  | ) |

Definition at line 100 of file PedigreeTwin.cpp.

{
if (!haveTwins) return;
IntArray mzTwins, surplus;
printf("Merging MZ twins into a single individual...\n");
for (int f = 0; f < familyCount; f++)
{
mzTwins.Clear();
for (int i = families[f]->first, j; i <= families[f]->last; i++)
if (persons[i]->isMzTwin(*persons[i]))
{
// Have we got another identical sib yet?
for (j = 0; j < mzTwins.Length(); j++)
if (persons[i]->isMzTwin(*persons[mzTwins[j]]))
break;
// If not, add to list of twins
if (j == mzTwins.Length())
{
mzTwins.Push(i);
continue;
}
// Append name to first twins name
persons[mzTwins[j]]->pid += ((char) '$') + persons[i]->pid;
// Set the first twin to affected if at least one of the cotwins is affected
for (int j = 0; j < affectionCount; j++)
if (persons[i]->affections[j] == 2)
persons[mzTwins[j]]->affections[j] = 2;
surplus.Push(i);
}
// More than one representative of each twin-pair...
if (surplus.Length())
{
// Reassign parent names for each offspring
for (int i = families[f]->first, j; i < families[f]->last; i++)
if (!persons[i]->isFounder())
{
if (persons[i]->father->isMzTwin(*persons[i]->father))
{
for (j = 0; j < mzTwins.Length(); j++)
if (persons[i]->father->isMzTwin(*persons[mzTwins[j]]))
break;
persons[i]->fatid = persons[mzTwins[j]]->pid;
}
if (persons[i]->mother->isMzTwin(*persons[i]->mother))
{
for (j = 0; j < mzTwins.Length(); j++)
if (persons[i]->mother->isMzTwin(*persons[mzTwins[j]]))
break;
persons[i]->motid = persons[mzTwins[j]]->pid;
}
}
// Delete surplus individuals
while (surplus.Length())
{
int serial = surplus.Pop();
delete persons[serial];
for (count--; serial < count; serial++)
persons[serial] = persons[serial + 1];
}
// Resort pedigree
Sort();
}
}
}

## operator[]()

Person & Pedigree::operator[] | ( | int | i | ) |

inline

Definition at line 102 of file Pedigree.h.

{
return *(persons[i]);
}

## Prepare() [1/2]

void Pedigree::Prepare | ( | const char * | input | ) |

Definition at line 533 of file PedigreeLoader.cpp.

{
// Clear any previously loaded pedigree description
if (multiPd != NULL)
delete [] multiPd;
multiFileCount = 1;
// Enable multifile support
StringArray filenames;
filenames.AddColumns(filename, ',');
if (filenames.Length() <= 1)
pd.Load(filename);
else
{
printf("AUTOMATIC MERGE ENABLED: Detected multiple datafile names, separated by commas...\n");
multiPd = new PedigreeDescription[filenames.Length()];
for (int i = 0; i < filenames.Length(); i++)
{
printf(" AUTOMATIC MERGE: Reading data file '%s' ...\n", (const char *) filenames[i]);
multiPd[i].Load(filenames[i], false);
}
multiFileCount = filenames.Length();
}
}
PedigreeDescription
Definition: PedigreeDescription.h:42

## Prepare() [2/2]

void Pedigree::Prepare | ( | IFILE & | input | ) |

Definition at line 26 of file PedigreeLoader.cpp.

{
pd.Load(input);
}

## PrepareDichotomization()

void Pedigree::PrepareDichotomization | ( |  | ) |

Definition at line 450 of file Pedigree.cpp.

{
for (int t = 0; t < traitCount; t++)
{
String new_affection = traitNames[t] + "*";
GetAffectionID(new_affection);
}
}

## SexLinkedCheck()

bool Pedigree::SexLinkedCheck | ( |  | ) |

Definition at line 706 of file Pedigree.cpp.

{
bool fail = false;
// Keep track of what families fail the basic inheritance check,
// so that we can run later run genotype elimination check on the remainder
IntArray failedFamilies(familyCount);
// For each marker ...
for (int m = 0; m < markerCount; m++)
{
MarkerInfo * info = GetMarkerInfo(m);
failedFamilies.Zero();
// Check for homozygous males
for (int f = 0; f < familyCount; f++)
for (int i = families[f]->first; i <= families[f]->last; i++)
if (persons[i]->sex == SEX_MALE && persons[i]->markers[m].isKnown() &&
!persons[i]->markers[m].isHomozygous())
{
printf("%s - Fam %s: Male %s has two X alleles [%s/%s]\n",
(const char *) markerNames[m],
(const char *) persons[i]->famid, (const char *) persons[i]->pid,
(const char *) info->GetAlleleLabel(persons[i]->markers[m].one),
(const char *) info->GetAlleleLabel(persons[i]->markers[m].two));
// Wipe this genotype so we don't get cascading errors below
persons[i]->markers[m][0] = persons[i]->markers[m][1] = 0;
fail = true;
failedFamilies[f] = true;
}
// Check full sibships for errors
// TODO -- We could do better by grouping male half-sibs
for (int f = 0; f < familyCount; f++)
for (int i = families[f]->first; i <= families[f]->last; i++)
if (!persons[i]->isFounder() && persons[i]->sibs[0] == persons[i])
{
// This loop runs once per sibship
Alleles fat = persons[i]->father->markers[m];
Alleles mot = persons[i]->mother->markers[m];
bool fgeno = fat.isKnown();
bool mgeno = mot.isKnown();
Alleles inferred_mother = mot;
Alleles first_sister;
Alleles inferred_father;
bool mother_ok = true;
int sisters = 0;
for (int j = 0; j < persons[i]->sibCount; j++)
if (persons[i]->sibs[j]->isGenotyped(m))
{
Alleles geno = persons[i]->sibs[j]->markers[m];
bool fat1 = fat.hasAllele(geno.one);
bool fat2 = fat.hasAllele(geno.two);
bool mot1 = mot.hasAllele(geno.one);
bool mot2 = mot.hasAllele(geno.two);
int sex = persons[i]->sibs[j]->sex;
if (sex == SEX_MALE)
{
if (mgeno && !mot1)
{
printf("%s - Fam %s: Child %s [%s/Y] has mother [%s/%s]\n",
(const char *) markerNames[m],
(const char *) persons[i]->famid,
(const char *) persons[i]->sibs[j]->pid,
(const char *) info->GetAlleleLabel(geno.one),
(const char *) info->GetAlleleLabel(mot.one),
(const char *) info->GetAlleleLabel(mot.two));
fail = true;
failedFamilies[f] = true;
}
else
mother_ok &= inferred_mother.AddAllele(geno.one);
}
if (sex == SEX_FEMALE)
{
if ((fgeno && mgeno && !((fat1 && mot2) || (fat2 && mot1))) ||
(fgeno && !(fat1 || fat2)) || (mgeno && !(mot1 || mot2)))
{
printf("%s - Fam %s: Child %s [%s/%s] has ",
(const char *) markerNames[m],
(const char *) persons[i]->famid,
(const char *) persons[i]->sibs[j]->pid,
(const char *) info->GetAlleleLabel(geno.one),
(const char *) info->GetAlleleLabel(geno.two));
if (!fgeno)
printf("mother [%s/%s]\n",
(const char *) info->GetAlleleLabel(mot.one),
(const char *) info->GetAlleleLabel(mot.two));
else if (!mgeno)
printf("father [%s/Y]\n",
(const char *) info->GetAlleleLabel(fat.one));
else
printf("parents [%s/Y]*[%s/%s]\n",
(const char *) info->GetAlleleLabel(fat.one),
(const char *) info->GetAlleleLabel(mot.one),
(const char *) info->GetAlleleLabel(mot.two));
fail = true;
failedFamilies[f] = true;
}
else
{
if (!sisters++)
inferred_father = first_sister = geno;
else if (first_sister != geno)
{
inferred_father.Intersect(geno);
mother_ok &= inferred_mother.AddAllele(
geno.otherAllele(inferred_father.one));
mother_ok &= inferred_mother.AddAllele(
first_sister.otherAllele(inferred_father.one));
}
if (!fgeno && (mot1 ^ mot2))
inferred_father.Intersect(mot1 ? geno.two : geno.one);
if (!mgeno && (fat1 ^ fat2))
mother_ok &= inferred_mother.AddAllele(fat1 ? geno.two : geno.one);
}
}
}
if (!mother_ok || (sisters && !inferred_father.isKnown()))
{
printf("%s - Fam %s: ",
(const char *) markerNames[m],
(const char *) persons[i]->famid);
if (fgeno)
printf("Father %s [%s/Y] has children [",
(const char *) persons[i]->father->pid,
(const char *) info->GetAlleleLabel(fat.one));
else if (mgeno)
printf("Mother %s [%s/%s] has children [",
(const char *) persons[i]->mother->pid,
(const char *) info->GetAlleleLabel(mot.one),
(const char *) info->GetAlleleLabel(mot.two));
else
printf("Couple %s * %s has children [",
(const char *) persons[i]->mother->pid,
(const char *) persons[i]->father->pid);
for (int j = 0; j < persons[i]->sibCount; j++)
printf(
persons[i]->sibs[j]->sex == SEX_MALE ? "%s%s/Y" : "%s%s/%s",
j == 0 ? "" : " ",
(const char *) info->GetAlleleLabel(persons[i]->sibs[j]->markers[m].one),
(const char *) info->GetAlleleLabel(persons[i]->sibs[j]->markers[m].two));
printf("]\n");
fail = true;
failedFamilies[f] = true;
}
}
for (int f = 0; f < familyCount; f++)
if (!failedFamilies[f] &&
(families[f]->count > families[f]->founders + 1) &&
!families[f]->isNuclear())
fail |= !GenotypeList::EliminateGenotypes(*this, families[f], m);
}
if (fail)
printf("\nMendelian inheritance errors detected\n");
return fail;
}

## ShowMemoryInfo()

void Pedigree::ShowMemoryInfo | ( |  | ) |

Definition at line 940 of file Pedigree.cpp.

{
unsigned int bytes = 0;
for (int i = 0; i < count; i++)
bytes += persons[i]->famid.BufferSize() + persons[i]->pid.BufferSize() +
persons[i]->fatid.BufferSize() + persons[i]->motid.BufferSize();
bytes += count * (markerCount * sizeof(Alleles) + traitCount * sizeof(double) +
covariateCount * sizeof(double) + affectionCount * sizeof(char) +
sizeof(Person));
printf(" %40s %s\n", "Pedigree file ...", (const char *) MemoryInfo(bytes));
}

## Sort()

void Pedigree::Sort | ( |  | ) |

Definition at line 56 of file Pedigree.cpp.

{
QuickSort(persons, count, sizeof(Person *),
COMPAREFUNC Pedigree::ComparePersons);
haveTwins = 0;
// Check for structural problems in input pedigree
bool problem = false;
// Check that we have no duplicates...
for (int i = 1; i < count; i++)
if (ComparePersons((const Person **) &persons[i-1],
(const Person **) &persons[i]) == 0)
{
printf("Family %s: Person %s is duplicated\n",
(const char *) persons[i]->famid,
(const char *) persons[i]->pid);
problem = true;
do
{
i++;
}
while (i < count &&
ComparePersons((const Person **) &persons[i-1],
(const Person **) &persons[i]) == 0);
}
// Assign parents...
for (int i = 0; i < count; i++)
{
persons[i]->serial = i;
persons[i]->father = FindPerson(persons[i]->famid, persons[i]->fatid);
persons[i]->mother = FindPerson(persons[i]->famid, persons[i]->motid);
problem |= !persons[i]->CheckParents();
persons[i]->AssessStatus();
// Check if we have any twins...
haveTwins |= persons[i]->zygosity;
}
if (problem)
error("Please correct problems with pedigree structure\n");
MakeSibships();
MakeFamilies();
}

## TranslateSexCode()

int Pedigree::TranslateSexCode | ( | const char * | code,
|  | bool & | failure
| ) |  |

Definition at line 619 of file PedigreeLoader.cpp.

{
failure = false;
switch (code[0])
{
case 'x' :
case 'X' :
case '?' :
return 0;
case '1' :
case 'm' :
case 'M' :
return 1;
case '2' :
case 'f' :
case 'F' :
return 2;
default :
{
int result = atoi(code);
if (result != 0 && result != 1 && result != 2)
{
failure = true;
result = 0;
}
return result;
}
};
}

## Trim()

void Pedigree::Trim | ( | bool | quiet = `false`,
|  | int * | informative = `NULL`
| ) |  |

Definition at line 29 of file PedigreeTrim.cpp.

{
int newCount = 0;
Person ** newPersons = new Person * [count];
// This function applies the following filters to reduce complexity
// of pedigree
//
// RULE 1: Remove all pedigrees no genotype or phenotype data
// RULE 2: Remove leaf individuals with no data
// RULE 3: Remove founder couples with <2 offspring and no data
bool showHeader = true;
IntArray discardable, offspring, mates, haveData;
for (int f = 0; f < familyCount; f++)
{
Family * fam = families[f];
// Cache for storing indicators about whether each family member is
// informative
haveData.Dimension(fam->count);
// Check that some data is available in the family
int hasData = false;
for (int i = fam->first; i <= fam->last; i++)
if (informative == NULL)
hasData |= haveData[persons[i]->traverse] = persons[i]->haveData();
else
hasData |= haveData[persons[i]->traverse] = informative[i];
if (!hasData)
{
if (!quiet)
{
ShowTrimHeader(showHeader);
printf(" Removing family %s: No data\n", (const char *) fam->famid);
}
for (int i = fam->first; i <= fam->last; i++)
delete persons[i];
continue;
}
// Assume that we need everyone in the family
discardable.Dimension(fam->count);
discardable.Set(0);
bool trimming = true;
while (trimming)
{
trimming = false;
// Tally the number of offspring for each individual
offspring.Dimension(fam->count);
offspring.Zero();
// Tally the number of mates for each individual
mates.Dimension(fam->count);
mates.Set(-1);
// In the first round, we count the number of offspring
// for each individual in the current trimmed version of the
// pedigree
for (int i = fam->count - 1; i >= fam->founders; i--)
{
if (discardable[i]) continue;
Person & p = *(persons[fam->path[i]]);
if (discardable[p.father->traverse])
continue;
if (offspring[i] == 0 && !haveData[p.traverse])
{
trimming = true;
discardable[i] = true;
continue;
}
int father = p.father->traverse;
int mother = p.mother->traverse;
if (mates[father] == -1 && mates[mother] == -1)
{
mates[father] = mother,
mates[mother] = father;
}
else if (mates[father] != mother)
{
if (mates[father] >= 0)
mates[mates[father]] = -2;
if (mates[mother] >= 0)
mates[mates[mother]] = -2;
mates[mother] = -2;
mates[father] = -2;
}
offspring[father]++;
offspring[mother]++;
}
// In the second pass, we remove individuals with no
// data who are founders with a single offspring (and
// no multiple matings) or who have no descendants
for (int i = fam->count - 1; i >= 0; i--)
{
if (discardable[i]) continue;
Person & p = *(persons[fam->path[i]]);
if (p.isFounder() || discardable[p.father->traverse])
{
if (mates[i] == -2 ||
offspring[i] > 1 ||
(mates[i] >= fam->founders &&
!discardable[persons[fam->path[mates[i]]]->father->traverse]) ||
haveData[p.traverse] ||
(mates[i] != -1 && haveData[mates[i]]))
continue;
trimming = true;
discardable[i] = true;
continue;
}
}
}
for (int i = fam->count - 1; i >= 0; i--)
if (discardable[i])
{
if (!quiet)
{
ShowTrimHeader(showHeader);
printf(" Removing person %s->%s: No data\n",
(const char *) fam->famid,
(const char *) persons[fam->path[i]]->pid);
}
delete persons[fam->path[i]];
}
else
newPersons[newCount++] = persons[fam->path[i]];
}
if (!showHeader)
printf("\n");
delete [] persons;
persons = newPersons;
count = newCount;
Sort();
}

## TwinCheck()

bool Pedigree::TwinCheck | ( |  | ) |

Definition at line 23 of file PedigreeTwin.cpp.

{
bool fail = false;
IntArray mzTwins;
for (int f = 0; f < familyCount; f++)
{
mzTwins.Clear();
for (int i = families[f]->first, j; i <= families[f]->last; i++)
// Is this person an identical twin?
if (persons[i]->isMzTwin(*persons[i]))
{
// Have we got another identical sib yet?
for (j = 0; j < mzTwins.Length(); j++)
if (persons[i]->isMzTwin(*persons[mzTwins[j]]))
break;
// If not, add to list of twins
if (j == mzTwins.Length())
{
mzTwins.Push(i);
continue;
}
// Check that their genotypes are compatible and
// merge new twin's genotypes into original twin...
Person * original = persons[mzTwins[j]];
Person * twin = persons[i];
for (int m = 0; m < Person::markerCount; m++)
{
if (!original->markers[m].isKnown())
original->markers[m] = twin->markers[m];
else if (twin->markers[m].isKnown() &&
twin->markers[m] != original->markers[m])
printf("MZ Twins %s and %s in family %s have "
"different %s genotypes\n",
(const char *) original->pid,
(const char *) twin->pid,
(const char *) original->famid,
(const char *) Person::markerNames[m]),
fail = true;
if (twin->sex != original->sex)
printf("MZ Twins %s and %s in family %s have "
"different sexes\n",
(const char *) original->pid,
(const char *) twin->pid,
(const char *) original->famid),
fail = true;
}
}
if (mzTwins.Length() == 0) continue;
// In the second pass we copy merged twin genotypes
// from original twin to other twins
for (int i = families[f]->first, j; i <= families[f]->last; i++)
if (persons[i]->isMzTwin(*persons[i]))
{
for (j = 0; j < mzTwins.Length(); j++)
if (persons[i]->isMzTwin(*persons[mzTwins[j]]))
break;
if (mzTwins[j] == i) continue;
Person * original = persons[mzTwins[j]];
Person * twin = persons[i];
for (int m = 0; m < Person::markerCount; m++)
twin->markers[m] = original->markers[m];
}
}
return fail;
}

## WriteDataFile() [1/2]

void Pedigree::WriteDataFile | ( | const char * | output | ) |

Definition at line 434 of file Pedigree.cpp.

{
FILE * f = fopen(output, "wt");
if (f == NULL) error("Couldn't open data file %s", output);
WriteDataFile(f);
fclose(f);
}

## WriteDataFile() [2/2]

void Pedigree::WriteDataFile | ( | FILE * | output | ) |

Definition at line 324 of file Pedigree.cpp.

{
// write in the following order:
// markers, traits, affections, covariates
if (haveTwins)
fprintf(output, " Z Zygosity\n");
for (int m = 0; m < markerCount; m++)
fprintf(output, " M %s\n", (const char *) markerNames[m]);
for (int t = 0; t < traitCount; t++)
fprintf(output, " T %s\n", (const char *) traitNames[t]);
for (int a = 0; a < affectionCount; a++)
fprintf(output, " A %s\n", (const char *) affectionNames[a]);
for (int c = 0; c < covariateCount; c++)
fprintf(output, " C %s\n", (const char *) covariateNames[c]);
for (int s = 0; s < stringCount; s++)
fprintf(output, " $ %s\n", (const char *) stringNames[s]);
fprintf(output, " E END-OF-DATA \n");
}

## WritePedigreeFile() [1/2]

void Pedigree::WritePedigreeFile | ( | const char * | output | ) |

Definition at line 442 of file Pedigree.cpp.

{
FILE * f = fopen(output, "wt");
if (f == NULL) error("Couldn't open pedigree file %s", output);
WritePedigreeFile(f);
fclose(f);
}

## WritePedigreeFile() [2/2]

void Pedigree::WritePedigreeFile | ( | FILE * | output | ) |

Definition at line 350 of file Pedigree.cpp.

{
MarkerInfo ** info = new MarkerInfo * [markerCount];
for (int i = 0; i < markerCount; i++)
info[i] = GetMarkerInfo(i);
for (int i = 0; i < count; i++)
WriteRecodedPerson(output, i, info);
fprintf(output, "end\n");
delete [] info;
}

## WritePerson()

void Pedigree::WritePerson | ( | FILE * | output,
|  | int | who,
|  | const char * | famid = `NULL`,
|  | const char * | pid = `NULL`,
|  | const char * | fatid = `NULL`,
|  | const char * | motid = `NULL`
| ) |  |

Definition at line 364 of file Pedigree.cpp.

{
WriteRecodedPerson(output, person, NULL, famid, pid, fatid, motid);
}

## WriteRecodedPerson()

void Pedigree::WriteRecodedPerson | ( | FILE * | output,
|  | int | who,
|  | MarkerInfo ** | markerInfo,
|  | const char * | famid = `NULL`,
|  | const char * | pid = `NULL`,
|  | const char * | fatid = `NULL`,
|  | const char * | motid = `NULL`
| ) |  |

Definition at line 370 of file Pedigree.cpp.

{
Person * p = persons[person];
if (famid == NULL) famid = p->famid;
if (pid == NULL) pid = p->pid;
if (fatid == NULL) fatid = p->fatid;
if (motid == NULL) motid = p->motid;
// write in the following order:
// markers, traits, affections, covariates
fprintf(output, "%s\t%s\t%s\t%s\t%d\t",
famid, pid, fatid, motid, p->sex);
const char * twinCodes[] = {"0", "MZ", "DZ"};
if (haveTwins)
{
if (p->zygosity <= 2)
fprintf(output, "%s\t", twinCodes[p->zygosity]);
else
fprintf(output, "%d\t", p->zygosity);
}
for (int m = 0; m < markerCount; m++)
if (markerInfo == NULL)
fprintf(output, markerCount < 20 ? "%3d/%3d\t" : "%d/%d\t",
p->markers[m][0], p->markers[m][1]);
else
fprintf(output, markerCount < 20 ? "%3s/%3s\t" : "%s/%s\t",
(const char *) markerInfo[m]->GetAlleleLabel(p->markers[m][0]),
(const char *) markerInfo[m]->GetAlleleLabel(p->markers[m][1]));
for (int t = 0; t < traitCount; t++)
if (p->isPhenotyped(t))
fprintf(output, "%.3f\t", p->traits[t]);
else
fprintf(output, "x\t");
for (int a = 0; a < affectionCount; a++)
if (p->isDiagnosed(a))
fprintf(output, "%d\t", p->affections[a]);
else
fprintf(output, "x\t");
for (int c = 0; c < covariateCount; c++)
if (p->isControlled(c))
fprintf(output, "%.3f\t", p->covariates[c]);
else
fprintf(output, "x\t");
for (int s = 0; s < stringCount; s++)
if (!p->strings[s].IsEmpty())
fprintf(output, "%s\t", (const char *) p->strings[s]);
else
fprintf(output, ".\t");
fprintf(output, "\n");
}

## Member Data Documentation

## count

int Pedigree::count

Definition at line 39 of file Pedigree.h.

## families

Family** Pedigree::families

Definition at line 42 of file Pedigree.h.

## familyCount

int Pedigree::familyCount

Definition at line 41 of file Pedigree.h.

## haveTwins

int Pedigree::haveTwins

Definition at line 43 of file Pedigree.h.

## missing

String Pedigree::missing

static

Definition at line 36 of file Pedigree.h.

## multiFileCount

int Pedigree::multiFileCount

Definition at line 47 of file Pedigree.h.

## multiPd

PedigreeDescription* Pedigree::multiPd

Definition at line 46 of file Pedigree.h.

## pd

PedigreeDescription Pedigree::pd

Definition at line 45 of file Pedigree.h.

## persons

Person** Pedigree::persons

Definition at line 40 of file Pedigree.h.

## sexAsCovariate

bool Pedigree::sexAsCovariate = false

static

Definition at line 35 of file Pedigree.h.

## size

int Pedigree::size

Definition at line 38 of file Pedigree.h.

The documentation for this class was generated from the following files:

- general/Pedigree.h
- general/Pedigree.cpp
- general/PedigreeLoader.cpp
- general/PedigreeTrim.cpp
- general/PedigreeTwin.cpp