1 /******************************************************************************
2
3 #### # # ##### #### # # #### ####
4 # # # # # # # # ## ## # # #
5 # ###### # # # # # ## # #### #
6 # # # ##### # # # # # ### #
7 # # # # # # # # # # # # ### # #
8 #### # # # # #### # # #### ### ####
9
10 ******************************************************************************/
11 /* This file is part of MAPMAKER 3.0b, Copyright 1987-1992, Whitehead Institute
12 for Biomedical Research. All rights reserved. See READ.ME for license. */
13
14 #define INC_LIB
15 #define INC_MISC
16 #define INC_SHELL
17 #include "mapm.h"
18
19 SAVED_LIST *chromosome;
20 ASSIGNMENT **assignment;
21 PLACEMENT **placement;
22 int current_chrom;
23 bool do_assignment();
24 int get_anchors();
25
26
27 /* do_assignments anchor_locus framework_marker set_anchor_loci */
28
29 /**************** Chromosomes ****************/
30
make_new_chrom(name,num)31 bool make_new_chrom(name,num)
32 char *name;
33 int *num;
34 {
35 int n, m;
36
37 if ((n=chromosome->num_maps)==MAX_CHROMOSOMES-1)
38 error("too many chromosomes - can't make any more");
39 if (isa_chrom(name,&m)) return(FALSE);
40
41 strcpy(chromosome->map_list[n]->map_name,name);
42 chromosome->map_list[n]->num_loci=0;
43 chromosome->num_maps+=1;
44 *num=n;
45 return(TRUE);
46 }
47
48
isa_chrom(name,chrom)49 bool isa_chrom(name,chrom)
50 char *name;
51 int *chrom; /* side-effected */
52 {
53 int i;
54
55 *chrom= NO_CHROM;
56 if (xstreq(name,"any")) { *chrom=NO_CHROM; return(TRUE); }
57 for (i=0; i<chromosome->num_maps; i++)
58 if (xstreq(name,chromosome->map_list[i]->map_name)) { *chrom=i; break; }
59 return (*chrom==NO_CHROM ? FALSE:TRUE);
60 }
61
62
get_chrom_frame(chrom,num_loci)63 MAP *get_chrom_frame(chrom,num_loci)
64 int chrom;
65 int *num_loci; /* side-effected, can be 0, or 1, or greater */
66 {
67 if (num_loci!=NULL) *num_loci= chromosome->map_list[chrom]->num_loci;
68 return(chromosome->map_list[chrom]);
69 }
70
71
framework_marker(locus)72 bool framework_marker(locus)
73 int locus;
74 {
75 int j, k, found_in_frame;
76 MAP *frame;
77
78 /* force_haplo_sanity(&locus,FALSE); */
79 if (!assigned(locus)) return(FALSE);
80
81 frame=chromosome->map_list[assignment_chrom(locus)];
82 for (j=0; j<frame->num_loci; j++) {
83 if (locus==frame->locus[j]) return(TRUE);
84 /* if (!check_haplos) continue;
85 for (k=haplo_first[frame->locus[j]]; k!=NO_LOCUS; k=haplo_next[k])
86 if (locus==k) return(TRUE); */
87 }
88 return(FALSE);
89 }
90
91
92 #define FRAME_OTHER_CHROM \
93 "bad framework for %s - %s is assigned to %s"
94 #define FRAME_NO_CHROM \
95 "bad framework - %s is not assigned to a chromosome"
96 #define FRAME_DUPS \
97 "bad framework - one or more loci are repeated in sequence"
98
set_chrom_frame(chrom,new)99 void set_chrom_frame(chrom,new)
100 int chrom;
101 MAP *new; /* warning: side-effected! */
102 /* When this is called, new MUST be equal to get_map_to_bash(chromosome), amd
103 assigned_to(*,chrom) must have be true for all loci in new map. We also
104 assume haplo_sanity is true for old framework, and force it for new one. */
105 {
106 int i, j, found, other;
107 MAP *old;
108
109 old=get_chrom_frame(chrom,NULL);
110
111 /* check for problems: markers on other chroms, haplo_sanity, duplicates */
112 for (j=0; j<new->num_loci; j++) {
113 /* force_haplo_sanity(new->locus+j,TRUE); */
114 if (!assigned(new->locus[j])) {
115 sf(ps,FRAME_NO_CHROM,loc2str(new->locus[j])); error(ps);
116 } else if ((other=assignment_chrom(new->locus[j]))!=chrom) {
117 sf(ps,FRAME_OTHER_CHROM,chrom2str(chrom),loc2str(new->locus[j]),
118 chrom2str(other)); error(ps);
119 }
120 }
121
122 /* unplace markers which WERE on the framework */
123 for (i=0; i<old->num_loci; i++) {
124 found=FALSE;
125 for (j=0; j<new->num_loci; j++)
126 if (old->locus[i]==new->locus[j]) { found=TRUE; break; }
127 if (!found) unplace_this(old->locus[i],NO_CHROM,M_UNKNOWN,FALSE);
128 }
129
130 /* unplace ALL markers which were placed relative to the old framework */
131 for (j=0; j<raw.num_markers; j++)
132 if (assigned_to(j,chrom) && placed_locus(j))
133 unplace_this(j,NO_CHROM,M_UNKNOWN,FALSE);
134
135 /* quasi-place new markers in the new framework on this chrom */
136 for (i=0; i<new->num_loci; i++) {
137 found=FALSE;
138 for (j=0; j<old->num_loci; j++)
139 if (old->locus[i]==new->locus[j]) { found=TRUE; break; }
140 if (!found) unplace_this(new->locus[i],chrom,M_FRAMEWORK,FALSE);
141 }
142
143 /* save the framework */
144 strcpy(new->map_name,chromosome->map_list[chrom]->map_name);
145 overwrite_map_num(chromosome,&new,chrom);
146 chromosome->map_list[chrom]->modified= TRUE;
147 }
148
149
get_chrom_loci(chrom,locus,which_loci,num_loci,num_framework)150 void get_chrom_loci(chrom,locus,which_loci,num_loci,num_framework)
151 int chrom, *locus, which_loci, *num_loci, *num_framework;
152 {
153 int i, j, k, n, primary;
154 bool framework=FALSE, non_frame=FALSE, haplos_anyway=FALSE;
155
156 if (which_loci>=HAPLOS) { haplos_anyway=TRUE; which_loci-=HAPLOS; }
157 if (which_loci>=NON_FRAME) { non_frame=TRUE; which_loci-=NON_FRAME; }
158 if (which_loci>=FRAMEWORK) { framework=TRUE; which_loci-=FRAMEWORK; }
159
160 n=0;
161 if (framework)
162 for (j=0; j<chromosome->map_list[chrom]->num_loci; j++) {
163 i=chromosome->map_list[chrom]->locus[j];
164 if (use_haplotypes && haplos_anyway && haplotyped(i)) {
165 for (k=haplo_first[j]; k!=NO_LOCUS; k=haplo_next[k])
166 locus[n++]=k;
167 } else { /* ignore haplos, and assume chrom frame is sane */
168 locus[n++]= i;
169 }
170 }
171 if (num_framework!=NULL) *num_framework=n;
172
173 if (non_frame)
174 for (i=0; i<raw.num_markers; i++) {
175 if (use_haplotypes && !haplos_anyway && haplotyped(i) &&
176 haplo_first[i]!=i) continue; /* then skip non-primaries */
177 else if (use_haplotypes && haplotyped(i)) primary=haplo_first[i];
178 else primary=i;
179 if (assigned_to(primary,chrom) && !framework_marker(primary))
180 locus[n++]=i;
181 }
182 if (num_loci!=NULL) *num_loci=n; /* the total! */
183 }
184
185
count_chrom_loci(chrom,n_anchor,n_frame,n_total,n_placed,n_unique,n_region,haplos_too,temp)186 void count_chrom_loci(chrom,n_anchor,n_frame,n_total,n_placed,n_unique,
187 n_region,haplos_too,temp)
188 int chrom;
189 int *n_anchor, *n_frame, *n_total, *n_placed, *n_unique, *n_region;
190 bool haplos_too;
191 int *temp; /* at most raw.num_markers long, alloced outside */
192 {
193 int which, i, locus, primary;
194 int frame, total, anchor, placed, unique, region;
195
196 if (use_haplotypes && haplos_too) which=ALL_LOCI+HAPLOS;
197 else which=ALL_LOCI;
198 get_chrom_loci(chrom,temp,which,&total,&frame);
199
200 anchor=placed=unique=region=0;
201 for (i=frame; i<total; i++) { /* Loop over non-frame markers */
202 locus=temp[i];
203 /* if !haplos_too then only primaries will be in the list */
204 if (use_haplotypes && haplotyped(locus)) primary=haplo_first[locus];
205 else primary=locus;
206 if (anchor_locus(primary)) anchor++;
207 if (placed_locus(primary)) {
208 placed++;
209 if (placement_state(primary)==M_UNIQUE) unique++;
210 else if (placement_state(primary)==M_REGION) region++;
211 }
212 }
213 if (n_anchor!=NULL) *n_anchor=anchor;
214 if (n_frame!=NULL) *n_frame= frame;
215 if (n_total!=NULL) *n_total= total;
216 if (n_placed!=NULL) *n_placed=placed;
217 if (n_unique!=NULL) *n_unique=unique;
218 if (n_region!=NULL) *n_region=region;
219 }
220
221
222 /**************** Assignments ****************/
223
assigned(locus)224 bool assigned(locus)
225 int locus;
226 { force_haplo_sanity(&locus,FALSE); return(assignment[locus]->status>0); }
227
assignment_state(locus)228 int assignment_state(locus)
229 int locus;
230 { force_haplo_sanity(&locus,FALSE); return(assignment[locus]->status); }
231
assignment_chrom(locus)232 int assignment_chrom(locus)
233 int locus;
234 {
235 force_haplo_sanity(&locus,FALSE);
236 return(assignment[locus]->status>0 ? assignment[locus]->chromosome:NO_CHROM);
237 }
238
assigned_to(locus,chrom)239 bool assigned_to(locus,chrom)
240 int locus, chrom;
241 {
242 force_haplo_sanity(&locus,FALSE);
243 return(assignment[locus]->status>0 && assignment[locus]->chromosome==chrom);
244 }
245
anchor_locus(locus)246 bool anchor_locus(locus)
247 int locus;
248 { return(assignment_state(locus)==A_ANCHOR); } /* does force_haplo_sanity */
249
250
251 #define ASS_ANCHOR "%s- anchor locus on %s...cannot re-assign\n"
252 #define ASS_REFRAME "%s- framework marker on %s...cannot re-assign to %s\n"
253 #define ASS_UNFRAME "%s- framework marker on %s...cannot un-assign\n"
254 #define ASS_ISFRAME "%s- framework marker on %s...remains attached\n"
255 #define ASS_INSANE \
256 "%s- not the name of its haplotype-group, can't assign or unassign\n"
257
is_assignable(locus,chrom,fix_frames)258 bool is_assignable(locus,chrom,fix_frames)
259 int locus, chrom; /* maybe NO_CHROM */
260 bool fix_frames;
261 {
262 int old;
263
264 /* if (!force_haplo_sanity(&locus,FALSE)) {
265 sf(ps,ASS_INSANE,loc2str(locus)); pr();
266 return(FALSE);
267 } */
268
269 if (!assigned(locus)) return(TRUE);
270 old= assignment_chrom(locus);
271
272 if (anchor_locus(locus) && old!=chrom) {
273 sf(ps,ASS_ANCHOR,loc2str(locus),chrom2str(old)); pr();
274 return(FALSE); /* don't touch assignment */
275 }
276 if (framework_marker(locus) && old!=chrom) {
277 /* includes chrom==NO_CHROM case, eg unassigning */
278 if (!fix_frames) {
279 if (chrom==NO_CHROM)
280 sf(ps,ASS_UNFRAME,loc2str(locus),chrom2str(old));
281 else
282 sf(ps,ASS_REFRAME,loc2str(locus),chrom2str(old),
283 chrom2str(chrom));
284 pr();
285 return(FALSE);
286 } else {
287 /* need to change assignment - lod has disappeared */
288 /* keep old assignment[locus]->chromosome */
289 assignment[locus]->status= A_FRAMEWORK;
290 assignment[locus]->LODscore= NO_LOD;
291 assignment[locus]->theta= NO_THETA;
292 assignment[locus]->linked_to= NO_LOCUS;
293 assignment[locus]->modified= TRUE;
294 /* no need to unplace - it's (still) a framework marker */
295 sf(ps,ASS_ISFRAME,loc2str(locus),chrom2str(old)); pr();
296 return(FALSE); /* ??? */
297 }
298 }
299 return(TRUE);
300 }
301
302
303 #define ASS_NONE "%s- unassigned\n"
304 #define ASS_UNASS "%s- unassigned (previously assigned to chrom %s)\n"
305 #define ASS_UNANCH "%s- unassigned (previously anchor locus on %s)\n"
306 #define ASS_NEWANCH "%s- unassigned (anchor loci on %s have been changed)\n"
307
308 #define ASS_FRAME "%s- framework locus...remains attached to %s\n"
309 #define ASS_ASSIGN "%s- assigned to %s at LOD %4.1lf\n"
310 #define ASS_BORDER "%s- assigned to %s at LOD *%4.1lf*\n"
311 #define ASS_ATTACH "%s- attached to %s\n"
312
313 #define CHG_ASSIGN "%s- assigned to %s at LOD %4.1lf (previously assigned to %s)\n"
314 #define CHG_ATTACH "%s- attached to %s (previously assigned to %s)\n"
315 #define CHG_BORDER "%s- assigned to %s at LOD *%.1lf* (previously assigned to %s)\n"
316
317 /* this will unassign anchors, but not reassign them correctly, and it will
318 certainly not make loci anchors - this is OK for now */
assign_this(locus,state,chrom,lod,theta,linked_locus,msg)319 void assign_this(locus,state,chrom,lod,theta,linked_locus,msg)
320 int locus, state, chrom;
321 real lod, theta;
322 int linked_locus;
323 char *msg; /* pre-empts other message, only for A_PROBLEM as yet */
324 {
325 int old_chrom= (assigned(locus) ? assignment_chrom(locus):NO_CHROM);
326
327 if (state<=0) { /* set to an unassigned state */
328 if (!nullstr(msg)) /* problem state: use this msg */
329 strcpy(ps,msg);
330 else if (anchor_locus(locus))
331 sf(ps,ASS_UNANCH,loc2str(locus),chrom2str(assignment_chrom(locus)));
332 else if (assigned(locus))
333 sf(ps,ASS_UNASS,loc2str(locus),chrom2str(assignment_chrom(locus)));
334 else
335 sf(ps,ASS_NONE,loc2str(locus));
336 pr();
337 unplace_this(locus,NO_CHROM,M_UNKNOWN,FALSE);
338
339 } else { /* assign to a chrom */
340 if (assigned(locus) && assignment_chrom(locus)!=chrom) { /* changed */
341 if (framework_marker(locus)) send(CRASH);
342 if (state==A_ATTACH) /* no lod state */
343 sf(ps,CHG_ATTACH,loc2str(locus),chrom2str(chrom),
344 chrom2str(assignment_chrom(locus)));
345 else if (state==A_FRAMEWORK) send(CRASH);
346 else if (state==A_BORDERLINE)
347 sf(ps,CHG_BORDER,loc2str(locus),chrom2str(chrom),lod,
348 chrom2str(assignment_chrom(locus)));
349 else /* state==A_ASSIGNED */
350 sf(ps,CHG_ASSIGN,loc2str(locus),chrom2str(chrom),lod,
351 chrom2str(assignment_chrom(locus)));
352 unplace_this(locus,NO_CHROM,M_UNKNOWN,FALSE);
353
354 } else { /* assignment has not been changed */
355 if (state==A_ATTACH) /* no lod states */
356 sf(ps,ASS_ATTACH,loc2str(locus),chrom2str(chrom));
357 else if (state==A_FRAMEWORK) /* no lod states */
358 sf(ps,ASS_FRAME,loc2str(locus),chrom2str(chrom));
359 else if (state==A_BORDERLINE)
360 sf(ps,ASS_BORDER,loc2str(locus),chrom2str(chrom),lod);
361 else
362 sf(ps,ASS_ASSIGN,loc2str(locus),chrom2str(chrom),lod);
363 }
364 pr();
365 }
366
367 assignment[locus]->chromosome= chrom;
368 assignment[locus]->status= state;
369 assignment[locus]->LODscore= lod;
370 assignment[locus]->theta= theta;
371 assignment[locus]->linked_to= linked_locus;
372 assignment[locus]->modified= TRUE;
373 }
374
375
unassign_this(locus,state)376 void unassign_this(locus,state)
377 int locus, state;
378 { assign_this(locus,state,NO_CHROM,NO_LOD,NO_THETA,NO_LOCUS,""); }
379
380
attach_this(locus,state,chrom)381 void attach_this(locus,state,chrom)
382 int locus, state;
383 { assign_this(locus,state,chrom,NO_LOD,NO_THETA,NO_LOCUS,""); }
384
385
386 #define ANCHOR_ISFRAME \
387 "%s is a framework marker on %s...cannot re-assign to %s\n"
388 #define ANCHOR_ISANCH \
389 "%s is a framework marker on %s...cannot re-assign to %s\n"
390 #define ANCHOR_ISNOW "%s- anchor locus on %s\n"
391 #define ANCHOR_DUPS "bad framework\none or more loci are repeated in sequence"
392
set_chrom_anchors(chrom,locus,num_loci)393 void set_chrom_anchors(chrom,locus,num_loci)
394 int chrom, *locus, num_loci; /* maybe 0 */
395 {
396 int i, j, old_chrom;
397 bool still_got_it;
398
399 /* check for problems: FW/anchor markers on other chroms,
400 need to assume haplo_sanity */
401 for (j=0; j<num_loci; j++) {
402 old_chrom=(assigned(locus[j]) ? assignment_chrom(locus[j]):NO_CHROM);
403 if (old_chrom!=chrom && framework_marker(locus[j])) {
404 sf(ps,ANCHOR_ISFRAME,loc2str(locus[j]),chrom2str(old_chrom));
405 error(ps);
406 }
407 if (old_chrom!=chrom && anchor_locus(locus[j])) {
408 sf(ps,ANCHOR_ISANCH,loc2str(locus[j]),chrom2str(old_chrom));
409 error(ps);
410 }
411 }
412
413 /* unassign old anchors */
414 for (i=0; i<raw.num_markers; i++)
415 if (assigned_to(i,chrom) && anchor_locus(i)) {
416 still_got_it=FALSE;
417 for (j=0; j<num_loci; j++)
418 if (locus[j]==i) { still_got_it=TRUE; break; }
419 if (!still_got_it) {
420 if (framework_marker(i)) attach_this(i,A_FRAMEWORK,chrom);
421 else unassign_this(i,A_CHANGED);
422 }
423 }
424
425 /* assign new anchors */
426 for (j=0; j<num_loci; j++) {
427 if (assigned(locus[j]) && assignment_chrom(locus[j])!=chrom)
428 unplace_this(locus[j],NO_CHROM,M_UNKNOWN,FALSE);
429 sf(ps,ANCHOR_ISNOW,loc2str(locus[j]),chrom2str(chrom)); pr();
430 assignment[locus[j]]->chromosome= chrom;
431 assignment[locus[j]]->status= A_ANCHOR;
432 assignment[locus[j]]->LODscore= NO_LOD;
433 assignment[locus[j]]->theta= NO_THETA;
434 assignment[locus[j]]->linked_to= NO_LOCUS;
435 assignment[locus[j]]->modified= TRUE;
436 }
437 }
438
439
440 #define DOASS_NOANCHS "no anchor loci have yet been assigned to chromosomes\n"
441 #define DOASS_NOCHROMS "no chromosomes have yet been defined\n"
442
do_assignments(locus,num_loci,lod1,unlinked_lod1,theta1,lod2,unlinked_lod2,theta2,haplo)443 void do_assignments(locus,num_loci,lod1,unlinked_lod1,theta1,
444 lod2,unlinked_lod2,theta2,haplo)
445 int *locus, num_loci; /* is_assignable must have been verified */
446 real lod1, unlinked_lod1, theta1, lod2, unlinked_lod2, theta2;
447 bool haplo;
448 {
449 int i, j, state, num_chroms;
450 bool assigned_any, do_changed_only;
451 int **anchor=NULL, *count=NULL;
452 real lod, unlinked_lod, theta;
453
454 run {
455 if ((num_chroms=chromosome->num_maps)==0) error(DOASS_NOCHROMS);
456 matrix(anchor,num_chroms,raw.num_markers,int);
457 array(count,num_chroms,int); for (i=0; i<num_chroms; i++) count[i]=0;
458 if (!get_anchors(anchor,count,locus,num_loci,haplo))
459 error(DOASS_NOANCHS);
460
461 lod=lod1; unlinked_lod=unlinked_lod1; theta=theta1;
462 assigned_any=TRUE;
463 /* when we start loop with assigned_any=FALSE, we switch lods */
464 do {
465 if (!assigned_any) {
466 lod=lod2; unlinked_lod=unlinked_lod2; theta=theta2;
467 }
468 assigned_any=FALSE;
469 for (i=0; i<num_loci; i++) {
470 if (locus[i]!=NO_LOCUS &&
471 do_assignment(locus[i],lod,unlinked_lod,theta,
472 anchor,count,num_chroms)) {
473 /* msg is printed */
474 locus[i]=NO_LOCUS;
475 assigned_any=TRUE;
476 }
477 }
478 } while (assigned_any || lod!=lod2);
479
480 /* if a locus made it to here, its unlinked */
481 for (i=0; i<num_loci; i++) if (locus[i]!=NO_LOCUS) {
482 state=assignment_state(i);
483 if (state!=A_FRAMEWORK && state!=A_ATTACH)
484 unassign_this(locus[i],A_UNLINKED);
485 else attach_this(locus[i],state,assignment_chrom(locus[i]));
486 }
487 } on_exit {
488 unmatrix(anchor,num_chroms,int);
489 unarray(count,int);
490 }
491 }
492
493
494
495 #define ASS_MULTI "%s- conflicting data (%s LOD %.2lf, %s LOD %.2lf)\n"
496
do_assignment(locus,lodbound,minlodbound,thetabound,anchor,count,num_groups)497 bool do_assignment(locus,lodbound,minlodbound,thetabound,
498 anchor,count,num_groups)
499 int locus;
500 real lodbound, minlodbound, thetabound;
501 int **anchor; /* [num_groups][0..count[this_group]-1] */
502 int *count; /* [num_groups] */
503 int num_groups;
504 {
505 int assigned_locus, j, k, state;
506 int this_locus, pos_locus, this_chrom, pos_chrom, alt_chrom, pos_group;
507 real lod, theta, this_lod, pos_lod, alt_lod, this_theta, pos_theta;
508 bool this_group;
509 char *temp= get_temp_string();
510
511 /* this actually does a bit of i/o (well, one line per locus) by
512 virtue of calling assign_this(), which is gabby */
513
514 /* this has slightly special behavior for loci with A_FRAMEWORK or
515 A_ATTACH, in that it will not unlink them if there is no evidence for
516 assignment (it will try to RELINK them however) THIS NEEDS WORK */
517
518 if (sex_specific) send(CRASH);
519
520 pos_chrom= alt_chrom= NO_CHROM;
521 pos_lod= alt_lod= 0.0;
522
523 for (j=0; j<num_groups; j++) {
524 /* if (do_changed_only && !changed[j]) continue; */
525 this_group=FALSE; this_lod= 0.0;
526 for (k=0; k<count[j]; k++) {
527 assigned_locus= anchor[j][k];
528 get_two_pt(locus,assigned_locus,&lod,&theta);
529 if (lod>=minlodbound && theta<=thetabound) {
530 this_group= TRUE;
531 this_chrom= j;
532 if (lod>this_lod) {
533 this_lod= lod;
534 this_theta= theta;
535 this_locus= assigned_locus;
536 }
537 }
538 }
539 if (this_group) { /* matched one in this group */
540 if (pos_chrom==NO_CHROM ||
541 (pos_chrom==this_chrom && this_lod>pos_lod)) {
542 /* we've matched no other chroms in this or other groups */
543 pos_chrom= this_chrom; pos_locus= assigned_locus; pos_group= j;
544 pos_lod= this_lod; pos_theta= this_theta;
545
546 } else if (this_lod>pos_lod) {
547 /* we've matched another chrom, but this one is best */
548 if (pos_lod>alt_lod) /* if ex-best chr is now second best */
549 { alt_chrom= pos_chrom; alt_lod= pos_lod; }
550 pos_chrom= this_chrom; pos_locus= assigned_locus; pos_group= j;
551 pos_lod= this_lod; pos_theta= this_theta;
552
553 } else if (alt_chrom!=NO_CHROM && this_lod>alt_lod) {
554 /* we've matched another, better, chrom, this is 2nd best */
555 alt_chrom= this_chrom; alt_lod= this_lod;
556 }
557 }
558 }
559
560 if (pos_lod>=lodbound && alt_chrom!=NO_CHROM &&
561 ((state=assignment_state(locus))!=A_FRAMEWORK && state!=A_ATTACH)) {
562 /* really linked, but there is evidence of linkage to other chroms */
563 sf(temp,ASS_MULTI,loc2str(locus),
564 chrom2str(pos_chrom),pos_lod,
565 chrom2str(alt_chrom),alt_lod);
566 assign_this(locus,A_PROBLEM,NO_CHROM,NO_LOD,NO_THETA,NO_LOCUS,temp);
567 return(TRUE);
568
569 } else if (pos_lod>=lodbound) {
570 /* really linked, only to this chrom */
571 assign_this(locus,A_ASSIGNED,pos_chrom,pos_lod,pos_theta,pos_locus,"");
572 anchor[pos_group][(count[pos_group])++]=locus;
573 return(TRUE);
574
575 } else return(FALSE);
576 }
577
578
579
get_anchors(anchor,count,locus,num_loci,haplo)580 bool get_anchors(anchor,count,locus,num_loci,haplo) /* internal use only */
581 int **anchor, *count; /* side-effected if non-null */
582 int *locus, num_loci; /* markers to assign now */
583 bool haplo; /* take only haplo_firsts */
584 {
585 int i, j, state, chrom, found, n=0;
586
587 for (i=0; i<raw.num_markers; i++) if (assigned(i)) {
588 state=assignment_state(i); chrom=assignment_chrom(i);
589 if ((state==A_ANCHOR || state==A_BORDERLINE || state==A_ASSIGNED) &&
590 (!haplo || haplo_first[i]==NO_CHROM || haplo_first[i]==i)) {
591 for (found=FALSE, j=0; j<num_loci; j++)
592 if (locus[j]==i) { found=TRUE; break; }
593 if (!found) { anchor[chrom][(count[chrom])++]=i; n++; }
594 }
595 }
596 return(n);
597 }
598
599
600
601 /**************** Placements ****************/
602
placed_locus(locus)603 bool placed_locus(locus)
604 int locus;
605 { force_haplo_sanity(&locus,FALSE); return(placement[locus]->status>0); }
606
placement_state(locus)607 bool placement_state(locus)
608 int locus;
609 { force_haplo_sanity(&locus,FALSE); return(placement[locus]->status); }
610
611
612 #define PLACE_ISFRAME \
613 " %4d %-9s - framework marker on chromosome %s, can't place\n"
614 #define PLACE_NOTASS \
615 " %4d %-9s - not assigned to a chromosome, can't place\n"
616 #define PLACE_NOTCHR \
617 " %4d %-9s - not assigned to chromosome %s, can't place\n"
618 #define PLACE_INSANE \
619 " %4d %-9s - not the name of its haplotype-group, can't place\n"
620
621 #define PLACE_PROBLEM \
622 " %4d %-9s - no locations allowed, can't place\n"
623 #define PLACE_UNKNOWN \
624 " %4d %-9s - unplaced"
625 #define PLACE_FRAMEWORK \
626 " %4d %-9s - framework marker"
627 #define PLACE_TOOMANY \
628 " %4d %-9s - too many possible locations, can't place\n"
629
630 #define PLACE_OFFEND \
631 " %4d %-9s - placed %soff %send of framework, like%s%.2lf\n"
632 #define PLACE_UNIQUE \
633 " %4d %-9s - placed %sin one interval, like%s%.2lf\n"
634 #define PLACE_ZERO \
635 " %4d %-9s - placed %sat zero distance, like%s%.2lf\n"
636 #define PLACE_REGION \
637 " %4d %-9s - placed %sin %d intervals, like%s%.2lf 2nd%s%.2lf\n"
638 /*234 123456789 - placed *with errors* in 24 intervals, like=-9.24, 2nd=-5.*/
639
is_placeable(locus,chrom)640 bool is_placeable(locus,chrom)
641 int locus, chrom;
642 {
643 int framework, old_chrom, k;
644
645 /* unplace_this() helps to clean up the placement structure, when this
646 is called by place or place_together */
647
648 if (!force_haplo_sanity(&locus,FALSE)) {
649 sf(ps,PLACE_INSANE,locus+1,locname(locus,TRUE));
650 pr(); return(FALSE);
651
652 } else if (framework_marker(locus)) {
653 sf(ps,PLACE_ISFRAME,locus+1,locname(locus,TRUE),
654 chrom2str(assignment_chrom(locus))); pr();
655 /* unplace_this(locus,NO_CHROM,M_UNKNOWN,FALSE); WHY? */
656 return(FALSE);
657
658 } else if (!assigned(locus)) {
659 sf(ps,PLACE_NOTASS,locus+1,locname(locus,TRUE)); pr();
660 /* unplace_this(locus,NO_CHROM,M_UNKNOWN,FALSE); */
661 return(FALSE);
662
663 } else if (chrom!=ANY_CHROM && !assigned_to(locus,chrom)) {
664 /* not used yet */
665 sf(ps,PLACE_NOTCHR,locus+1,locname(locus,TRUE),chrom2str(chrom)); pr();
666 /* unplace_this(locus,NO_CHROM,M_UNKNOWN,FALSE); */
667 return(FALSE);
668
669 } else return(TRUE);
670 }
671
672
place_this(locus,chrom,place,like_thresh,one_err_thresh,net_err_thresh,excluded)673 int place_this(locus,chrom,place,like_thresh,one_err_thresh,net_err_thresh,
674 excluded)
675 int locus, chrom;
676 PLACE **place; /* better be ralative to chrom's fw order */
677 real like_thresh, one_err_thresh, net_err_thresh;
678 bool *excluded; /* used as a temp for npt_exclusions() */
679 {
680 int j, n, num, good;
681 real second_best, support, error_lod;
682 bool zero, off_end, is_single_error;
683 char *sgn, *sgn2, *witherr;
684
685 num= chromosome->map_list[chrom]->num_loci;
686
687 good= npt_exclusions(place,num,like_thresh,one_err_thresh,net_err_thresh,
688 excluded,&zero,&off_end,&error_lod,&is_single_error,
689 &second_best,&support);
690
691 placement[locus]->modified= TRUE;
692 placement[locus]->chromosome=chrom;
693 placement[locus]->threshold= like_thresh;
694 placement[locus]->error_lod= error_lod; /* maybe NO_ERRORS */
695 placement[locus]->single_error= is_single_error;
696
697 n=0;
698 for (j=0; j<=num; j++) if (!excluded[j]) {
699 if (place[j]->like>PLACEMENT_THRESHOLD) {
700 if (n<MAX_STORED_PLACES) {
701 placement[locus]->interval[n]= j;
702 placement[locus]->like_ratio[n]= place[j]->like;
703 placement[locus]->distance[n]= place[j]->dist;
704 placement[locus]->num_intervals= ++n;
705 } else { /* we are full */
706 placement[locus]->num_intervals= 0;
707 placement[locus]->threshold= 0.0;
708 placement[locus]->status= M_PROBLEM;
709 sf(ps,PLACE_TOOMANY,locus+1,locname(locus,TRUE)); pr();
710 return(0);
711 }
712 }
713 }
714
715 sgn=ptr_to("=");
716 if (support==NO_LIKE) { sgn=ptr_to("<"); support=-5.0; }
717 witherr=ptr_to("");
718 if (error_lod!=NO_ERRORS) witherr=ptr_to("*with errors* ");
719
720 if (off_end) {
721 placement[locus]->status= (error_lod!=NO_ERRORS ? M_ERROR:M_OFFEND);
722 sf(ps,PLACE_OFFEND,locus+1,locname(locus,TRUE),witherr,
723 (off_end==2 ? "*either* ":""),sgn,support);
724 pr();
725 /* print the errors? */
726
727 } else if (good==1) {
728 if (zero) {
729 placement[locus]->status=(error_lod!=NO_ERRORS ? M_ERROR:M_ZERO);
730 sf(ps,PLACE_ZERO,locus+1,locname(locus,TRUE),witherr,
731 sgn,support); pr();
732
733 } else {
734 placement[locus]->status=(error_lod!=NO_ERRORS ? M_ERROR:M_UNIQUE);
735 sf(ps,PLACE_UNIQUE,locus+1,locname(locus,TRUE),witherr,
736 sgn,support); pr();
737 }
738
739 } else { /* good>1 */
740 sgn2=ptr_to("=");
741 if (second_best==NO_LIKE) { sgn2=ptr_to("<"); second_best=-5.0; }
742 placement[locus]->status= (error_lod!=NO_ERRORS ? M_ERROR:M_REGION);
743 sf(ps,PLACE_REGION,locus+1,locname(locus,TRUE),witherr,good,
744 sgn,support,sgn2,second_best);
745 pr();
746 /* print possible errors? */
747 }
748
749 return(good);
750 }
751
752
unplace_this(locus,chrom,status,verbose)753 void unplace_this(locus,chrom,status,verbose)
754 int locus, chrom, status;
755 bool verbose;
756 {
757 placement[locus]->modified= TRUE;
758 placement[locus]->num_intervals= 0;
759 placement[locus]->threshold= 0.0;
760 placement[locus]->error_lod= NO_ERRORS;
761 placement[locus]->single_error= TRUE;
762 placement[locus]->chromosome= chrom;
763 placement[locus]->status= status;
764 if (verbose) {
765 if (status==M_PROBLEM)
766 { sf(ps,PLACE_PROBLEM,locus+1,locname(locus,TRUE)); pr(); }
767 else if (status==M_FRAMEWORK)
768 { sf(ps,PLACE_FRAMEWORK,locus+1,locname(locus,TRUE)); pr(); }
769 else
770 { sf(ps,PLACE_UNKNOWN,locus+1,locname(locus,TRUE)); pr(); }
771 }
772 }
773
774
775 /* These have no error traps - only use them if valid data are stored! */
best_placement(locus)776 int best_placement(locus)
777 int locus;
778 {
779 int i;
780
781 if (placement[locus]->num_intervals==0) send(CRASH);
782 for (i=0; i<placement[locus]->num_intervals; i++)
783 if (placement[locus]->like_ratio[i]==0.0) break;
784 if (i==placement[locus]->num_intervals) send(CRASH);
785 return(i);
786 }
787
788
second_best_placement(locus,like)789 int second_best_placement(locus,like) /* only ok for M_REGION */
790 int locus;
791 real *like;
792 {
793 int i, j, pos; /* need to add many error traps */
794 real best;
795
796 for (i=0; i<placement[locus]->num_intervals; i++)
797 if (placement[locus]->like_ratio[i]==0.0) break;
798 best= -VERY_BIG;
799 for (j=0; j<placement[locus]->num_intervals; j++)
800 if (j!=i && placement[locus]->like_ratio[j]>best)
801 { best=placement[locus]->like_ratio[j]; pos=j; }
802 if (like!=NULL) *like=best;
803 if (best== -VERY_BIG) return(-1);
804 return(j);
805 }
806
807
808
809 /************ Load/Save/Reset ************/
810
811
bash_mapping_data(changed,num_changed)812 void bash_mapping_data(changed,num_changed)
813 int *changed, num_changed; /* changed markers */
814 {
815 int i, j, n;
816 MAP *map;
817 bool bash[MAX_CHROMOSOMES];
818 for (j=0; j<chromosome->num_maps; j++) bash[j]=FALSE;
819
820 for (i=0; i<num_changed; i++) {
821 n=changed[i];
822 sf(ps,"%-8s - unassigned and unplaced (changed)\n",
823 locname(n,FALSE)); pr();
824 }
825 for (i=0; i<num_changed; i++) {
826 n=changed[i];
827 if (assignment[n]->status==A_ANCHOR) {
828 sf(ps,"warning: %s WAS an anchor locus for chromosome %s\n",
829 locname(n,FALSE),chrom2str(assignment[n]->chromosome)); pr();
830 }
831 }
832 for (i=0; i<num_changed; i++) {
833 n=changed[i];
834 if (assignment[n]->status!=A_UNKNOWN)
835 assignment[n]->status= A_CHANGED;
836 assignment[n]->chromosome= NO_CHROM;
837 assignment[n]->linked_to= NO_LOCUS;
838 assignment[n]->LODscore= NO_LOD;
839 assignment[n]->theta= NO_THETA;
840 assignment[n]->modified= FALSE;
841
842 if (placement[n]->status==M_FRAMEWORK)
843 bash[assignment[n]->chromosome]=TRUE;
844 placement[n]->status= M_UNKNOWN;
845 placement[n]->num_intervals= 0;
846 placement[n]->threshold= 0.0;
847 placement[n]->error_lod= NO_ERRORS;
848 placement[n]->single_error= TRUE;
849 placement[n]->chromosome= NO_CHROM;
850 placement[n]->modified= FALSE;
851 }
852
853 for (j=0; j<chromosome->num_maps; j++)
854 if (bash[j] && chromosome->map_list[j]->num_loci>0) {
855 sf("chromosome %s framework cleared, all loci unplaced\n",
856 chrom2str(j)); pr();
857 map=get_map_to_bash(chromosome);
858 clean_map(map); /* num_loci -> 0 */
859 set_chrom_frame(j,map);
860 }
861 }
862
863
allocate_mapping_data(num_markers)864 void allocate_mapping_data(num_markers)
865 int num_markers;
866 {
867 int locus;
868
869 chromosome=
870 allocate_map_list(MAX_CHROMOSOMES,MAX_CHROM_LOCI,UNSORTED,NULL);
871 parray(assignment,num_markers,ASSIGNMENT);
872 parray(placement, num_markers,PLACEMENT);
873
874 for (locus=0; locus<num_markers; locus++) {
875 assignment[locus]->status= A_UNKNOWN;
876 assignment[locus]->chromosome=NO_CHROM;
877 assignment[locus]->linked_to= NO_LOCUS;
878 assignment[locus]->LODscore= NO_LOD;
879 assignment[locus]->theta= NO_THETA;
880 assignment[locus]->modified= FALSE;
881
882 placement[locus]->status= M_UNKNOWN;
883 placement[locus]->num_intervals= 0;
884 placement[locus]->threshold= 0.0;
885 placement[locus]->error_lod= NO_ERRORS;
886 placement[locus]->single_error= TRUE;
887 placement[locus]->chromosome= NO_CHROM;
888 placement[locus]->modified= FALSE;
889 }
890 }
891
892
free_mapping_data(num_markers)893 void free_mapping_data(num_markers)
894 int num_markers;
895 {
896 free_map_list(chromosome);
897 unparray(assignment,num_markers,ASSIGNMENT);
898 unparray(placement, num_markers,PLACEMENT);
899 }
900
901
write_mapping_data(fp)902 void write_mapping_data(fp)
903 FILE *fp;
904 {
905 int locus, i, j;
906
907 sf(ps,"*Chromosomes: %d\n", chromosome->num_maps); fpr(fp);
908 for (i=0; i < chromosome->num_maps; i++) {
909 write_map(fp, chromosome->map_list[i]);
910 }
911
912 fprint(fp,WRS("*Assignments and Placements:\n"));
913 for (locus=0; locus< raw.num_markers; locus++) {
914 sf(ps,"*%-8s %2d",raw.locus_name[locus],assignment[locus]->status);
915 fpr(fp);
916 if (assignment[locus]->status==M_UNKNOWN) { fnl(fp); continue; }
917
918 sf(ps," %d %d %lf %lf | %d %lf %lf %d %d \n",
919 assignment[locus]->chromosome, assignment[locus]->linked_to,
920 assignment[locus]->LODscore, assignment[locus]->theta,
921 placement[locus]->status, placement[locus]->threshold,
922 placement[locus]->error_lod, placement[locus]->single_error,
923 placement[locus]->num_intervals); fpr(fp);
924
925 if (placement[locus]->num_intervals==0) continue;
926
927 for (j=0; j < placement[locus]->num_intervals; j++) {
928 sf(ps," %d %lf %lf",
929 placement[locus]->interval[j], placement[locus]->like_ratio[j],
930 placement[locus]->distance[j]); fpr(fp);
931 }
932 fnl(fp);
933 }
934 }
935
936
read_mapping_data(fp)937 void read_mapping_data(fp)
938 FILE *fp;
939 {
940 int locus, num, chrom_num, i, j, num_chroms;
941 real rnum, rnum2;
942 char word[TOKLEN+1], temp_locus_name[NAME_LEN+2];
943 MAP *map;
944
945 /* chromosomes */
946 fgetln_(fp);
947 stoken(&ln,sREQUIRED,word);
948 if (!streq(word,"*Chromosomes:") || !itoken(&ln,iREQUIRED,&num_chroms)) {
949 baddata("error finding *Chromosomes:");
950 }
951 for (i=0; i < num_chroms; i++) {
952 map= get_map_to_bash(chromosome);
953 read_map(fp,map);
954 insert_map_into_list(chromosome,&map);
955 }
956 if (chromosome->num_maps != num_chroms) {
957 baddata("listed number of chromosomes and actual number do not agree");
958 }
959
960 fgetln_(fp);
961 if (!streq(ln,"*Assignments and Placements:"))
962 baddata("error finding *Assignments and Placements:");
963 for (locus=0; locus < raw.num_markers; locus++) {
964 getdataln(fp);
965
966 if (!nstoken(&ln,sREQUIRED,temp_locus_name,NAME_LEN+1) ||
967 temp_locus_name[0]!='*' || len(temp_locus_name)<2)
968 baddata("expected *name");
969 else if (!streq(raw.locus_name[locus],&temp_locus_name[1]))
970 baddata("locus names don't match");
971
972 /* assignment info */
973 itoken(&ln,iREQUIRED,&num);
974 assignment[locus]->status=num;
975 if (num==A_UNKNOWN) continue; /* next locus */
976
977 if (sscanf(ln,"%d %d %lf %lf %s %d %lf %lf %d %d",
978 &assignment[locus]->chromosome,
979 &assignment[locus]->linked_to,
980 &assignment[locus]->LODscore,
981 &assignment[locus]->theta,
982 word,
983 &placement[locus]->status,
984 &placement[locus]->threshold,
985 &placement[locus]->error_lod,
986 &placement[locus]->single_error,
987 &placement[locus]->num_intervals)!=10 || !streq(word,"|"))
988 baddata("unable to parse assignment/placement line");
989
990 placement[locus]->chromosome= assignment[locus]->chromosome;
991 if (placement[locus]->num_intervals==0) continue; /* next locus */
992
993 getdataln(fp); /* get next line */
994 for (j=0; j < placement[locus]->num_intervals; j++) {
995 itoken(&ln,iREQUIRED,&num);
996 placement[locus]->interval[j]=num;
997 rtoken(&ln,rREQUIRED,&rnum);
998 placement[locus]->like_ratio[j]=rnum;
999 rtoken(&ln,rREQUIRED,&rnum);
1000 placement[locus]->distance[j]=rnum;
1001 }
1002 }
1003 }
1004