void Family::ShowInvalidCycles() { // Try and identify key individuals responsible for // pedigree mess-up ... when this function is called // pedigree has been traversed top-down and individuals // that are correctly specified have IDs of >= 0. // This routine traverses the pedigree bottom up to // identify a subset of individuals likely to be causing // the problem IntArray descendants(ped.count); descendants.Zero(); for (int i = first; i <= last; i++) if (ped[i].traverse == -1) { descendants[ped[i].father->serial]++; descendants[ped[i].mother->serial]++; } IntArray stack; for (int i = first; i <= last; i++) if (ped[i].traverse == -1 && descendants[i] == 0) { stack.Push(i); do { int j = stack.Pop(); if (ped[j].traverse != -1) continue; ped[j].traverse = 9999; if (--descendants[ped[j].father->serial] == 0) stack.Push(ped[j].father->serial); if (--descendants[ped[j].mother->serial] == 0) stack.Push(ped[j].mother->serial); } while (stack.Length()); } printf("The structure of family %s requires\n" "an individual to be his own ancestor.\n\n" "To identify the problem(s), examine the\n" "following key individuals:\n\n", (const char *) famid); for (int i = first; i <= last; i++) if (ped[i].traverse == -1) printf("Problem Person: %s\n", (const char *) ped[i].pid); error("Invalid pedigree structure."); }
int HaploTree::Traverse(IntArray & pointer, IntArray & state) const { while (pointer.Length()) { int branch = pointer.Peek(); int & allele = state[levels[branch]]; int next = -1; while (++allele < alleleCounts[levels[branch]]) if ((next = PeekBranch(branch, allele)) != -1) break; if (next == -1) { allele = -1; pointer.Pop(); continue; } if (levels[branch] == depth - 1) return next; pointer.Push(next); } return -1; }
void HaploTree::SetupTraversal(IntArray & pointer, IntArray & state) const { pointer.Clear(); pointer.Push(0); state.Dimension(depth); state.Set(-1); }
void InverseNormalTransform(Pedigree & ped) { Vector phenotypes; IntArray individuals; QuickIndex index; phenotypes.Dimension(ped.count); individuals.Dimension(ped.count); for (int trait = 0; trait < ped.traitCount; trait++) { phenotypes.Dimension(0); individuals.Dimension(0); for (int i = 0; i < ped.count; i++) if (ped[i].traits[trait] != _NAN_) { phenotypes.Push(ped[i].traits[trait]); individuals.Push(i); } int count = individuals.Length(); if (count == 0) continue; index.Index(phenotypes); double scale = 1.0 / count; for (int i = 0, j; i < index.Length(); i++) { for (j = i; j + 1 < index.Length(); j++) if (ped[individuals[index[i]]].traits[trait] != ped[individuals[index[j]]].traits[trait] ) break; if (ped[individuals[index[i]]].traits[trait] != ped[individuals[index[j]]].traits[trait] ) j--; double z = ninv(((i + j) * 0.5 + 0.5) * scale); for (int k = i; k <= j; k++) ped[individuals[index[k]]].traits[trait] = z; i = j; } } }
bool Pedigree::TwinCheck() { 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; }