32{
33 if (pd.mendelFormat)
34 {
35 LoadMendel(input);
36 return;
37 }
38
39 int sexCovariate = sexAsCovariate ? GetCovariateID("sex") : -1;
40
41 int textCols = pd.CountTextColumns() + 5;
42 int oldCount = count;
43 bool warn = true;
44 int line = 0;
45
48
50 {
51 int field = 0;
52
53 buffer.ReadLine(input);
54
55 tokens.Clear();
56 tokens.AddTokens(buffer, WHITESPACE);
57
58 if (tokens.Length() == 0) continue;
59 if (tokens[0].SlowCompare("end") == 0) break;
60
61 line++;
62
63 if (tokens.Length() < textCols)
64 {
65 if (buffer.Length() > 79)
66 {
67 buffer.SetLength(75);
68 buffer += " ...";
69 }
70
72
73 pd.ColumnSummary(description);
74 error("Loading Pedigree...\n\n"
75 "Expecting %d columns (%s),\n"
76 "but read only %d columns in line %d.\n\n"
77 "The problem line is transcribed below:\n%s\n",
78 textCols, (const char *) description,
79 tokens.Length(), line, (const char *) buffer);
80 }
81
82 if (tokens.Length() > textCols && warn && textCols > 5)
83 {
84 pd.ColumnSummary(buffer);
85 printf("WARNING -- Trailing columns in pedigree file will be ignored\n"
86 " Expecting %d data columns (%s)\n"
87 " However line %d, for example, has %d data columns\n\n",
88 textCols - 5, (const char *) buffer, line, tokens.Length() - 5);
89 warn = false;
90 }
91
93
94
95 if (oldCount==0 || (p = FindPerson(tokens[0], tokens[1], oldCount))==NULL)
96 {
97 if (count == size) Grow();
98
99 p = persons[count++] =
new Person;
100 }
101
102 p->famid = tokens[field++];
103 p->pid = tokens[field++];
104 p->fatid = tokens[field++];
105 p->motid = tokens[field++];
106
107 bool failure = false;
108 p->sex = TranslateSexCode(tokens[field++], failure);
109 if (failure)
110 error("Can't interpret the sex of individual #%d\n"
111 "Family: %s Individual: %s Sex Code: %s", count,
112 (const char *) p->famid, (const char *) p->pid,
113 (const char *) tokens[field-1]);
114
115 if (sexAsCovariate)
116 {
117 if (p->sex)
118 p->covariates[sexCovariate] = p->sex;
119 else
120 p->covariates[sexCovariate] = _NAN_;
121 }
122
123 for (int col = 0; col < pd.columnCount; col++)
124 switch (pd.columns[col])
125 {
126 case pcAffection :
127 {
128 int a = pd.columnHash[col];
129 int new_status;
130
131 const char * affection = tokens[field++];
132
133 switch (toupper(affection[0]))
134 {
135 case '1' :
136 case 'N' :
137 case 'U' :
138 new_status = 1;
139 break;
140 case '2' :
141 case 'D' :
142 case 'A' :
143 case 'Y' :
144 new_status = 2;
145 break;
146 default :
147 new_status = atoi(affection);
148 if (new_status < 0 || new_status > 2)
149 error("Incorrect formatting for affection status "
150 "Col %d, Affection %s\n"
151 "Family: %s Individual: %s Status: %s",
152 col, (const char *) affectionNames[a],
153 (const char *) p->famid, (const char *) p->pid,
154 affection);
155 }
156 if (new_status != 0 && p->affections[a] != 0 &&
157 new_status != p->affections[a])
158 error("Conflict with previous affection status - "
159 "Col %d, Affection %s\n"
160 "Family: %s Individual: %s Old: %d New: %d",
161 col, (const char *) affectionNames[a],
162 (const char *) p->famid, (const char *) p->pid,
163 p->affections[a], new_status);
164 if (new_status) p->affections[a] = new_status;
165 break;
166 }
167 case pcMarker :
168 {
169 int m = pd.columnHash[col];
170
172
173 new_genotype[0] = LoadAllele(m, tokens[field++]);
174 new_genotype[1] = LoadAllele(m, tokens[field++]);
175
176 if (p->markers[m].isKnown() && new_genotype.isKnown() &&
177 new_genotype != p->markers[m])
178 {
180
181 error("Conflict with previous genotype - Col %d, Marker %s\n"
182 "Family: %s Individual: %s Old: %s/%s New: %s/%s",
183 col, (const char *) markerNames[m],
184 (const char *) p->famid, (const char *) p->pid,
185 (const char *) info->GetAlleleLabel(p->markers[m][0]),
186 (const char *) info->GetAlleleLabel(p->markers[m][1]),
187 (const char *) info->GetAlleleLabel(new_genotype[0]),
188 (const char *) info->GetAlleleLabel(new_genotype[1]));
189 }
190
191 if (new_genotype.isKnown()) p->markers[m] = new_genotype;
192 break;
193 }
194 case pcTrait :
195 case pcUndocumentedTraitCovariate :
196 {
197 int t = pd.columnHash[col];
198 double new_pheno = _NAN_;
199
200 if (pd.columns[col] == pcUndocumentedTraitCovariate)
201 t = t / 32768;
202
203 const char * value = tokens[field++];
204 char * flag = NULL;
205
206 if (missing == (const char *) NULL || strcmp(value, missing) != 0)
207 new_pheno = strtod(value, &flag);
208 if (flag != NULL && *flag) new_pheno = _NAN_;
209
210 if (p->traits[t] != _NAN_ && new_pheno != _NAN_ &&
211 new_pheno != p->traits[t])
212 error("Conflict with previous phenotype - Col %d, Trait %s\n"
213 "Family: %s Individual: %s Old: %f New: %f",
214 col, (const char *) traitNames[t],
215 (const char *) p->famid, (const char *) p->pid,
216 p->traits[t], new_pheno);
217
218 if (new_pheno != _NAN_) p->traits[t] = new_pheno;
219 if (pd.columns[col] == pcTrait) break;
220 }
221 case pcCovariate :
222 {
223 int c = pd.columnHash[col];
224 double new_covar = _NAN_;
225
226 if (pd.columns[col] == pcUndocumentedTraitCovariate)
227 {
228 c = c % 32768;
229 field--;
230 }
231
232 const char * value = tokens[field++];
233 char * flag = NULL;
234
235 if (missing == (const char *) NULL || strcmp(value, missing) != 0)
236 new_covar = strtod(value, &flag);
237 if (flag != NULL && *flag) new_covar = _NAN_;
238
239 if (p->covariates[c] != _NAN_ && new_covar != _NAN_ &&
240 new_covar != p->covariates[c])
241 error("Conflict with previous value - Col %d, Covariate %s\n"
242 "Family: %s Individual: %s Old: %f New: %f",
243 col, (const char *) covariateNames[c],
244 (const char *) p->famid, (const char *) p->pid,
245 p->covariates[c], new_covar);
246
247 if (new_covar != _NAN_) p->covariates[c] = new_covar;
248 break;
249 }
250 case pcString :
251 {
252 int c = pd.columnHash[col];
253
254 if (!p->strings[c].IsEmpty() && p->strings[c] != tokens[field])
255 error("Conflict with previous value - Col %d, String %s\n"
256 "Family: %s Individual: %s Old: %s New: %s",
257 col, (const char *) stringNames[c],
258 (const char *) p->famid, (const char *) p->pid,
259 (const char *) p->strings[c], (const char *) tokens[field]);
260
261 p->strings[c] = tokens[field++];
262
263 break;
264 }
265 case pcSkip :
266 field++;
267 break;
268 case pcZygosity :
269 {
270 int new_zygosity;
271
272 const char * zygosity = tokens[field++];
273
274 switch (zygosity[0])
275 {
276 case 'D' :
277 case 'd' :
278 new_zygosity = 2;
279 break;
280 case 'M' :
281 case 'm' :
282 new_zygosity = 1;
283 break;
284 default :
285 new_zygosity = atoi(zygosity);
286 }
287 if (p->zygosity != 0 && new_zygosity != p->zygosity)
288 error("Conflict with previous zygosity - "
289 "Column %d in pedigree\n"
290 "Family: %s Individual: %s Old: %d New: %d\n",
291 col, (const char *) p->famid, (const char *) p->pid,
292 p->zygosity, new_zygosity);
293 p->zygosity = new_zygosity;
294 break;
295 }
296 case pcEnd :
297 break;
298 default :
299 error("Inconsistent Pedigree Description -- Internal Error");
300 }
301 }
302
303 Sort();
304}