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_SHELL
16 #define INC_MISC
17 #include "mapm.h"
18 
19 /* external proccedures WHY WHY WHY FIX FIX FIX */
20 void try_marker();
21 
22 /* local */
23 void maybe_print_together();
24 
25 #define ASS_ALREADY "%s- already assigned to %s at LOD %4.1lf...not changing\n"
26 
27 
28 /**************** COMMANDS ****************/
29 
30 #define CANT_MAKE "warning: can't make chromosome '%s'... %s\n"
31 
make_chromosome()32 command make_chromosome()
33 {
34     char name[TOKLEN+1];
35     int i, num;
36 
37     mapm_ready(ANY_DATA,0,0,NULL);
38 
39     if (!nullstr(args)) {
40 	while (stoken(&args,sREQUIRED,name)) {
41 	    if (!valid_name(name))
42 	      { sf(ps,CANT_MAKE,name,"illegal name"); pr(); }
43 	    else if (!valid_new_name(name))
44 	      { sf(ps,CANT_MAKE,name,"name is already in use"); pr(); }
45 	    else if (!make_new_chrom(name,&num))
46 	      { sf(ps,CANT_MAKE,name,"chromosome already exists"); pr(); }
47 	}
48     }
49     print("chromosomes defined: ");
50     if (num_chromosomes==0) print("none");
51     else for (i=0; i<num_chromosomes; i++)
52       { print(chrom2str(i)); print(" "); }
53     nl();
54 }
55 
56 
set_anchors()57 command set_anchors()
58 {
59     int i, *locus=NULL, num_loci, chrom;
60 
61     mapm_ready(ANY_DATA,MAYBE_SEQ,LIST_SEQ,&num_loci);
62     chrom=get_chrom_arg(FALSE);
63     nomore_args(num_args);
64 
65     run {
66 	if (num_loci>0)	{
67 	    alloc_list_of_all_loci(seq,&locus,&num_loci);
68 	    for (i=0; i<num_loci; i++)
69 	      if (!is_assignable(locus[i],chrom,FALSE))
70 		abort_command(); /* prints msg - is this a sufficient test? */
71 	    set_chrom_anchors(chrom,locus,num_loci);
72 	    sf(ps,"chromosome %s anchor(s): ",chrom2str(chrom)); pr();
73 	    for (i=0; i<raw.num_markers; i++) /* requires haplo sanity */
74 	      if (assigned_to(i,chrom) && anchor_locus(i))
75 		{ print(locname(i,TRUE)); print(" "); }
76 	    nl();
77 	} else {
78 	    set_chrom_anchors(chrom,locus,0);
79 	    sf(ps,"chromosome %s now has no anchors\n",chrom2str(chrom)); pr();
80 	}
81     } on_exit {
82 	unarray(locus,int);
83 	relay_messages;
84     }
85 }
86 
87 
88 #define CHROM_SETTING "setting framework for chromosome %s..."
89 #define CHROM_FRAME_EXISTS \
90   "chromosome %s framework already exists, changing it..."
91 #define CHROM_NOFRAME "chromosome %s framework is %sempty..."
92 
93 #define CHROM_FRAME "%s framework:\n"
94 #define CHROM_MARKS "%s Markers:\n"
95 
set_framework()96 command set_framework()
97 {
98     MAP *map, *old;
99     char title[TOKLEN+1];
100     int i, chrom, num_loci;
101 
102     mapm_ready(ANY_DATA,MAYBE_SEQ,ONE_ORDER,&num_loci);
103     chrom=get_chrom_arg(FALSE);
104     nomore_args(num_args);
105     if (num_loci>MAX_CHROM_LOCI)
106       error("too many loci in the sequence for a chromosome framework");
107 
108     old=get_chrom_frame(chrom,NULL);
109     map=get_map_to_bash(chromosome);
110     if (num_loci==0) {
111 	sf(ps,CHROM_NOFRAME,chrom2str(chrom),(old->num_loci>0 ? "now ":""));
112 	pr(); nl();
113 	clean_map(map);
114 	set_chrom_frame(chrom,map);
115 	return;
116     }
117     run {
118 	get_one_order(seq,map);
119 	if (old->num_loci>0)
120 	  { sf(ps,CHROM_FRAME_EXISTS,chrom2str(chrom)); pr(); nl(); }
121 	else { sf(ps,CHROM_SETTING,chrom2str(chrom)); pr(); nl(); }
122 
123 	init_rec_fracs(map);
124 	converge_to_map(map);
125 	set_chrom_frame(chrom,map);
126 
127 	print(MAP_DIVIDER);
128 	sf(title,CHROM_FRAME,chrom2str(chrom));
129 	print_long_map(map,title);
130 	print(MAP_DIVIDER);
131 
132     } on_exit { relay_messages; }
133 }
134 
135 
136 #define CHROMS_TITLE \
137 " Chromosome:  #Total  #Frame  #Anchors  #Placed  #Unique  #Region\n"
138 /*2345678.......234.....234......234.......234......234......234*/
139 #define CHROMS_FORMAT \
140 "   %-8s    %4d    %4d     %4d      %4d     %4d     %4d\n"
141 
list_chroms()142 command list_chroms()
143 {
144     int frame, total, anchor, placed, unique, region, i, *loci=NULL;
145     int sum_frame, sum_total, sum_anchor, sum_placed, sum_unique, sum_region;
146 
147     mapm_ready(ANY_DATA,0,0,NULL);
148     nomore_args(0);
149     if (num_chromosomes==0) error("no chromosomes presently defined\n");
150 
151     array(loci,raw.num_markers,int);
152     sum_frame=sum_total=sum_anchor=sum_placed=sum_unique=sum_region= 0;
153     nl(); print(CHROMS_TITLE);
154 
155     for (i=0; i<chromosome->num_maps; i++) {
156 	count_chrom_loci(i,&anchor,&frame,&total,&placed,&unique,&region,
157 			 TRUE,loci);
158 	sf(ps,CHROMS_FORMAT,chrom2str(i),total,frame,anchor,placed,
159 	   unique,region); pr();
160 	sum_frame+=frame; sum_total+=total; sum_anchor+=anchor;
161 	sum_placed+=placed; sum_unique+=unique; sum_region+=region;
162     }
163     sf(ps,CHROMS_FORMAT,"Total:",sum_total,sum_frame,sum_anchor,
164        sum_placed,sum_unique,sum_region); pr();
165     unarray(loci,int);
166 }
167 
168 
list_assignments()169 command list_assignments()
170 {
171     int chrom, i;
172 
173     mapm_ready(ANY_DATA,0,0,NULL);
174     nomore_args(0);
175     if (num_chromosomes==0) error("no chromosomes presently defined\n");
176     print("Chromosome assignments of all loci:\n"); nl();
177 
178     for (chrom=0; chrom<chromosome->num_maps; chrom++) {
179 	sf(ps,"%s= ",chrom2str(chrom)); pr();
180 	for (i=0; i<raw.num_markers; i++) if (assigned_to(i,chrom))
181 	  { print(rag(loc2str(i))); print(" "); }
182 	nl();
183 	print("-------\n");
184     }
185     print("unassign= ");
186     for (i=0; i<raw.num_markers; i++) if (!assigned(i))
187       { print(rag(loc2str(i))); print(" "); }
188     nl();
189 }
190 
191 
list_mapping()192 command list_mapping()
193 {
194     int source, num_loci, *locus=NULL;
195 
196     mapm_ready(ANY_DATA,MAYBE_SEQ,UNCRUNCHED_LIST,&num_loci);
197     run {
198 	if (!nullstr(args)) {
199 	    parse_locus_args(&locus,&num_loci); /* error if fails */
200 	    if (num_loci==0) error("no loci in arguments\n");
201 	    source=IN_ARGS;
202 	} else {
203 	    if (!alloc_list_of_all_loci(seq,&locus,&num_loci))
204 	      error(NEED_SEQ_OR_ARGS);
205 	    source=IN_SEQ;
206 	}
207 	crunch_locus_list(locus,&num_loci,CRUNCH_WARNINGS,ANY_CHROMS,source);
208 	nl();
209 	hold(more_mode) print_mapping_summary(locus,num_loci,use_haplotypes);
210     } on_exit {
211 	unarray(locus,int);
212 	relay_messages;
213     }
214 }
215 
216 
assign()217 command assign()
218 {
219     int i, n_loci, *locus=NULL;
220     real theta, lod, min_lod, unlinked_lod;
221 
222     mapm_ready(ANY_DATA,1,UNCRUNCHED_LIST,&n_loci);
223 
224     if (!rtoken(&args,default_lod,&lod) || !rrange(&lod,0.0,1000.0))
225       error("Bad value for LOD score bound");
226     if (!rtoken(&args,default_theta,&theta) || !input_dist(&theta))
227       error("Bad value for theta bound");
228     if (!rtoken(&args,lod,&unlinked_lod) || !rrange(&unlinked_lod,0.0,lod))
229       error("Bad value for maximum unlinked lod bound");
230     if (!rtoken(&args,lod,&min_lod) || !rrange(&min_lod,0.0,lod))
231       error("Bad value for marginal LOD bound");
232     nomore_args(0);
233 
234     run {
235 	alloc_list_of_all_loci(seq,&locus,&n_loci);
236 	crunch_locus_list(locus,&n_loci,CRUNCH_WARNINGS,ANY_CHROMS,IN_SEQ);
237 	for (i=0; i<n_loci; i++)
238 	  if (!is_assignable(locus[i],ANY_CHROM,TRUE)) locus[i]=NO_LOCUS;
239 	do_assignments(locus,n_loci,lod,unlinked_lod,theta,
240 		       min_lod,min_lod,theta,FALSE);  /* FIX */
241 
242     } on_exit {
243 	unarray(locus, int);
244 	relay_messages;
245     }
246 }
247 
248 
attach()249 command attach()
250 {
251     int total_loci, i, chrom, n_loci, *locus=NULL;
252 
253     mapm_ready(ANY_DATA,1,UNCRUNCHED_LIST,&n_loci);
254     chrom=get_chrom_arg(FALSE);
255     nomore_args(num_args);
256 
257     run {
258 	alloc_list_of_all_loci(seq,&locus,&n_loci);
259 	crunch_locus_list(locus,&n_loci,CRUNCH_WARNINGS,ANY_CHROMS,IN_SEQ);
260 	for (i=0; i<n_loci; i++)
261 	  if (is_assignable(locus[i],ANY_CHROM,TRUE)) {
262 	      if (assigned_to(locus[i],chrom) &&
263 		  (assignment_state(locus[i])==A_ASSIGNED ||
264 		   assignment_state(locus[i])==A_BORDERLINE))
265 		{ sf(ps,ASS_ALREADY,loc2str(locus[i]),
266 		     chrom2str(assignment_chrom(locus[i])),
267 		     assignment_lod(locus[i])); pr(); continue; }
268 	      assign_this(locus[i],A_ATTACH,chrom,NO_LOD,NO_THETA,NO_LOCUS,"");
269 	  }
270 	print("ok\n");
271 
272     } on_exit {
273 	unarray(locus, int);
274 	relay_messages;
275     }
276 }
277 
278 
unassign()279 command unassign()
280 {
281     int n_loci, i, j, k, *locus=NULL;
282 
283     mapm_ready(ANY_DATA,1,UNCRUNCHED_LIST,&n_loci);
284     nomore_args(0);
285 
286     run {
287 	alloc_list_of_all_loci(seq,&locus,&n_loci);
288 	crunch_locus_list(locus,&n_loci,CRUNCH_WARNINGS,ANY_CHROMS,IN_SEQ);
289 	for (i=0; i<n_loci; i++) {
290 	    if (is_assignable(locus[i],ANY_CHROM,TRUE))
291 	      assign_this(locus[i],A_UNKNOWN,NO_CHROM,NO_LOD,
292 			  NO_THETA,NO_LOCUS,"");
293 	}
294     } on_exit {
295 	unarray(locus,int);
296 	relay_messages;
297     }
298 }
299 
300 
301 #define PLACE_HEADER  "Placing markers at log-likelihood threshold %.2lf...\n"
302 #define PLACE_SOME    "%d marker%s to place on chromosome %s...\n"
303 #define PLACE_NOFRAME "chromosome has no framework order - no markers placed\n"
304 #define PLACE_NONE    "unable to place any markers in the sequence"
305 #define NONE_OK "no orders allowed by three-point analysis, not placed\n"
306 #define NPT_WINDOW 5
place()307 command place()
308 {
309     int  chrom, i, j, left, right;
310     int  *locus=NULL, n_loci, *chrom_locus=NULL, n_to_place, n_allowed;
311     int  *chrom_all=NULL, n_chrom, n_frame, n_to_punt;
312     real npt_thresh, diff;
313     bool got_any, ok;
314     PLACE **placements=NULL;
315     PLACEME **unplaced=NULL;
316     MAP *temp=NULL, *frame; /* frame is NOT malloced */
317 
318     mapm_ready(ANY_DATA,1,LIST_SEQ,&n_loci);
319     if (!rtoken(&args,2.0,&npt_thresh) ||
320 	!rrange(&npt_thresh,0.0,-1.0 * PLACEMENT_THRESHOLD))
321       error("Bad value for multipoint likelihood threshold");
322 
323     run {
324 	alloc_list_of_all_loci(seq,&locus,&n_loci);
325 	array(chrom_locus,raw.num_markers,int);
326 	array(chrom_all,raw.num_markers,int);
327 	parray(placements,MAX_CHROM_LOCI+1,PLACE);
328 	parray(unplaced,n_loci,PLACEME);
329 	for (i=0; i<n_loci; i++) {
330 	    array(unplaced[i]->excluded,MAX_CHROM_LOCI+1,bool);
331 	    unplaced[i]->best_map=allocate_map(MAX_CHROM_LOCI+1);
332 	}
333 	temp=allocate_map(MAX_CHROM_LOCI+1);
334 
335 	sf(ps,PLACE_HEADER,npt_thresh); pr();
336 	for (i=0; i<n_loci; i++) /* is_placable may print a msg & unplace */
337 	  if (!is_placeable(locus[i],ANY_CHROM)) locus[i]=NO_LOCUS;
338 
339 	got_any= FALSE;
340 	for (chrom=0; chrom<chromosome->num_maps; chrom++) {
341 	    /* chrom_locus[], n_to_place is all loci in seq on this chrom */
342 	    n_to_place=0;
343 	    for (i=0; i<n_loci; i++) if (locus[i]!=NO_LOCUS)
344 	      if (assigned_to(locus[i],chrom) && is_placeable(locus[i],chrom))
345 		{ chrom_locus[n_to_place++]=locus[i]; locus[i]=NO_LOCUS; }
346 	    if (n_to_place==0) continue; /* next chrom */
347 
348 	    frame= get_chrom_frame(chrom,&n_frame);
349 	    /* chrom_all has the framework first, then chrom_locus loci */
350 	    get_chrom_loci(chrom,chrom_all,ALL_LOCI,&n_chrom,NULL);
351 	    sort_loci(chrom_all,n_chrom);
352 
353 	    /* if (!got_any) nl(); */
354 	    print(MAP_DIVIDER);
355 	    sf(ps,PLACE_SOME,n_to_place,maybe_s(n_to_place),chrom2str(chrom));
356 	    pr(); nl();
357 	    if (n_frame<2) { sf(ps,PLACE_NOFRAME); pr(); nl(); continue; }
358 	    got_any=TRUE; /* yes, do this here */
359 	    /* if (use_haplotypes)
360 	       { print_haplo_summary(chrom_all,n_chrom); nl(); } */
361 	    print_long_map(frame,"Framework Map:"); nl();
362 
363 	    if (use_three_pt)
364 	      setup_3pt_data(chrom_all,n_chrom,-three_pt_threshold);
365 
366 	    n_to_punt=0;
367 	    print("Placing Markers:\n");
368 	    for (i=0; i<n_to_place; i++) {
369 		unplaced[i]->locus=chrom_locus[i];
370 		ok=TRUE;
371 
372 		if (use_three_pt) {
373 		    /* three_pt_exclusions sets excluded[x] to FALSE first */
374 		    n_allowed=three_pt_exclusions(frame->locus,frame->num_loci,
375 						  unplaced[i]->locus,
376 						  unplaced[i]->excluded);
377 		    find_window(frame->locus,frame->num_loci,
378 				unplaced[i]->locus,unplaced[i]->excluded,
379 				NPT_WINDOW,&left,&right);
380 		} else { /* no three-pt -> all orders are OK */
381 		    n_allowed=n_frame+1;
382 		    left=0; right=n_frame; /* window= all intervals */
383 		}
384 
385 		if (n_allowed==0) { /* (un)place_this() does all of the i/o */
386 		    unplace_this(unplaced[i]->locus,chrom,M_PROBLEM,TRUE);
387 		    unplaced[i]->locus=NO_LOCUS; n_to_punt++;
388 
389 		} else {
390 		    place_locus(frame,unplaced[i]->locus,left,right,
391 				unplaced[i]->excluded,placements,
392 				&unplaced[i]->best_pos,unplaced[i]->best_map,
393 				temp);
394 		    place_this(unplaced[i]->locus,chrom,placements,-npt_thresh,
395 			       10000.0,error_net_thresh,unplaced[i]->excluded);
396 		    /* place_this() calls npt_exclusions() on placements */
397 		}
398 	    }
399 
400 	    nl();
401 	    if (n_to_place-n_to_punt==0) print("No Valid Placements\n");
402 	    else {
403 		print("Placements:\n");
404 		new_print_placements(frame,unplaced,n_to_place);
405 		for (i=0; i<n_to_place; i++)
406 		  if (print_all_maps && unplaced[i]->locus!=NO_LOCUS &&
407 		        placed_locus(unplaced[i]->locus)) {
408 		      print(SUB_DIVIDER);
409 		      sf(ps,"Best placement of %s:",
410 			 rag(loc2str(unplaced[i]->locus)));
411 		      print_special_map(unplaced[i]->best_map,ps,
412 					n_frame,frame->locus);
413 		  }
414 	    }
415 
416 	} /* next chrom */
417 	if (got_any) print(MAP_DIVIDER);
418 	else error(PLACE_NONE);
419 
420     } on_exit {
421 	unarray(locus,int);
422 	unparray(placements,MAX_CHROM_LOCI+1,real);
423 	unarray(chrom_locus,int);
424 	unarray(chrom_all,int);
425 	free_map(temp);
426 	for (i=0; i<n_loci; i++) {
427 	    free_map(unplaced[i]->best_map);
428 	    unarray(unplaced[i]->excluded,bool);
429 	}
430 	unparray(unplaced,n_loci,PLACEME);
431 	relay_messages;
432     }
433 }
434 
435 
show_chrom()436 command show_chrom()
437 {
438     int chrom, i, j;
439     bool found_in_frame, found;
440     int *marker=NULL, num_markers, **placement_state=NULL;
441     char name[TOKLEN+1], title[TOKLEN+1];
442     MAP *map=NULL;
443 
444     mapm_ready(ANY_DATA,0,0,NULL);
445     chrom=get_chrom_arg(FALSE);
446     nomore_args(num_args);
447 
448     run {
449 	array(marker,raw.num_markers,int); /* non-frame markers */
450 	get_chrom_loci(chrom,marker,NON_FRAME,&num_markers,NULL);
451 	matrix(placement_state,num_markers,
452 	       chromosome->map_list[chrom]->num_loci+1,int);
453 
454 	nl();
455 	print(MAP_DIVIDER);
456 	sf(title,CHROM_FRAME,chrom2str(chrom));
457 	print_long_map(chromosome->map_list[chrom],title);
458 	print(MAP_DIVIDER);
459 
460 	sf(ps,CHROM_MARKS,chrom2str(chrom)); pr(); nl();
461 	get_chrom_loci(chrom,marker,ALL_LOCI,&num_markers,NULL);
462 	print_locus_summary(marker,num_markers,TRUE); /* change to FALSE? */
463 	if (use_haplotypes) { nl(); print_haplo_summary(marker,num_markers); }
464 	print(MAP_DIVIDER);
465 
466 /*	get_chrom_loci(chrom,marker,&num_markers,...);
467 	print_3pt_placements(chromosome->map_list[chrom]->locus,
468 			     chromosome->map_list[chrom]->num_loci,
469 			     marker,num_markers,placement_state);
470     	print(MAP_DIVIDER);  */
471 
472     } on_exit {
473 	unarray(marker,int);
474 	relay_messages;
475     }
476 }
477 
478 
479 #define PLACE_AT \
480 "Placing markers at log-likelihood threshold %.1lf:\n"
481 
place_together()482 command place_together()
483 {
484     int  chrom, i, j, left, right;
485     int  *locus=NULL, n_loci, *chrom_locus=NULL, n_to_place, n_allowed;
486     int  *chrom_all=NULL, n_chrom, n_frame, n_to_punt, n_unplaced, num, prev;
487     real npt_thresh, diff;
488     bool got_any, ok;
489     PLACEME **unplaced=NULL;
490     MAP *order=NULL, *frame; /* frame is NOT malloced */
491 
492     mapm_ready(ANY_DATA,1,LIST_SEQ,&n_loci);
493     nomore_args(0);
494     if (npt_threshold==npt_first_threshold) /* globals */
495       sf(ps,"Placement Threshold %.2lf, Npt-Window %d\n",
496 	 npt_threshold,npt_window);
497     else
498       sf(ps,"Placement Threshold-1 %.2lf, Threshold-2 %.2lf, Npt-Window %d\n",
499 	 npt_first_threshold,npt_threshold,npt_window);
500     pr();
501 
502     run {
503 	alloc_list_of_all_loci(seq,&locus,&n_loci);
504 	array(chrom_locus,raw.num_markers,int);
505 	array(chrom_all,raw.num_markers,int);
506 	parray(unplaced,n_loci,PLACEME);
507 	for (i=0; i<n_loci; i++) {
508 	    array(unplaced[i]->excluded,MAX_CHROM_LOCI+1,bool);
509 	    unplaced[i]->best_map=allocate_map(MAX_CHROM_LOCI+1);
510 	}
511 	order=allocate_map(MAX_CHROM_LOCI+1);
512 
513 	sf(ps,PLACE_HEADER,npt_thresh); pr();
514 	for (i=0; i<n_loci; i++) /* is_placable may print a msg & unplace */
515 	  if (!is_placeable(locus[i],ANY_CHROM)) locus[i]=NO_LOCUS;
516 
517 	got_any= FALSE;
518 	for (chrom=0; chrom<chromosome->num_maps; chrom++) {
519 	    /* chrom_locus[], n_to_place is all loci in seq on this chrom */
520 	    n_to_place=0;
521 	    for (i=0; i<n_loci; i++) if (locus[i]!=NO_LOCUS)
522 	      if (assigned_to(locus[i],chrom) && is_placeable(locus[i],chrom))
523 		{ chrom_locus[n_to_place++]=locus[i]; locus[i]=NO_LOCUS; }
524 	    if (n_to_place==0) continue; /* next chrom */
525 
526 	    frame= get_chrom_frame(chrom,&n_frame);
527 	    /* chrom_all has the framework first, then chrom_locus loci */
528 	    get_chrom_loci(chrom,chrom_all,ALL_LOCI,&n_chrom,NULL);
529 	    sort_loci(chrom_all,n_chrom);
530 
531 	    /* if (!got_any) nl(); */
532 	    print(MAP_DIVIDER);
533 	    sf(ps,PLACE_SOME,n_to_place,maybe_s(n_to_place),chrom2str(chrom));
534 	    pr(); nl();
535 	    if (n_frame<2) { sf(ps,PLACE_NOFRAME); pr(); nl(); continue; }
536 	    got_any=TRUE; /* yes, do this here */
537 
538 	    /* if (use_haplotypes)
539 	       { print_haplo_summary(chrom_all,n_chrom); nl(); } */
540 	    if (use_three_pt)
541 	      setup_3pt_data(chrom_all,n_chrom,-three_pt_threshold);
542 
543 	    for (i=0; i<n_chrom; i++) {
544 		num=chrom_all[i];
545 		sf(ps,"%4d %s%s",num+1,raw.locus_name[num],
546 		   (use_haplotypes && haplotyped(num) ? "+":""));
547 		pad_to_len(ps,14); pr();
548 		if (i==n_chrom-1 || i%5==4) nl(); else print("  ");
549 	    }
550 
551 	    mapcpy(order,frame,TRUE);
552 	    for (i=0; i<n_to_place; i++) unplaced[i]->locus=chrom_locus[i];
553 	    n_unplaced= n_to_place;
554 
555 	    nl(); sf(ps,PLACE_AT,npt_first_threshold); pr();
556 	    extend_order(order,unplaced,&n_unplaced,-npt_first_threshold,TRUE);
557 
558 	    if (npt_first_threshold!=npt_threshold && n_unplaced>0) {
559 		print(SUB_DIVIDER);
560 		sf(ps,PLACE_AT,npt_threshold); pr();
561 		extend_order(order,unplaced,&n_unplaced,-npt_threshold,FALSE);
562 	    }
563 
564 	    nl();
565 	    sf(ps,"order%d= ",num_orders+1); pr();
566 	    for (i=0; i<order->num_loci; i++) {
567 		sf(ps,"%s ",rag(loc2str(order->locus[i]))); pr();
568 		if (i==0) order_first[0]=order->locus[i];
569 		else order_next[prev]=order->locus[i];
570 		prev=order->locus[i]; /* lint warning is OK */
571 	    }
572 	    nl();
573 	    sf(ps,"other%d= ",num_orders+1); pr();
574 	    for (i=0; i<n_unplaced; i++) {
575 		sf(ps,"%s ",rag(loc2str(unplaced[i]->locus))); pr();
576 		if (i==0) unorder_first[0]=unplaced[i]->locus;
577 		else order_next[prev]=unplaced[i]->locus;
578 		prev=unplaced[i]->locus;
579 	    }
580 	    nl();
581 	    num_orders++;
582 
583 	    if (print_all_maps) for (i=0; i<n_unplaced; i++)
584 	      if (unplaced[i]->best_map->num_loci>0) {
585 		  print(SUB_DIVIDER);
586 		  sf(ps,"Best placement of %s:",
587 		     rag(loc2str(unplaced[i]->locus)));
588 		  print_special_map(unplaced[i]->best_map,ps,
589 				    order->num_loci,order->locus);
590 	      }
591 
592 	} /* next chrom */
593 	if (got_any) print(MAP_DIVIDER); else error(PLACE_NONE);
594 
595     } on_exit {
596 	/* add FREEs */
597 	relay_messages;
598     }
599 }
600 
601 
draw_chromosome()602 command draw_chromosome()
603 {
604     int chrom;
605     char name[PATH_LENGTH+1];
606     FILE *fp=NULL;
607 
608     mapm_ready(ANY_DATA,0,0,NULL);
609     use_uncrunched_args();
610     chrom=get_chrom_arg(FALSE);
611     get_arg(stoken,chrom2str(chrom),name);
612     nomore_args(num_args);
613 
614     run {
615 	if (!make_filename(name,FORCE_EXTENSION,PS_EXT))
616 	  { sf(ps,"illegal filename '%s'",name); error(ps); }
617 	fp= open_file(name,WRITE);
618 	sf(ps,"Drawing chromosome %s in PostScript file '%s'... \n",
619 	   chrom2str(chrom),name); pr();
620 	print_ps_chrom(fp,chrom);
621 	close_file(fp);
622 	print("ok\n");
623 
624     } except {
625 	when CANTOPEN:  sf(ps,"Can't create output file '%s'",name); error(ps);
626 	when CANTCLOSE: error("\nCan't close file - disk is full?");
627 	default: close_file(fp); relay_messages;
628     }
629 }
630 
631 
draw_all_chromosomes()632 command draw_all_chromosomes()
633 {
634     int chrom;
635     char name[PATH_LENGTH+1];
636     FILE *fp=NULL;
637 
638     mapm_ready(ANY_DATA,0,0,NULL);
639     use_uncrunched_args();
640     get_arg(stoken,raw.filename,name);
641     nomore_args(num_args);
642 
643     run {
644 	/* print all chroms in same file to same scale */
645 	if (!make_filename(name,FORCE_EXTENSION,PS_EXT))
646 	  { sf(ps,"illegal filename '%s'",name); error(ps); }
647 	fp=open_file(name,WRITE);
648 	sf(ps,"Drawing all chromosomes in PostScript file '%s'... \n",name);
649 	pr();
650 	print_all_ps_chroms(fp);
651 	close_file(fp);
652 	print("ok\n");
653 
654     } except {
655 	when CANTOPEN:  sf(ps,"Can't create output file '%s'",name); error(ps);
656 	when CANTCLOSE: error("\nCan't close file - disk is full?");
657 	default: close_file(fp); relay_messages;
658     }
659 }
660