libStatGen Software  1
PedigreeTwin.cpp
00001 /*
00002  *  Copyright (C) 2010  Regents of the University of Michigan
00003  *
00004  *   This program is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #include "Pedigree.h"
00019 #include "Error.h"
00020 
00021 #include <stdio.h>
00022 
00023 bool Pedigree::TwinCheck()
00024 {
00025     bool fail = false;
00026     IntArray mzTwins;
00027 
00028     for (int f = 0; f < familyCount; f++)
00029     {
00030         mzTwins.Clear();
00031 
00032         for (int i = families[f]->first, j; i <= families[f]->last; i++)
00033             // Is this person an identical twin?
00034             if (persons[i]->isMzTwin(*persons[i]))
00035             {
00036                 // Have we got another identical sib yet?
00037                 for (j = 0; j < mzTwins.Length(); j++)
00038                     if (persons[i]->isMzTwin(*persons[mzTwins[j]]))
00039                         break;
00040 
00041                 // If not, add to list of twins
00042                 if (j == mzTwins.Length())
00043                 {
00044                     mzTwins.Push(i);
00045                     continue;
00046                 }
00047 
00048                 // Check that their genotypes are compatible and
00049                 // merge new twin's genotypes into original twin...
00050                 Person * original = persons[mzTwins[j]];
00051                 Person * twin = persons[i];
00052 
00053                 for (int m = 0; m < Person::markerCount; m++)
00054                 {
00055                     if (!original->markers[m].isKnown())
00056                         original->markers[m] = twin->markers[m];
00057                     else if (twin->markers[m].isKnown() &&
00058                              twin->markers[m] != original->markers[m])
00059                         printf("MZ Twins %s and %s in family %s have "
00060                                "different %s genotypes\n",
00061                                (const char *) original->pid,
00062                                (const char *) twin->pid,
00063                                (const char *) original->famid,
00064                                (const char *) Person::markerNames[m]),
00065                         fail = true;
00066 
00067                     if (twin->sex != original->sex)
00068                         printf("MZ Twins %s and %s in family %s have "
00069                                "different sexes\n",
00070                                (const char *) original->pid,
00071                                (const char *) twin->pid,
00072                                (const char *) original->famid),
00073                         fail = true;
00074                 }
00075             }
00076 
00077         if (mzTwins.Length() == 0) continue;
00078 
00079         // In the second pass we copy merged twin genotypes
00080         // from original twin to other twins
00081         for (int i = families[f]->first, j; i <= families[f]->last; i++)
00082             if (persons[i]->isMzTwin(*persons[i]))
00083             {
00084                 for (j = 0; j < mzTwins.Length(); j++)
00085                     if (persons[i]->isMzTwin(*persons[mzTwins[j]]))
00086                         break;
00087 
00088                 if (mzTwins[j] == i) continue;
00089 
00090                 Person * original = persons[mzTwins[j]];
00091                 Person * twin = persons[i];
00092 
00093                 for (int m = 0; m < Person::markerCount; m++)
00094                     twin->markers[m] = original->markers[m];
00095             }
00096     }
00097     return fail;
00098 }
00099 
00100 void Pedigree::MergeTwins()
00101 {
00102     if (!haveTwins) return;
00103 
00104     IntArray mzTwins, surplus;
00105 
00106     printf("Merging MZ twins into a single individual...\n");
00107 
00108     for (int f = 0; f < familyCount; f++)
00109     {
00110         mzTwins.Clear();
00111 
00112         for (int i = families[f]->first, j; i <= families[f]->last; i++)
00113             if (persons[i]->isMzTwin(*persons[i]))
00114             {
00115                 // Have we got another identical sib yet?
00116                 for (j = 0; j < mzTwins.Length(); j++)
00117                     if (persons[i]->isMzTwin(*persons[mzTwins[j]]))
00118                         break;
00119 
00120                 // If not, add to list of twins
00121                 if (j == mzTwins.Length())
00122                 {
00123                     mzTwins.Push(i);
00124                     continue;
00125                 }
00126 
00127                 // Append name to first twins name
00128                 persons[mzTwins[j]]->pid += ((char) '$') + persons[i]->pid;
00129 
00130                 // Set the first twin to affected if at least one of the cotwins is affected
00131                 for (int j = 0; j < affectionCount; j++)
00132                     if (persons[i]->affections[j] == 2)
00133                         persons[mzTwins[j]]->affections[j] = 2;
00134 
00135                 surplus.Push(i);
00136             }
00137 
00138         // More than one representative of each twin-pair...
00139         if (surplus.Length())
00140         {
00141             // Reassign parent names for each offspring
00142             for (int i = families[f]->first, j; i < families[f]->last; i++)
00143                 if (!persons[i]->isFounder())
00144                 {
00145                     if (persons[i]->father->isMzTwin(*persons[i]->father))
00146                     {
00147                         for (j = 0; j < mzTwins.Length(); j++)
00148                             if (persons[i]->father->isMzTwin(*persons[mzTwins[j]]))
00149                                 break;
00150                         persons[i]->fatid = persons[mzTwins[j]]->pid;
00151                     }
00152                     if (persons[i]->mother->isMzTwin(*persons[i]->mother))
00153                     {
00154                         for (j = 0; j < mzTwins.Length(); j++)
00155                             if (persons[i]->mother->isMzTwin(*persons[mzTwins[j]]))
00156                                 break;
00157                         persons[i]->motid = persons[mzTwins[j]]->pid;
00158                     }
00159                 }
00160 
00161             // Delete surplus individuals
00162             while (surplus.Length())
00163             {
00164                 int serial = surplus.Pop();
00165 
00166                 delete persons[serial];
00167 
00168                 for (count--; serial < count; serial++)
00169                     persons[serial] = persons[serial + 1];
00170             }
00171 
00172             // Resort pedigree
00173             Sort();
00174         }
00175     }
00176 }
00177 
00178 
00179 
00180 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends