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