PedigreePerson.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 "PedigreePerson.h"
00019 #include "Constant.h"
00020 #include "StringArray.h"
00021 #include "Error.h"
00022 
00023 #include <stdlib.h>
00024 #include <ctype.h>
00025 #include <string.h>
00026 #include <limits.h>
00027 
00028 Person::Person()
00029 {
00030     zygosity = sex = 0;
00031     serial = traverse = -1;
00032 
00033     markers = new Alleles [markerCount];
00034     traits = new double [traitCount];
00035     covariates = new double [covariateCount];
00036     affections = new char [affectionCount];
00037 
00038     for (int i = 0; i < traitCount; i++) traits[i] = _NAN_;
00039     for (int i = 0; i < covariateCount; i++) covariates[i] = _NAN_;
00040     for (int i = 0; i < affectionCount; i++) affections[i] = 0;
00041 
00042     filter = false;
00043 
00044     father = mother = NULL;
00045     sibs = NULL;
00046     sibCount = 0;
00047 
00048     ngeno = 0;
00049     hasBothParents = hasAllTraits = hasAllAffections = hasAllCovariates = false;
00050 }
00051 
00052 Person::~Person()
00053 {
00054     delete [] markers;
00055     delete [] traits;
00056     delete [] affections;
00057     delete [] covariates;
00058 
00059     if (sibCount) delete [] sibs;
00060 }
00061 
00062 void Person::Copy(Person & rhs)
00063 {
00064     CopyIDs(rhs);
00065     CopyPhenotypes(rhs);
00066 }
00067 
00068 void Person::CopyPhenotypes(Person & rhs)
00069 {
00070     for (int i = 0; i < Person::traitCount; i++)
00071         traits[i] = rhs.traits[i];
00072     for (int i = 0; i < Person::affectionCount; i++)
00073         affections[i] = rhs.affections[i];
00074     for (int i = 0; i < Person::covariateCount; i++)
00075         covariates[i] = rhs.covariates[i];
00076     for (int i = 0; i < Person::markerCount; i++)
00077         markers[i] = rhs.markers[i];
00078     ngeno = rhs.ngeno;
00079 }
00080 
00081 void Person::WipePhenotypes(bool remove_genotypes)
00082 {
00083     for (int i = 0; i < traitCount; i++) traits[i] = _NAN_;
00084     for (int i = 0; i < covariateCount; i++) covariates[i] = _NAN_;
00085     for (int i = 0; i < affectionCount; i++) affections[i] = 0;
00086 
00087     if (remove_genotypes)
00088     {
00089         for (int i = 0; i < markerCount; i++)
00090             markers[i][0] = markers[i][1] = 0;
00091         ngeno = 0;
00092     }
00093 }
00094 
00095 void Person::CopyIDs(Person & rhs)
00096 {
00097     famid = rhs.famid;
00098     pid = rhs.pid;
00099     fatid = rhs.fatid;
00100     motid = rhs.motid;
00101     sex = rhs.sex;
00102     zygosity = rhs.zygosity;
00103 }
00104 
00105 bool Person::CheckParents()
00106 {
00107     hasBothParents = father != NULL && mother != NULL;
00108 
00109     if (!hasBothParents)
00110     {
00111         if (father != NULL || mother != NULL)
00112         {
00113             printf("Parent named %s for Person %s in Family %s is missing\n",
00114                    (father == NULL) ? (const char *) fatid : (const char *) motid,
00115                    (const char *) pid, (const char *) famid);
00116             return false;
00117         }
00118         else
00119             return true;
00120     }
00121 
00122     if (father->sex == SEX_FEMALE || mother->sex == SEX_MALE)
00123         // If parents are switched around, we can fix it...
00124     {
00125         Person * swap = father;
00126         father = mother;
00127         mother = swap;
00128 
00129         String temp = fatid;
00130         fatid = motid;
00131         motid = temp;
00132     }
00133 
00134     if (father->sex == SEX_FEMALE || mother->sex == SEX_MALE)
00135         // If things still don't make sense then the problem is more serious ...
00136     {
00137         printf("Parental sex codes don't make sense for Person %s in Family %s\n",
00138                (const char *) pid, (const char *) famid);
00139         return false;
00140     }
00141 
00142     return true;
00143 }
00144 
00145 void Person::AssessStatus()
00146 {
00147     hasBothParents = father != NULL && mother != NULL;
00148 
00149     hasAllTraits = hasAllAffections = hasAllCovariates = true;
00150 
00151     ngeno = 0;
00152     for (int m = 0; m < markerCount; m++)
00153         if (isGenotyped(m))
00154             ngeno++;
00155 
00156     for (int t = 0; t < traitCount; t++)
00157         if (!isPhenotyped(t))
00158         {
00159             hasAllTraits = false;
00160             break;
00161         }
00162 
00163     for (int c = 0; c < covariateCount; c++)
00164         if (!isControlled(c))
00165         {
00166             hasAllCovariates = false;
00167             break;
00168         }
00169 
00170     for (int a = 0; a < affectionCount; a++)
00171         if (!isDiagnosed(a))
00172         {
00173             hasAllAffections = false;
00174             break;
00175         }
00176 }
00177 
00178 void Person::Order(Person * & p1, Person * & p2)
00179 {
00180     if (p1->traverse > p2->traverse)
00181     {
00182         Person * temp = p1;
00183         p1 = p2;
00184         p2 = temp;
00185     }
00186 }
00187 
00188 int Person::GenotypedMarkers()
00189 {
00190     int count = 0;
00191 
00192     for (int m = 0; m < Person::markerCount; m++)
00193         if (markers[m].isKnown())
00194             count++;
00195 
00196     return count;
00197 }
00198 
00199 bool Person::haveData()
00200 {
00201     if (ngeno)
00202         return true;
00203 
00204     for (int i = 0; i < affectionCount; i++)
00205         if (affections[i] != 0)
00206             return true;
00207 
00208     for (int i = 0; i < traitCount; i++)
00209         if (traits[i] != _NAN_)
00210             return true;
00211 
00212     return false;
00213 }
00214 
00215 bool Person::isAncestor(Person * descendant)
00216 {
00217     if (traverse > descendant->traverse)
00218         return false;
00219 
00220     if (serial == descendant->serial)
00221         return true;
00222 
00223     if (descendant->isFounder())
00224         return false;
00225 
00226     return (isAncestor(descendant->mother) ||
00227             isAncestor(descendant->father));
00228 }
00229 
00230 
00231 
00232 
00233 
00234 
00235 
Generated on Wed Nov 17 15:38:29 2010 for StatGen Software by  doxygen 1.6.3