libStatGen Software
1
|
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 }