PedigreeFamily.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "Pedigree.h"
00019 #include "Constant.h"
00020 #include "MathConstant.h"
00021 #include "Error.h"
00022
00023 #include <stdlib.h>
00024 #include <ctype.h>
00025 #include <string.h>
00026 #include <limits.h>
00027
00028 Family::Family(Pedigree & pedigree, int _first, int _last, int _serial) :
00029 ped(pedigree)
00030 {
00031 serial = _serial;
00032 first = _first;
00033 last = _last;
00034 count = last - first + 1;
00035 path = new int [count];
00036 famid = ped[first].famid;
00037
00038 founders = mzTwins = 0;
00039
00040 for (int i=first; i<=last; i++)
00041 if (ped[i].isFounder())
00042 {
00043 ped[i].traverse = founders;
00044 path[founders++] = ped[i].serial;
00045 }
00046 else
00047 {
00048 ped[i].traverse = -1;
00049 if (ped[i].isMzTwin(ped[i]))
00050 for (int j = first; j < i; j++)
00051 if (ped[i].isMzTwin(ped[j]))
00052 {
00053 mzTwins++;
00054 break;
00055 }
00056 }
00057
00058 nonFounders = count - founders;
00059 generations = nonFounders == 0 ? 1 : 2;
00060
00061 int next = founders;
00062 while (next < count)
00063 {
00064 bool check = false;
00065
00066
00067 for (int i=first; i<=last; i++)
00068 if (ped[i].traverse == -1)
00069 {
00070 int fatherSerial = ped[i].father->traverse;
00071 int motherSerial = ped[i].mother->traverse;
00072
00073 if (fatherSerial >= 0 && motherSerial >= 0)
00074 {
00075 check = true;
00076
00077 ped[i].traverse = next;
00078 path[next++] = i;
00079
00080 if (fatherSerial >= founders || motherSerial >= founders)
00081 generations = 3;
00082
00083
00084 if (ped[i].zygosity & 1)
00085 for (int j = 0; j < ped[i].sibCount; j++)
00086 {
00087 Person & sib = *ped[i].sibs[j];
00088
00089
00090
00091 if (sib.traverse == -1 && ped[i].zygosity == sib.zygosity)
00092 {
00093 sib.traverse = next;
00094 path[next++] = sib.serial;
00095 }
00096 }
00097 }
00098 }
00099
00100 if (!check) ShowInvalidCycles();
00101 }
00102 }
00103
00104 Family::~Family()
00105 {
00106 delete [] path;
00107 }
00108
00109 void Family::ShowInvalidCycles()
00110 {
00111
00112
00113
00114
00115
00116
00117
00118
00119 IntArray descendants(ped.count);
00120 descendants.Zero();
00121
00122 for (int i = first; i <= last; i++)
00123 if (ped[i].traverse == -1)
00124 {
00125 descendants[ped[i].father->serial]++;
00126 descendants[ped[i].mother->serial]++;
00127 }
00128
00129 IntArray stack;
00130
00131 for (int i = first; i <= last; i++)
00132 if (ped[i].traverse == -1 && descendants[i] == 0)
00133 {
00134 stack.Push(i);
00135
00136 do
00137 {
00138 int j = stack.Pop();
00139
00140 if (ped[j].traverse != -1) continue;
00141
00142 ped[j].traverse = 9999;
00143
00144 if (--descendants[ped[j].father->serial] == 0)
00145 stack.Push(ped[j].father->serial);
00146 if (--descendants[ped[j].mother->serial] == 0)
00147 stack.Push(ped[j].mother->serial);
00148 }
00149 while (stack.Length());
00150 }
00151
00152 printf("The structure of family %s requires\n"
00153 "an individual to be his own ancestor.\n\n"
00154 "To identify the problem(s), examine the\n"
00155 "following key individuals:\n\n",
00156 (const char *) famid);
00157
00158 for (int i = first; i <= last; i++)
00159 if (ped[i].traverse == -1)
00160 printf("Problem Person: %s\n", (const char *) ped[i].pid);
00161
00162 error("Invalid pedigree structure.");
00163 }
00164
00165 int Family::ConnectedGroups(IntArray * groupMembership)
00166 {
00167 IntArray groups(count);
00168
00169
00170 groups.SetSequence(0, 1);
00171 for (int i = count - 1; i >= founders; i--)
00172 {
00173
00174 int group0 = i;
00175 int group1 = ped[path[i]].father->traverse;
00176 int group2 = ped[path[i]].mother->traverse;
00177
00178
00179 while (groups[group0] != group0) group0 = groups[group0];
00180 while (groups[group1] != group1) group1 = groups[group1];
00181 while (groups[group2] != group2) group2 = groups[group2];
00182
00183 int group = group1 < group2 ? group1 : group2;
00184 if (group0 < group) group = group0;
00185
00186 groups[group0] = groups[group1] = groups[group2] = group;
00187 }
00188
00189
00190 int groupCount = 0;
00191 for (int i = 0; i < founders; i++)
00192 if (groups[i] == i)
00193 groupCount++;
00194
00195 if (groupMembership == NULL)
00196 return groupCount;
00197
00198
00199 for (int i = 1; i < count; i++)
00200 groups[i] = groups[groups[i]];
00201
00202
00203 int group = 0;
00204 groupMembership->Dimension(count);
00205 for (int i = 0; i < count; i++)
00206 if (groups[i] == i)
00207 (*groupMembership)[i] = ++group;
00208 else
00209 (*groupMembership)[i] = (*groupMembership)[groups[i]];
00210
00211 #if 0
00212
00213
00214 for (int j = first; j <= last; j++)
00215 printf("%s %s %s %s %d %d\n",
00216 (const char *) famid, (const char *) ped[j].pid,
00217 (const char *) ped[j].fatid, (const char *) ped[j].motid,
00218 ped[j].sex, groups[ped[j].traverse]);
00219 #endif
00220
00221 return groupCount;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295