20 #include "MathConstant.h"
28 Family::Family(
Pedigree & pedigree,
int _first,
int _last,
int _serial) :
34 count = last - first + 1;
35 path =
new int [count];
36 famid = ped[first].famid;
38 founders = mzTwins = 0;
40 for (
int i=first; i<=last; i++)
41 if (ped[i].isFounder())
43 ped[i].traverse = founders;
44 path[founders++] = ped[i].serial;
49 if (ped[i].isMzTwin(ped[i]))
50 for (
int j = first; j < i; j++)
51 if (ped[i].isMzTwin(ped[j]))
58 nonFounders = count - founders;
59 generations = nonFounders == 0 ? 1 : 2;
67 for (
int i=first; i<=last; i++)
68 if (ped[i].traverse == -1)
70 int fatherSerial = ped[i].father->traverse;
71 int motherSerial = ped[i].mother->traverse;
73 if (fatherSerial >= 0 && motherSerial >= 0)
77 ped[i].traverse = next;
80 if (fatherSerial >= founders || motherSerial >= founders)
84 if (ped[i].zygosity & 1)
85 for (
int j = 0; j < ped[i].sibCount; j++)
87 Person & sib = *ped[i].sibs[j];
91 if (sib.traverse == -1 && ped[i].zygosity == sib.zygosity)
94 path[next++] = sib.serial;
100 if (!check) ShowInvalidCycles();
109 void Family::ShowInvalidCycles()
122 for (
int i = first; i <= last; i++)
123 if (ped[i].traverse == -1)
125 descendants[ped[i].father->serial]++;
126 descendants[ped[i].mother->serial]++;
131 for (
int i = first; i <= last; i++)
132 if (ped[i].traverse == -1 && descendants[i] == 0)
140 if (ped[j].traverse != -1)
continue;
142 ped[j].traverse = 9999;
144 if (--descendants[ped[j].father->serial] == 0)
145 stack.Push(ped[j].father->serial);
146 if (--descendants[ped[j].mother->serial] == 0)
147 stack.Push(ped[j].mother->serial);
149 while (stack.Length());
152 printf(
"The structure of family %s requires\n"
153 "an individual to be his own ancestor.\n\n"
154 "To identify the problem(s), examine the\n"
155 "following key individuals:\n\n",
156 (
const char *) famid);
158 for (
int i = first; i <= last; i++)
159 if (ped[i].traverse == -1)
160 printf(
"Problem Person: %s\n", (
const char *) ped[i].pid);
162 error(
"Invalid pedigree structure.");
165 int Family::ConnectedGroups(
IntArray * groupMembership)
170 groups.SetSequence(0, 1);
171 for (
int i = count - 1; i >= founders; i--)
175 int group1 = ped[path[i]].father->traverse;
176 int group2 = ped[path[i]].mother->traverse;
179 while (groups[group0] != group0) group0 = groups[group0];
180 while (groups[group1] != group1) group1 = groups[group1];
181 while (groups[group2] != group2) group2 = groups[group2];
183 int group = group1 < group2 ? group1 : group2;
184 if (group0 < group) group = group0;
186 groups[group0] = groups[group1] = groups[group2] = group;
191 for (
int i = 0; i < founders; i++)
195 if (groupMembership == NULL)
199 for (
int i = 1; i < count; i++)
200 groups[i] = groups[groups[i]];
204 groupMembership->Dimension(count);
205 for (
int i = 0; i < count; i++)
207 (*groupMembership)[i] = ++group;
209 (*groupMembership)[i] = (*groupMembership)[groups[i]];
214 for (
int j = first; j <= last; j++)
215 printf(
"%s %s %s %s %d %d\n",
216 (
const char *) famid, (
const char *) ped[j].pid,
217 (
const char *) ped[j].fatid, (
const char *) ped[j].motid,
218 ped[j].sex, groups[ped[j].traverse]);