8 /****************************************************************************
10 ALPS - Main routines for ALSCRIPT alignment formatting tool
12 Copyright: Geoffrey J. Barton (1992,1993,1997)
14 email: geoff@ebi.ac.uk
16 All use of this program must cite: Barton, G. J. (1993), ALSCRIPT: A Tool to
17 Format Multiple Sequence Alignments, Protein Engineering, Volume 6, No. 1,
20 Please see README file for details of limitations of use.
22 $Id: alps.c,v 1.3 1998/09/17 17:34:26 geoff Exp $
24 Revision 1.3 1998/09/17 17:34:26 geoff
25 Add the new README file and the LICENSE and RELEASE_NOTES
27 Revision 1.2 1998/09/17 16:54:58 geoff
28 Check consistency with archive
31 ****************************************************************************
33 Main routine for ALSCRIPT - formally called ALPS
38 This file contains a set of subroutines that provide for flexible
39 formatting of multiple sequence alignments in PostScript at
44 1. Modified getbloc.c to Agetbloc.c. Agetbloc reads all characters
45 (ie not just legal amino acid codes) from an AMPS blocfile format
46 multiple alignment file.
48 2. Wrote basic page scaling features to allow arbitrary page
49 dimensions to be defined and to allow all x,y locations to be defined
50 in terms of characters of the chosen pointsize. The number of
51 residues per line and hence number of pages is determined by the
52 pointsize. The page is divided into four areas. (a) The main region
53 for plotting out the amino acid sequences. (b) A region to the left of
54 a for plotting sequence identifier codes - the width of this region is
55 set by variable Cidwidth. (c) A region above region a, and (d) a
56 region below a. Regions c and d are initially set to zero size.
57 Routine ALReserveSpace() allows a selected number of lines to be
58 reserved above or below for plotting.
60 3. Routines ALOutID and ALOutSeq written and multi-page plotting of
61 the sequences sorted out. Still limited to one page in the vertical
62 direction - toyed with the idea of writing single page PostScript and
63 using PostScript to modify clipping boundaries like in the Poster demo
64 program in the CookBook.
66 4. Experiment with simple boxing facility - ALDrawSimpleBox(). This
67 routine is incompatible with multi-page output since page breaks are
70 5. Develop sophisticated (!) boxing facility - defines boxes in terms
71 of TOP BOTTOM LEFT and RIGHT lines that may be defined around each
72 character routine ALLineRes() implements this feature. The details of
73 TOP etc for each character are stored in the unsigned char array
74 "lines". This uses the rightmost four bits to encode LEFT RIGHT etc.
75 Thus a line to the LEFT line is coded by decimal 1 (0001 binary), a
76 full box by decimal 15 (1111 binary). ALBoxRes and ALBoxRegion
77 written to allow boxing of arbitrary regions.
79 6. The y coordinate sent to the low level ALLineRes routine
80 refers directly to the index to the lines array. If you want to work in
81 residue coordinate space, you need to flip the y coordinate before
82 writing to the lines array (also the fill array). Routines ALSurroundChars
83 and ALFillChars do this directly. Routines ALBoxRegion and ALFilRegion
84 make use of the Yindx array which does the flip in a much cleaner and more
85 elegant way. If I'd thought of it at the
86 time, I would have used this in ALSurroundChars and ALFillChars as well!
88 7. Now add capability to split alignments vertically as well as horizontally.
89 There is now no limit on pointsize or number/length of sequences
90 (in principle!). Next move on the page layout front will be to allow
91 multiple blocks on a single page - this would permit alignments of a
92 few sequences, or small fonts to make better use of paper!
94 8. We now have most of the subroutines working OK. So time to tidy up the
95 input. Add simple command parser to main programme - this is in two steps,
96 step 1 reads the basic page layout commands, step 2 reads the boxing/shading
97 font changing commands - Oh yes, added the font changing option as well.
99 Current commands as follows:
100 Commands are delimited by space, comma, or tab. Newline signals the end of a
101 command. Unless otherwise stated, units are in characters of the default pointsize.
102 For a full list see the file "alscript.doc".
106 BLOCK_FILE <input filename> %The name of the alignment file to format
107 OUTPUT_FILE <file> %must have this near the beginning
108 LANDSCAPE %Longest side horizontal
110 POINTSIZE <float> %Pointsize for page calculations and character spacing/default size.
111 IDENT_WIDTH <integer> %Width allocated to identifiers.
112 NUMBER_SEQS 1 || 0 %1=number identifiers, 0= no numbers (default).
113 DEFINE_FONT <font number integer> <font name> <pointsize> %define a font to be referred to as font number.
115 DEFINE_FONT 0 Helvetica 10 %font 0 is Helvetica at 10 point
116 DEFINE_FONT 4 Times-Roman DEFAULT %font 4 is Times-Roman at the default pointsize.
117 SETUP %signals end of step 1 commands.
121 RESERVE_SPACE_TOP <integer> %make space at the top of the alignment
122 RESERVE_SPACE_BOTTOM <integer> % bottom DOES NOT WORK.
123 SURROUND_CHARS <chars> <start_res> <start_seq> <end_res> <end_seq>
124 %surround (box) the characters chars within the ranges specified
126 SURROUND_CHARS PG 1 7 20 12 %surround P and G characters from residues 1 to 20 of sequences 7 to 12.
127 SURROUND_CHARS DEKHR ALL %surround D and E and K and R characters for the whole alignment.
129 SHADE_CHARS <chars> <start_res> <start_seq> <end_res> <end_seq> <grey>
130 %similar syntax to SURROUND_CHARS with the addition of a grey value
131 % 0 = black, 1 = white. Note that shading is done before outputing the
134 SHADE_CHARS PG 1 7 20 12 0.5 % shade P and G in the range shown with a grey value of 0.5
135 SHADE_CHARS ILV ALL 0 % shade all I and L and V in black.
137 FONT_CHARS <chars> <start_res> <start_seq> <end_res> <end_seq> <fontnumber>
138 %same syntax as SHADE_CHARS, only give the font number in place of grey.
139 %font numbers must first be defined with the DEFINE_FONT command above.
140 FONT_RESIDUE sx sy font %allows setting of font for one residue (use with TEXT command)
142 BOX_REGION <start_res> <start_seq> <end_res> <end_seq>
143 %draw a rectangular box around the characters within the defined range.
144 SHADE_REGION <start_res> <start_seq> <end_res> <end_seq> <grey>
145 %shade the region by the chosed grey value.
147 9. Add option to place arbitrary text string at a character location.
149 TEXT 1 7 "SIGNAL PEPTIDE" %puts this text at sequence position 1 7.
150 %to change fonts use the FONT_RESIDUE or FONT_REGION commands.
151 10. Add option to change fonts of identifiers.
152 ID_FONT <sequence> <font>
154 ID_FONT 3 1 %sets font to 1 for sequence identifier 3
155 ID_FONT ALL 7 %uses font 7 for all identifiers
158 Still fiddling - must get back to some real work soon.
159 Split alps away from the scanps program. Now have a separate main() for the routine.
161 Add options to redefine all defaults: e.g. MAXslen (maximum sequence
162 length etc.) Add arbitrary line drawing options: eg. LINE TOP 20 15 50
163 draws a line along the top of the characters from residue 20 to 50 or
164 sequence 15. Think about adding the option to change line thickness at
165 different parts of the plot. Decide not to implement that option right
166 now. Add option to include dummy sequences (ADD_SEQ)
168 Check the programme compiles on the 386 PC. It does!
169 Write documentation and brief report of the programme.
171 22nd June 1992: Get back to some real work!
173 19th October: Add SILENT_MODE Command and carriage returns to all .PS print statements.
174 21st October: Add VERTICAL_SPACING command and ability to output multiple blocks per page.
175 15th November: Add pipe options to alscript.c Tidy up file handling.
177 6th December: Add Colour options.
178 18th Jan 1993: Tidy up citations: modify Inverse chars to allow reversion.
179 1 March 1993: Fix bug in colour option. Pass use_colour to ALDrawLines routine to
180 specify black for line colour. Previously, this was drawn in white
181 if coloured shading had been specified on the same characters.
182 2 March 1993: Fix bug in colour option to output identifiers in black, not white!
183 9 March 1993: Add NO_NUMBERS option to avoid printing residue numbers.
184 24 March 1993: Add mask features.
186 11 March 1994: At PERI - Add special text features - preliminary version only.
187 This permits strands and helices to be plotted as cylinders and arrows.
188 Special text features also permit triangles and circles etc etc. through
191 23 May 1995: Numerous changes and additions over the last year - these
192 include the option to colour backgrounds differently, ommission of
193 idents on second and subsequent lines, helix, strand and other special
194 characters, relative numbering, error checking of ranges on input,
195 bounding box, screening, conservation colouring...
200 #define TOKENS "\" ,\n\t" /* standard command token delimiters */
201 #define POINT 72 /* Work in points throughout */
202 #define C_ID_WIDTH 10 /* Default width for writing id's (in characters) */
203 #define DEF_POINTSIZE 10.0
204 #define X_OFFSET 40 /* offset for bottom lh corner of page (points) */
206 #define DEF_YPOS 0 /* default first printinf position (character units) */
207 #define LINE_WIDTH_FACTOR 0.05 /* Multiply pointsize by this to get linewidth */
208 #define MAX_ADD_SEQ 10 /* Maximum number of ADD_SEQ commands allowed */
210 /*#define MAX_S 10.5 max and min page side in inches */
211 /*#define MIN_S 6.5 */
212 /*#define MAXSIDE (MAX_S * POINT) Default Max and min dimensions of paper */
213 /*#define MINSIDE (MIN_S * POINT) */
215 #define SCREENSIZE 120 /* define default size for screen */
218 int width = 0; /* max width and height of drawing area */
220 char *tokens = TOKENS;
222 float MAXside = 10.5 * POINT; /* values to hold Max and min page side in points */
223 float MINside = 6.5 * POINT;
228 int Cidwidth = C_ID_WIDTH; /* width of id region in characters (left of sequence block)*/
229 int Cseqwidth; /* width of sequence region in characters */
230 int Cwidth; /* width/height of page in characters */
232 int Xspace; /* spacing between characters in X */
233 int Yspace; /* spacing between characters in Y */
234 float XspaceFactor = 0.2; /* extra bit to add to horizontal character spacing */
235 float YspaceFactor = 0.0; /* extra bit to add to vertical character spacing */
236 float XshiftFactor = 0.12; /* *pointsize gives the shift for vertical lines */
237 float YshiftFactor = 0.12; /* horizontal lines */
240 int CseqVoffset = 0; /* vertical offset for sequence block (characters)*/
241 int CtopSpace =0; /* extra space above sequence block (characters) */
242 int CbottomSpace = 0; /* " " below " " " */
243 int Csheet = 1; /* number of vertical splits in sequence block */
245 int TVspace = 0; /* total vertical space reserved (characters)*/
247 float Xshift = 0; /* offsets for drawing box lines */
249 float LineWidthFactor = LINE_WIDTH_FACTOR;
251 float pointsize = DEF_POINTSIZE;
254 int Vspacing = 0; /* vertical spacing in characters between blocks on a page */
272 /* bit masks for the lines array */
273 unsigned char LINE_LEFT = 1; /* mask for line at left of char */
274 unsigned char LINE_RIGHT= 2; /* right */
275 unsigned char LINE_TOP = 4; /* top */
276 unsigned char LINE_BOTTOM=8; /* bottom */
278 void ALOutId(struct seqdat *,int,unsigned char *colour,
279 unsigned char *,int,int,int,int, FILE *);
280 void ALOutSeq(struct seqdat *,unsigned char **,
282 unsigned char **,int ,unsigned char **,
283 unsigned char **text_colour,
284 unsigned char background_colour,
285 int ,int ,int ,int ,FILE *);
286 void PSPutText(int,int,char *,FILE *);
287 void PSPutChar(int,int,char,FILE *);
288 void PSShowPage(FILE *);
289 void ALSetFont(char *,int,FILE *);
290 void ALCheckSinglePage(int ,int ,int );
291 void ALSetPageLimits(void);
292 void PSSetOrientation(int, FILE *);
293 void PSPreamble(FILE *,int, int*, int screensize);
294 void PSLandscape(FILE *);
295 void PSPortrait(FILE *);
296 void PSSetupPage(int,int,FILE *);
297 void ALReserveSpace(int, int);
298 void ALReportInfo(int, FILE *);
299 char **ALCreateNumbers(int,int,int,int);
300 char *ALCreateTicks(int,int,int);
301 void ALOutTicks(char *,int,int,int,int,FILE *);
302 void ALOutNumbers(char **,int,int,int,int,FILE *);
303 void PSDrawBox(float,float,float,float,float,FILE *);
304 void ALSimpleBox(int,int,int,int,float,FILE *);
305 void PSline(float,float,float,float,FILE *);
306 void ALLineChar(unsigned char **,int,int,unsigned char);
307 void ALLineRes(unsigned char **,int,int,unsigned char);
308 void ALDrawLines(unsigned char **,int,
309 unsigned char **left_line_colour,
310 unsigned char **right_line_colour,
311 unsigned char **top_line_colour,
312 unsigned char **bottom_line_colour,
313 int,int,int,int,int,int,FILE *);
314 void ALBoxRes(unsigned char **,int,int);
315 void ALDrawFills(signed char **,int ,unsigned char **,
316 int,int ,int,int ,int ,int, FILE *);
317 void ALFilRes(signed char **,int,int,float);
318 void ALBoxRegion(unsigned char **,int,int,int,int,int *);
319 void ALFilRegion(signed char **,int ,int,int,int , int *,float);
320 void ALSurroundChars(struct seqdat *,unsigned char **,int,int,int,int,int,char *);
321 void ALShadeChars(struct seqdat *,signed char **,
322 int ,int,int,int,int,char *,float);
323 void ALDefineFont(int,char *,float,FILE *);
325 void ALGetFourInt(int *,int *,int *,int *);
326 void ALGetThreeInt(int *,int *,int *);
327 void ALGetTwoInt(int *,int *);
328 void ALFontChars(struct seqdat *,unsigned char **,
329 int,int,int,int,char *,unsigned char);
330 void ALFontRegion(unsigned char **,int,int,int,int,unsigned char);
331 void PSSetFont(unsigned char,FILE *);
332 void ALDoLine(unsigned char **,int,int,int,int,int *);
333 void ALSubChars(struct seqdat *,int,int,int,int,char,char);
334 char ALChekSpace(const char *);
335 void PSSetGrey(float,FILE *);
336 void ALInverseChars(struct seqdat *,unsigned char **,int,int,int,int,char *);
337 int Agetbloc(FILE *,struct seqdat *,int *);
338 void ALDefineColour(int,char *coltype, float,float,float,FILE *);
339 void ALSColChars(struct seqdat *,unsigned char **,
340 int,int,int,int,int,char *,unsigned char);
341 void ALColourChars(struct seqdat *,unsigned char **,
342 int ,int,int,int,char *,unsigned char);
343 void ALColRes(unsigned char **,int ,int , int );
344 void PSSetColour(unsigned char,FILE *);
345 void ALColRegion(unsigned char **,int,int,int,int,int *,unsigned char);
346 void ALColRRegion(unsigned char **,int,int,int,int,unsigned char);
347 void ckdd(struct seqdat *, int);
348 int Ifound(struct seqdat *,int,int,char *,int);
349 void ALSColMask(unsigned char **,unsigned char **,
350 int, int, int, int,int, unsigned char);
351 void ALInverseMask(unsigned char **,unsigned char **,int, int, int, int);
352 void ALFontMask(unsigned char **,unsigned char **,int, int, int, int,unsigned char);
353 void ALShadeMask(unsigned char **,signed char **,int,int,int,int,int *, float);
354 void ALGetAllRange(int *, int *, int *, int *,int ,int );
355 void ALid_mask(unsigned char **,struct seqdat *,int, int, int, int, int, char *, char *);
356 void ALfre_mask(unsigned char **mask,struct seqdat *,int, int, int, int, char *, char *);
357 int Ifound(struct seqdat *,int,int,char *,int);
358 void ALagree_mask(unsigned char **,struct seqdat *,int,int,int,int,int);
359 void ALnot_mask(unsigned char **,int, int, int, int);
360 void ALsub_mask(unsigned char **,struct seqdat *,int, int, int, int, char);
361 void ALMask(unsigned char **,int, int, int, int);
362 void ALConsMask(unsigned char **mask,
363 int sx,int sy,int ex,int ey,int *consval,int conscut);
364 void ALColourMask(unsigned char **,unsigned char **,int,int,int,int,unsigned char);
365 void ALSurroundMask(unsigned char **,struct seqdat *,unsigned char **,int,int,int,int,int);
366 int save_pir(struct seqdat *,int,FILE *);
367 void ALDrawHorizLine(
368 float Xpos, /* bottom left hand corner of character posn */
370 float Xspace, /* horizontal width of character position */
371 float Yspace, /* vertical height of character position */
372 float width_fac,FILE *outf); /* proportion of vertical height that the line will fill */
373 void ALDrawRightArrow(float Xpos,float Ypos, float Xspace,
374 float Yspace, float width_fac,FILE *outf);
375 void ALDrawLeftArrow(float Xpos,float Ypos, float Xspace,
376 float Yspace, float width_fac,FILE *outf);
377 void ALDrawUpArrow(float Xpos,float Ypos, float Xspace,
378 float Yspace, float width_fac,FILE *outf);
379 void ALDrawDownArrow(float Xpos,float Ypos, float Xspace,
380 float Yspace, float width_fac,FILE *outf);
381 void ALDrawCircle(float Xpos,float Ypos, float Xspace,
382 float Yspace, float width_fac,FILE *outf);
383 void ALDrawPseudoEllipse(float Xpos,float Ypos, float Xspace,
384 float Yspace, float width_fac,
386 void ALDrawLeftSemiEnd(float Xpos,float Ypos, float Xspace,
387 float Yspace, float width_fac,FILE *outf);
388 void ALDrawRightSemiEnd(float Xpos,float Ypos, float Xspace,
389 float Yspace, float width_fac,FILE *outf);
390 void ALDrawRightHalfHorizLine(float Xpos,float Ypos,float Xspace,
391 float Yspace,float width_fac,FILE *outf);
392 void ALDrawLeftHalfHorizLine(float Xpos,float Ypos,float Xspace,float
393 Yspace,float width_fac,FILE *outf);
394 void PSmoveto(float x,float y,FILE *outf);
395 void PSlineto(float x,float y,FILE *outf);
396 void PSPutSpecialText(float Xpos,float Ypos,float Xspace,
397 float Yspace,char *text,unsigned char current_col,
398 unsigned char background_colour,
399 float YspaceFactor,FILE *outf);
400 void PSstroke(FILE *outf);
401 void PSnewpath(FILE *outf);
402 void ALColourBackground(FILE *outf,int colour,int *background_region);
403 void ALCheckLegalRange(int sx,int sy, int ex, int ey, int xmin, int ymin, int xmax, int ymax);
404 void ALMakeCoilText(int sx, int sy, int ex, char ***texts);
405 void ALMakeStrandText(int sx, int sy, int ex, char ***texts);
406 void ALMakeHelixText(int sx, int sy, int ex, char ***texts);
407 int ALrel(char *pos,int *relnum);
408 int GJindex(char *str,char c);
409 float mzcons(unsigned char *pos,int n);
410 int *ALCalCons(struct seqdat *bloc,
411 int sx,int sy,int ex,int ey,int *ret_val,int len);
412 int save_msf(struct seqdat *bloc,int nseq,FILE *msff);
414 int alps(char *command_file,int silent, int pipe, int singlepage)
416 FILE *cf,*inf,*outf,*pirf,*msff;
423 extern int MAXtlen,MAXnbloc;
424 extern int MAXilen,precis,MAXslen;
432 unsigned char **lines;
438 unsigned char **fonts;
439 unsigned char *idfonts;
440 unsigned char **inverse;
453 char oldchar,newchar;
455 struct seqdat *addbloc;
465 int nbp,nspage; /*counter and total for number of blocks per page */
469 /* bounding_box - allows explicit fiddling with the bounding_box */
473 float red,green,blue;
474 unsigned char **s_colour; /*colour number for shading */
475 unsigned char **c_colour; /*colour number for characters */
476 /* new 4th Oct 1994 */
477 unsigned char *id_colour; /*colour for identifiers */
478 unsigned char **left_line_colour; /*colours for lines */
479 unsigned char **right_line_colour;
480 unsigned char **top_line_colour;
481 unsigned char **bottom_line_colour;
482 unsigned char **text_colour; /*colour for text */
485 int background_colour = 99; /*set background to white */
486 int *background_region; /* use this to set the region for background colouring */
488 int number_colour = 100; /* colour for numbers along top of plot */
492 int use_colour; /* flag set if the define_colour command is seen */
497 /* min and max ranges in the sequence alignment */
498 int xmin, ymin, xmax, ymax;
500 /* masking variables */
501 unsigned char **mask;
506 /* screen size variable - for printer screen */
507 int screensize = SCREENSIZE;
509 /* set up relative numbering - allows commands to follow
510 a specific sequence numbering
511 firstres defines the number of the first residue */
512 int relative_seq = 0;
519 /* flag for idents */
520 int id_only_on_first = 0;
524 /* conservation values */
525 int *consval; /* array */
526 int conscut; /* cutoff */
528 /* counter for add_seq errors */
532 extern FILE *std_in, *std_out, *std_err;
534 /* By default read and write to stdin and stdout */
539 /* default is no colour */
542 /* if set, residue numbers are output */
547 /* set the bounding box to default values for portrait A4*/
548 bounding_box = (int *) GJmalloc(sizeof(int) * 4);
551 bounding_box[2] = 590;
552 bounding_box[3] = 826;
554 /* set the background colour region equal to the default bounding box */
555 background_region = (int *) GJmalloc(sizeof(int) * 4);
556 background_region[0] = 0;
557 background_region[1] = 0;
558 background_region[2] = 590;
559 background_region[3] = 826;
561 /* initialise the mask */
566 adds = (struct addseq *) malloc(sizeof(struct addseq) * (MAX_ADD_SEQ+1));
570 fname = (char *) malloc(sizeof(char)*MAXtlen);
572 buff = (char *) malloc(MAXtlen * sizeof(char));
573 if(buff == NULL)error("No Space for buff",1);
575 if((cf = fopen(command_file,"r")) == NULL){
576 error("Cannot open ALSCRIPT command file",0);
581 This is a little inelegant at the moment - when I get the generalized
582 parser finished this could be cleaned up substantially
585 /* main loop to read commands */
587 /* Alscript is being used as a pipe so write preamble to std_out */
589 PSPreamble(outf,singlepage,bounding_box,screensize);
592 if(!silent)fprintf(std_err,"Starting ALSCRIPT\n");
594 while(buff = fgets(buff,MAXtlen,cf)){
595 if(!silent)echo(buff);
596 if(buff == NULL) continue;
597 token = strtok(buff,TOKENS);
598 if(token == NULL) continue;
599 token = GJstoup(token);
601 if(!silent)echo("Comment\n");
602 }else if(strcmp(token,"SILENT_MODE")==0){
608 }else if(strcmp(token,"MAX_INPUT_LEN")==0){
609 if(!silent) fprintf(std_err,"Max input len was:\t%d\n",MAXtlen);
610 token = strtok(NULL,TOKENS);
611 MAXtlen = atoi(token);
612 if(!silent)fprintf(std_err,"Max input len now:\t%d\n",MAXtlen);
613 }else if(strcmp(token,"MAX_NSEQ")==0){
614 if(!silent)fprintf(std_err,"Max No. of sequences was:\t%d\n",MAXnbloc);
615 token = strtok(NULL,TOKENS);
616 MAXnbloc = atoi(token);
618 fprintf(std_err,"Max No. of sequences now:\t%d\n",MAXnbloc);
619 }else if(strcmp(token,"MAX_ILEN")==0){
620 if(!silent)fprintf(std_err,"Max Identifier length was:\t%d\n",MAXilen);
621 token = strtok(NULL,TOKENS);
622 MAXilen = atoi(token);
623 if(!silent)fprintf(std_err,"Max Identifier length now:\t%d\n",MAXilen);
624 }else if(strcmp(token,"PRECISION")==0){
625 token = strtok(NULL,TOKENS);
626 precis = atoi(token);
627 }else if(strcmp(token,"MAX_SEQ_LEN")==0){
628 if(!silent)fprintf(std_err,"Max Sequence Length was:\t%d\n",MAXslen);
629 token = strtok(NULL,TOKENS);
630 MAXslen = atoi(token);
631 if(!silent)fprintf(std_err,"Max Sequence Length now:\t%d\n",MAXslen);
632 }else if(strcmp(token,"X_OFFSET")==0){
633 if(!silent)fprintf(std_err,"X offset was:\t%d\n",xoff);
634 token = strtok(NULL,TOKENS);
636 if(!silent)fprintf(std_err,"X offset now:\t%d\n",xoff);
637 }else if(strcmp(token,"Y_OFFSET")==0){
638 if(!silent)fprintf(std_err,"Y offset was:\t%d\n",yoff);
639 token = strtok(NULL,TOKENS);
641 if(!silent)fprintf(std_err,"Y offset now:\t%d\n",yoff);
642 }else if(strcmp(token,"MAX_SIDE")==0){
643 if(!silent)fprintf(std_err,"Longest page side was:\t%.2f inches\n",MAXside/POINT);
644 token = strtok(NULL,TOKENS);
645 MAXside = POINT * atof(token);
646 if(!silent)fprintf(std_err,"Longest page side now:\t%.2f inches\n",MAXside/POINT);
647 }else if(strcmp(token,"MIN_SIDE")==0){
648 if(!silent)fprintf(std_err,"Shortest page side was:\t%.2f inches\n",MINside/POINT);
649 token = strtok(NULL,TOKENS);
650 MINside = POINT * atof(token);
651 if(!silent)fprintf(std_err,"Shortest page side now:\t%.2f inches\n",MINside/POINT);
652 }else if(strcmp(token,"LINE_WIDTH_FACTOR")==0){
653 if(!silent)fprintf(std_err,"Line width multiplication factor was:\t%f\n",LineWidthFactor);
654 token = strtok(NULL,TOKENS);
655 LineWidthFactor = atof(token);
656 if(!silent)fprintf(std_err,"Line width multiplication factor now:\t%f\n",LineWidthFactor);
657 }else if(strcmp(token,"SCREENSIZE")==0){
658 if(!silent)fprintf(std_err,"Screensize was:\t%d\n",screensize);
659 token = strtok(NULL,TOKENS);
660 screensize = atoi(token);
661 if(!silent)fprintf(std_err,"Screensize now:\t%d\n",screensize);
662 }else if(strcmp(token,"BLOCK_FILE") == 0){
663 token = strtok(NULL,TOKENS);
665 inf = fopen(token,"r");
666 if(inf == NULL)error("Cannot open BLOCK_FILE\n",1);
668 }else if(strcmp(token,"OUTPUT_FILE")==0){
669 token = strtok(NULL,TOKENS);
671 outf = fopen(token,"w");
672 if(outf == NULL)error("Cannot open OUTPUT_FILE\n",1);
673 PSPreamble(outf,singlepage,bounding_box,screensize);
675 }else if(strcmp(token,"PIR_SAVE")==0){
676 token = strtok(NULL,TOKENS);
677 pirf = fopen(token,"w");
678 if(pirf == NULL)error("Cannot open PIR_SAVE file\n",1);
680 }else if(strcmp(token,"MSF_SAVE")==0){
681 token = strtok(NULL,TOKENS);
682 msff = fopen(token,"w");
683 if(msff == NULL)error("Cannot open MSF_SAVE file\n",1);
685 }else if(strcmp(token,"LANDSCAPE")==0){
686 orientation = LANDSCAPE;
687 }else if(strcmp(token,"PORTRAIT")==0){
688 orientation = PORTRAIT;
690 }else if(strcmp(token,"POINTSIZE")==0){
691 token = strtok(NULL,TOKENS);
692 pointsize = atof(token);
693 }else if(strcmp(token,"IDENT_WIDTH")==0){
694 token = strtok(NULL,TOKENS);
695 Cidwidth = atoi(token);
696 if(Cidwidth > MAXilen)error("INCREASE MAX_ID_LEN value",1);
697 }else if(strcmp(token,"NUMBER_SEQS")==0){
699 }else if(strcmp(token,"X_SPACE_FACTOR")==0){
700 if(!silent)fprintf(std_err,"Was:\t%.2f\n",XspaceFactor);
701 token = strtok(NULL,TOKENS);
702 XspaceFactor = atof(token);
703 if(!silent)fprintf(std_err,"Now Is:\t%.2f\n",XspaceFactor);
704 }else if(strcmp(token,"Y_SPACE_FACTOR")==0){
705 if(!silent)fprintf(std_err,"Was:\t%.2f\n",YspaceFactor);
706 token = strtok(NULL,TOKENS);
707 YspaceFactor = atof(token);
708 }else if(strcmp(token,"X_SHIFT_FACTOR")==0){
709 if(!silent)fprintf(std_err,"Was:\t%.2f\n",XshiftFactor);
710 token = strtok(NULL,TOKENS);
711 XshiftFactor = atof(token);
712 if(!silent)fprintf(std_err,"Now Is:\t%.2f\n",XshiftFactor);
713 }else if(strcmp(token,"Y_SHIFT_FACTOR")==0){
714 if(!silent)fprintf(std_err,"Was:\t%.2f\n",YshiftFactor);
715 token = strtok(NULL,TOKENS);
716 YshiftFactor = atof(token);
717 if(!silent)fprintf(std_err,"Now Is:\t%.2f\n",YshiftFactor);
718 }else if(strcmp(token,"VERTICAL_SPACING")==0){
719 if(!silent)fprintf(std_err,"Was:\t%d\n",Vspacing);
720 token = strtok(NULL,TOKENS);
721 Vspacing = (int) atol(token);
722 if(!silent)fprintf(std_err,"Now Is:\t%d\n",Vspacing);
723 }else if(strcmp(token,"DEFINE_FONT")==0){
724 token = strtok(NULL,TOKENS);
725 fnum = atoi(token); /* font number */
726 token = strtok(NULL,TOKENS); /* font name */
727 fname = strcpy(fname,token);
728 token = strtok(NULL,TOKENS);
729 if(strcmp(token,"DEFAULT")==0){
731 }else if(strcmp(token,"REL")==0){
732 token = strtok(NULL,TOKENS);
733 fpoint = pointsize * atof(token);
735 fpoint = atof(token);
737 ALDefineFont(fnum,fname,fpoint,outf);
738 }else if(strcmp(token,"DEFINE_COLOUR")==0 || strcmp(token,"DEFINE_COLOR")==0){
740 define_colour <colour_number | colour type> colour_name r g b <colour_number> */
741 /* e.g. define_colour 1 1.0 1.0 1.0
743 define_colour rgb red 1.0 0.0 0.0 7
744 (define an rgb colour (red,green,blue),colour_number)
745 define_colour hsb red 1.0 0.0 0.0 9
746 (define an hsb colour (hue,sat,bright),colour_number)
747 currently can use either hsb OR rgb, but not mix them
750 token = strtok(NULL,TOKENS);
751 tstring = GJstoupper(token);
752 if(strcmp(tstring,"RGB")==0 || strcmp(tstring,"HSB")==0){
753 token = strtok(NULL,TOKENS);
754 colname = GJstrdup(token);
755 token = strtok(NULL,TOKENS);
757 token = strtok(NULL,TOKENS);
759 token = strtok(NULL,TOKENS);
761 token = strtok(NULL,TOKENS);
764 fnum = atoi(token); /* colour number */
765 token = strtok(NULL,TOKENS);
767 token = strtok(NULL,TOKENS);
769 token = strtok(NULL,TOKENS);
773 /* for now just ignore the colour name - we'll allow use of this later */
774 ALDefineColour(fnum,tstring,red,green,blue,outf);
776 }else if(strcmp(token,"ADD_SEQ")==0){
777 token = strtok(NULL,TOKENS);
778 adds[nadds].pos = atoi(token);
779 token = strtok(NULL,TOKENS);
780 adds[nadds].num = atoi(token);
782 }else if(strcmp(token,"DO_TICKS")==0){
784 }else if(strcmp(token,"NUMBER_INT")==0){
785 token = strtok(NULL,TOKENS);
786 number_int = atoi(token);
787 if(!silent)fprintf(std_err,"Sequence Numbering interval now:\t%d\n",number_int);
788 }else if(strcmp(token,"NO_NUMBERS")==0){
790 }else if(strcmp(token,"NUMBER_COLOUR")==0){
791 token = strtok(NULL,TOKENS);
792 number_colour = atoi(token);
793 }else if(strcmp(token,"SINGLE_PAGE")==0){
794 /* if this is set, then alscript assumes a single page -
795 just adds a bounding box for now*/
796 if(!silent)fprintf(std_err,"Single page was: %d\n",singlepage);
798 if(!silent)fprintf(std_err,"Single page now: %d\n",singlepage);
799 }else if(strcmp(token,"BOUNDING_BOX")==0){
800 ALGetFourInt(&bounding_box[0],&bounding_box[1],
801 &bounding_box[2],&bounding_box[3]);
803 fprintf(std_err,"Bounding box set to: %d %d %d %d\n",
804 bounding_box[0],bounding_box[1],
805 bounding_box[2],bounding_box[3]);
807 }else if(strcmp(token,"BACKGROUND_REGION") == 0){
808 /* set the region of the background to colour */
809 ALGetFourInt(&background_region[0],&background_region[1],
810 &background_region[2],&background_region[3]);
812 fprintf(std_err,"Background region set to: %d %d %d %d\n",
813 background_region[0],background_region[1],
814 background_region[2],background_region[3]);
816 }else if(strcmp(token,"ID_ONLY_ON_FIRST_LINE")==0){
817 /* flag to indicate identifiers only on first line!*/
818 id_only_on_first = 1;
819 }else if(strcmp(token,"BACKGROUND_COLOUR") ==0){
820 /* set the colour for background defined by background_region */
821 token = strtok(NULL,TOKENS);
822 background_colour = atoi(token);
823 }else if(strcmp(token,"SETUP")==0){
824 if(!silent)fprintf(std_err,"Initial Commands read - Establishing basic settings\n");
827 fprintf(std_err,"%s",buff);
828 error("Unrecognised Step 1 command",1);
834 if(!silent)fprintf(std_err,"Output file undefined - will write to stdout\n");
839 if(!silent)fprintf(std_err,"Block file undefined - will read from stdin\n");
842 bloc = (struct seqdat *) malloc(sizeof(struct seqdat) * MAXnbloc);
843 mcheck((char *) bloc,"Cannot get space for bloc");
844 if(!Agetbloc(inf,bloc,&nseq))error("Cannot read bloc file",1);
849 if(!save_pir(bloc,nseq,pirf))error("Cannot write to pirf file",1);
854 if(!save_msf(bloc,nseq,msff))error("Cannot write to msf file",1);
858 /* Initialise relnum to 1..n*/
859 /* relnum = (int *) GJmalloc(sizeof(int) * MAXslen); */
860 /* for(i=1;i<MAXslen;++i){ */
864 /* Initialise relnum to 1..n*/
865 /* 29 July 1998 - allocate relnum to MAXslen *2. with pointer in the middle */
867 trelnum = (int *) GJmalloc(sizeof(int) * MAXslen * 2);
868 for(i=1;i<(MAXslen +1);++i){
871 relnum = &trelnum[MAXslen];
872 for(i=1;i<MAXslen;++i){
876 /* do a check of the adds array to make sure there are no out of bounds
880 for(i=0;i<nadds;++i){
881 if(adds[i].pos > nseq){
883 fprintf(std_err,"Error in ADD_SEQ request: %d %d\n",adds[i].pos,adds[i].num);
884 fprintf(std_err,"%d is greater than the number of sequences in the block file(%d)\n",adds[i].pos,nseq);
885 fprintf(std_err,"Please see the manual for help on using ADD_SEQ\n");
889 fprintf(std_err,"%d ADD_SEQ errors - exiting\n",adderr);
895 if(!silent)fprintf(std_err,"Making extra space for %d additions\n",nadds);
897 for(i=0;i<nadds;++i){
898 natot += adds[i].num;
900 if(!silent)fprintf(std_err,"Total of %d extra sequences\n",natot);
901 addbloc = (struct seqdat *) malloc(sizeof(struct seqdat) *(nseq+natot+1));
906 if(k < nadds && i==adds[k].pos){
907 /* reserve space for the new sequences and set to blank*/
908 for(l=0;l<adds[k].num;++l){
910 addbloc[j].id = (char *) malloc(sizeof(char) * MAXilen);
911 addbloc[j].id = GJstrblank(addbloc[j].id,MAXilen);
912 addbloc[j].seq = (char *) malloc(sizeof(char) * (bloc[1].slen+1));
913 addbloc[j].seq = GJstrblank(addbloc[j].seq,bloc[1].slen+1);
917 /* just copy the pointers to the bloc sequences */
921 addbloc[j].id = bloc[i].id;
922 addbloc[j].title = bloc[i].title;
923 addbloc[j].seq = bloc[i].seq;
927 addbloc[1].slen = bloc[1].slen;
932 if(!silent)fprintf(std_err,"Total number of sequences now: %d\n",nseq);
934 msl = bloc[1].slen-2; /* maximum sequence length defined */
936 xmin = 1; ymin = 1; xmax = msl+1; ymax = nseq;
938 PSSetupPage(orientation,1,outf);
941 CtopSpace = 2; /* set top 2 lines for numbers */
943 /* now set up the bounding box and background
944 based on current values of xoff, yoff, width and height
945 these can be overridden by step 2 commands
949 bounding_box[2] = width;
950 bounding_box[3] = height;
953 /* set the background colour region equal to the default bounding box
954 background_region[0] = bounding_box[0];
955 background_region[1] = bounding_box[1];
956 background_region[2] = bounding_box[2];
957 background_region[3] = bounding_box[3];
960 if(background_colour != 99)ALColourBackground(outf,background_colour,background_region);
965 /* ALReserveSpace(TOP,2);*/
968 /* allocate to +1 size to allow indexing from 1...max */
969 /* lines array - stored info on where to draw lines */
970 lines = uchararr(bloc[1].slen+1,nseq+1);
971 if(lines == NULL)error("No space for lines array\n",1);
972 GJUCinit(lines,bloc[1].slen+1,nseq+1,0);
974 /* array holds grey value for each character fill*/
975 fills = chararr(bloc[1].slen+1,nseq+1);
976 if(fills == NULL)error("No space for fills array\n",1);
977 GJCinit(fills,bloc[1].slen+1,nseq+1,-1);
979 /* allocate to +1 size to allow indexing from 1...max */
980 /* fonts array - stores a number representing the font to use for each residue */
981 /* default font is font 0 */
982 fonts = uchararr(bloc[1].slen+1,nseq+1);
983 if(fonts == NULL)error("No space for fonts array\n",1);
984 GJUCinit(fonts,bloc[1].slen+1,nseq+1,0);
986 /* inverse indicates whether the the text at i j should be printed in white */
987 inverse = uchararr(bloc[1].slen+1,nseq+1);
988 if(inverse == NULL)error("No space for inverse array\n",1);
989 GJUCinit(inverse,bloc[1].slen+1,nseq+1,0);
991 /* colour arrays - define the colour to use for shading and lettering */
992 /* default colour numbers are 99 for white and 100 for black */
993 s_colour = uchararr(bloc[1].slen+1,nseq+1); /* shading colour */
994 if(s_colour == NULL)error("No space for s_colour array\n",1);
995 GJUCinit(s_colour,bloc[1].slen+1,nseq+1,background_colour);
996 c_colour = uchararr(bloc[1].slen+1,nseq+1); /* character colour */
997 if(c_colour == NULL)error("No space for c_colour array\n",1);
998 GJUCinit(c_colour,bloc[1].slen+1,nseq+1,100);
999 left_line_colour = uchararr(bloc[1].slen+1,nseq+1); /* left line colour */
1000 if(left_line_colour == NULL)error("No space for left_line_colour array\n",1);
1001 GJUCinit(left_line_colour,bloc[1].slen+1,nseq+1,100);
1002 right_line_colour = uchararr(bloc[1].slen+1,nseq+1); /* right line colour */
1003 if(right_line_colour == NULL)error("No space for right_line_colour array\n",1);
1004 GJUCinit(right_line_colour,bloc[1].slen+1,nseq+1,100);
1005 top_line_colour = uchararr(bloc[1].slen+1,nseq+1); /* top line colour */
1006 if(top_line_colour == NULL)error("No space for top_line_colour array\n",1);
1007 GJUCinit(top_line_colour,bloc[1].slen+1,nseq+1,100);
1008 bottom_line_colour = uchararr(bloc[1].slen+1,nseq+1); /* bottom line colour */
1009 if(bottom_line_colour == NULL)error("No space for bottom_line_colour array\n",1);
1010 GJUCinit(bottom_line_colour,bloc[1].slen+1,nseq+1,100);
1011 text_colour = uchararr(bloc[1].slen+1,nseq+1); /* text colour */
1012 if(text_colour == NULL)error("No space for text_colour array\n",1);
1013 GJUCinit(text_colour,bloc[1].slen+1,nseq+1,100);
1015 /* holds font information for each identifier */
1016 idfonts = (unsigned char *) malloc(sizeof(unsigned char) * nseq+1);
1017 for(i=0;i<nseq+1;++i){
1018 idfonts[i]= (unsigned char) 0;
1020 /* holds colour information for each identifier */
1021 id_colour = (unsigned char *) GJmalloc(sizeof(unsigned char) * nseq+1);
1022 for(i=0;i<nseq+1;++i){
1023 id_colour[i]= (unsigned char) 100;
1025 /* holds conservation values */
1026 consval = (int *) GJmalloc(sizeof(int) * bloc[1].slen);
1027 GJIinit(consval,bloc[1].slen,0);
1030 /* array holds pointers to text strings at each [i][j] point*/
1031 texts = (char ***) malloc(sizeof(char **) * (bloc[1].slen+1));
1032 rowsiz = sizeof(char *) * (nseq + 1);
1033 for(k=0;k<bloc[1].slen+1;++k){
1034 texts[k] = (char **) malloc(rowsiz);
1035 for(i=0;i<(nseq+1);++i){
1040 Yindx = (int *) malloc(sizeof(int)*(nseq+1));
1041 for(i=1,j=nseq;i<nseq+1;++i,--j){
1045 numbers = ALCreateNumbers(0,number_int,bloc[1].slen,4);
1046 ticks = ALCreateTicks(0,number_int,bloc[1].slen);
1049 while(buff = fgets(buff,MAXtlen,cf)){
1050 if(buff == NULL) break;
1051 if(!silent)echo(buff);
1052 token = strtok(buff,TOKENS);
1053 if(token == NULL) break;
1054 token = GJstoup(token);
1056 if(!silent)echo("Comment\n");
1057 }else if(strcmp(token,"SILENT_MODE")==0){
1063 /* This block has moved to the MODE 1 section
1064 }else if(strcmp(token,"BOUNDING_BOX")==0){
1065 ALGetFourInt(&bounding_box[0],&bounding_box[1],
1066 &bounding_box[2],&bounding_box[3]);
1068 }else if(strcmp(token,"BACKGROUND_REGION") == 0){
1069 set the region of the background to colour
1070 ALGetFourInt(&background_region[0],&background_region[1],
1071 &background_region[2],&background_region[3]);
1073 }else if(strcmp(token,"RESERVE_SPACE_TOP")==0){
1074 token = strtok(NULL,TOKENS);
1075 ALReserveSpace(TOP,atoi(token));
1076 }else if(strcmp(token,"RESERVE_SPACE_BOTTOM")==0){
1077 token = strtok(NULL,TOKENS);
1078 ALReserveSpace(BOTTOM,atoi(token));
1079 CseqTop = nseq + CbottomSpace;
1080 }else if(strcmp(token,"SURROUND_CHARS")==0){
1081 token = strtok(NULL,TOKENS);
1083 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1084 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1085 ALSurroundChars(bloc,lines,relnum[sx],sy,relnum[ex],ey,nseq,charstring);
1086 }else if(strcmp(token,"SHADE_CHARS")==0){
1087 token = strtok(NULL,TOKENS);
1089 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1090 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1091 token = strtok(NULL,TOKENS);
1092 ALShadeChars(bloc,fills,relnum[sx],sy,relnum[ex],ey,nseq,charstring,(float)atof(token));
1093 }else if(strcmp(token,"FONT_CHARS")==0){
1094 token = strtok(NULL,TOKENS);
1096 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1097 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1098 token = strtok(NULL,TOKENS);
1099 ALFontChars(bloc,fonts,relnum[sx],sy,relnum[ex],ey,charstring,atoi(token));
1100 }else if(strcmp(token,"CCOL_CHARS")==0){ /* colour characters */
1101 if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
1102 token = strtok(NULL,TOKENS);
1104 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1105 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1106 token = strtok(NULL,TOKENS);
1107 ALColourChars(bloc,c_colour,relnum[sx],sy,relnum[ex],ey,charstring,atoi(token));
1108 }else if(strcmp(token,"SCOL_CHARS")==0){ /* colour character backgrounds */
1109 if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
1110 token = strtok(NULL,TOKENS);
1112 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1113 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1114 token = strtok(NULL,TOKENS);
1115 ALSColChars(bloc,s_colour,relnum[sx],sy,relnum[ex],ey,nseq,charstring,(unsigned char) atoi(token));
1116 }else if(strcmp(token,"INVERSE_CHARS")==0){
1117 token = strtok(NULL,TOKENS);
1119 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1120 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1121 ALInverseChars(bloc,inverse,relnum[sx],sy,relnum[ex],ey,charstring);
1122 }else if(strcmp(token,"SUB_CHARS")==0){
1123 token = strtok(NULL,TOKENS);
1124 if(strcmp(token,"ALL")==0){
1125 token = strtok(NULL,TOKENS);
1126 oldchar = ALChekSpace(token);
1127 token = strtok(NULL,TOKENS);
1128 newchar = ALChekSpace(token);
1129 ALSubChars(bloc,1,1,bloc[1].slen-1,nseq,oldchar,newchar);
1132 ALGetThreeInt(&sy,&ex,&ey);
1133 token = strtok(NULL,TOKENS);
1134 oldchar = ALChekSpace(token);
1135 token = strtok(NULL,TOKENS);
1136 newchar = ALChekSpace(token);
1137 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1138 ALSubChars(bloc,relnum[sx],sy,relnum[ex],ey,oldchar,newchar);
1140 }else if(strcmp(token,"SUB_ID")==0){
1141 token = strtok(NULL,"\"");
1143 token = strtok(NULL,"\"");
1144 ALCheckLegalRange(xmin,1,xmax,sx,xmin,ymin,xmax,ymax);
1145 bloc[sx].id = (char *) realloc(bloc[sx].id,sizeof(char)*(strlen(token)+1));
1146 bloc[sx].id = strcpy(bloc[sx].id,token);
1147 }else if(strcmp(token,"FONT_REGION")==0){
1148 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1149 token = strtok(NULL,TOKENS);
1150 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1151 ALFontRegion(fonts,relnum[sx],sy,relnum[ex],ey,atoi(token));
1152 }else if(strcmp(token,"FONT_RESIDUE")==0){
1153 token = strtok(NULL,TOKENS);
1155 token=strtok(NULL,TOKENS);
1157 token=strtok(NULL,TOKENS);
1158 ALCheckLegalRange(relnum[sx],sy,relnum[sx],sy,xmin,ymin,xmax,ymax);
1159 ALFontRegion(fonts,relnum[sx],sy,relnum[sx],sy,atoi(token));
1160 }else if(strcmp(token,"LINE")==0){
1161 token = strtok(NULL,TOKENS);
1162 if(strcmp(token,"TOP")==0){
1163 ALGetThreeInt(&sx,&sy,&ex);
1164 if(ex > bloc[1].slen-1) ex = bloc[1].slen-1;
1165 ALCheckLegalRange(relnum[sx],sy,relnum[ex],sy,xmin,ymin,xmax,ymax);
1166 ALDoLine(lines,relnum[sx],sy,relnum[ex],LINE_TOP,Yindx);
1167 }else if(strcmp(token,"BOTTOM")==0){
1168 ALGetThreeInt(&sx,&sy,&ex);
1169 ALCheckLegalRange(relnum[sx],sy,relnum[ex],sy,xmin,ymin,xmax,ymax);
1170 if(ex > bloc[1].slen-1) ex = bloc[1].slen-1;
1171 ALDoLine(lines,relnum[sx],sy,relnum[ex],LINE_BOTTOM,Yindx);
1172 }else if(strcmp(token,"LEFT")==0){
1173 ALGetThreeInt(&sx,&sy,&ey);
1174 ALCheckLegalRange(relnum[sx],sy,relnum[sx],ey,xmin,ymin,xmax,ymax);
1175 if(ey > nseq) ey = nseq;
1176 ALDoLine(lines,relnum[sx],sy,ey,LINE_LEFT,Yindx);
1177 }else if(strcmp(token,"RIGHT")==0){
1178 ALGetThreeInt(&sx,&sy,&ey);
1179 ALCheckLegalRange(relnum[sx],sy,relnum[sx],ey,xmin,ymin,xmax,ymax);
1180 if(ey > nseq) ey = nseq;
1181 ALDoLine(lines,relnum[sx],sy,ey,LINE_RIGHT,Yindx);
1183 error("Illegal LINE command\n",1);
1185 }else if(strcmp(token,"BOX_REGION")==0){
1186 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1187 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1188 ALBoxRegion(lines,relnum[sx],sy,relnum[ex],ey,Yindx);
1189 }else if(strcmp(token,"SHADE_REGION")==0){
1190 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1191 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1192 token = strtok(NULL,TOKENS);
1193 ALFilRegion(fills,relnum[sx],sy,relnum[ex],ey,Yindx,(float)atof(token));
1194 }else if(strcmp(token,"SHADE_RES")==0){
1195 ALGetTwoInt(&sx,&sy);
1196 ALCheckLegalRange(relnum[sx],sy,relnum[sx],sy,xmin,ymin,xmax,ymax);
1197 token = strtok(NULL,TOKENS);
1198 ALFilRegion(fills,relnum[sx],sy,relnum[sx],sy,Yindx,(float)atof(token));
1199 }else if(strcmp(token,"COLOUR_REGION")==0 || strcmp(token,"COLOR_REGION")==0){
1200 if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
1201 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1202 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1203 token = strtok(NULL,TOKENS);
1204 ALColRegion(s_colour,relnum[sx],sy,relnum[ex],ey,Yindx,(unsigned char) atoi(token));
1205 }else if(strcmp(token,"COLOUR_TEXT_REGION")==0 || strcmp(token,"COLOR_TEXT_REGION")==0){
1206 if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
1207 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1208 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1209 token = strtok(NULL,TOKENS);
1210 ALColRRegion(text_colour,relnum[sx],sy,relnum[ex],ey,(unsigned char) atoi(token));
1211 }else if(strcmp(token,"COLOUR_RES")==0 || strcmp(token,"COLOR_RES")==0){
1212 if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
1213 ALGetTwoInt(&sx,&sy);
1214 ALCheckLegalRange(relnum[sx],sy,relnum[sx],sy,xmin,ymin,xmax,ymax);
1215 token = strtok(NULL,TOKENS);
1216 ALColRRegion(s_colour,relnum[sx],sy,relnum[sx],sy,(unsigned char) atoi(token));
1217 }else if(strcmp(token,"CCOLOUR_REGION")==0 || strcmp(token,"CCOLOR_REGION")==0){
1218 if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
1219 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1220 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1221 token = strtok(NULL,TOKENS);
1222 ALColRRegion(c_colour,relnum[sx],sy,relnum[ex],ey,(unsigned char) atoi(token));
1223 }else if(strcmp(token,"COLOUR_LINE_REGION")==0 || strcmp(token,"COLOR_LINE_REGION")==0){
1224 if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
1225 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1226 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1227 token = strtok(NULL,TOKENS);
1228 ALColRegion(left_line_colour,relnum[sx],sy,relnum[ex],ey,Yindx,(unsigned char) atoi(token));
1229 ALColRegion(right_line_colour,relnum[sx],sy,relnum[ex],ey,Yindx,(unsigned char) atoi(token));
1230 ALColRegion(top_line_colour,relnum[sx],sy,relnum[ex],ey,Yindx,(unsigned char) atoi(token));
1231 ALColRegion(bottom_line_colour,relnum[sx],sy,relnum[ex],ey,Yindx,(unsigned char) atoi(token));
1232 }else if(strcmp(token,"CCOLOUR_RES")==0 || strcmp(token,"CCOLOR_RES")==0){
1233 if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
1234 ALGetTwoInt(&sx,&sy);
1235 token = strtok(NULL,TOKENS);
1236 ALCheckLegalRange(relnum[sx],sy,relnum[sx],sy,xmin,ymin,xmax,ymax);
1237 ALColRRegion(c_colour,relnum[sx],sy,relnum[sx],sy,(unsigned char) atoi(token));
1238 }else if(strcmp(token,"MASK")==0){
1240 token = strtok(NULL,TOKENS);
1241 if(strcmp(token,"SETUP")==0){
1243 mask = uchararr(bloc[1].slen+1,nseq+1);
1244 GJUCinit(mask,bloc[1].slen+1,nseq+1,0);
1246 GJUCinit(mask,bloc[1].slen+1,nseq+1,0);
1248 }else if(strcmp(token,"RESET")==0){
1249 GJUCinit(mask,bloc[1].slen+1,nseq+1,0);
1250 }else if(strcmp(token,"LEGAL")==0){
1251 /* get the legal character list */
1252 token = strtok(NULL,TOKENS);
1253 if(legal != NULL) GJfree(legal);
1254 legal = GJstrdup(token);
1255 if(!silent)fprintf(stderr,"legal:%s\n",legal);
1256 }else if(strcmp(token,"ILLEGAL")==0){
1257 /* get the illegal character list */
1258 token = strtok(NULL,TOKENS);
1259 if(illegal != NULL) GJfree(illegal);
1260 illegal = GJstrdup(token);
1261 if(!silent)fprintf(stderr,"illegal:%s:\n",illegal);
1262 }else if(strcmp(token,"ID")==0){
1263 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1264 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1265 token = strtok(NULL,TOKENS);
1266 id_cut = atoi(token);
1267 if(id_cut < (int) ( ( ((float) (ey-sy+1) / 2.0) + 0.6))){
1268 error("ID cutoff must be > half the number of sequences",1);
1270 ALid_mask(mask,bloc,relnum[sx],sy,relnum[ex],ey,id_cut,legal,illegal);
1271 }else if(strcmp(token,"AGREE")==0){
1272 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1273 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1274 token= strtok(NULL,TOKENS);
1275 ALagree_mask(mask,bloc,relnum[sx],sy,relnum[ex],ey,atoi(token));
1276 }else if(strcmp(token,"FRE")==0){
1277 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1278 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1279 ALfre_mask(mask,bloc,relnum[sx],sy,relnum[ex],ey,legal,illegal);
1280 }else if(strcmp(token,"NOT")==0){
1281 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1282 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1283 ALnot_mask(mask,relnum[sx],sy,relnum[ex],ey);
1284 }else if(strcmp(token,"SUB")==0){
1285 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1286 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1287 token=strtok(NULL,TOKENS);
1288 ALsub_mask(mask,bloc,relnum[sx],sy,relnum[ex],ey,token[0]);
1289 }else if(strcmp(token,"REGION")==0){
1290 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1291 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1292 ALMask(mask,relnum[sx],sy,relnum[ex],ey);
1293 }else if(strcmp(token,"CONSERVATION")==0){
1294 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1295 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1296 token=strtok(NULL,TOKENS);
1297 conscut = atoi(token);
1298 if(!silent)fprintf(std_err,"Conservation Cutoff:%d\n",conscut);
1299 ALConsMask(mask,relnum[sx],sy,relnum[ex],ey,consval,conscut);
1300 }else if(strcmp(token,"BOX")==0){
1301 /* box the masked residues - ie surround them*/
1302 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1303 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1304 ALSurroundMask(mask,bloc,lines,relnum[sx],sy,relnum[ex],ey,nseq);
1305 }else if(strcmp(token,"SHADE")==0){
1306 /* shade the masked residues - */
1307 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1308 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1309 token = strtok(NULL,TOKENS);
1310 ALShadeMask(mask,fills,relnum[sx],sy,relnum[ex],ey,Yindx,(float)atof(token));
1311 }else if(strcmp(token,"FONT")==0){
1312 /* set the font of the masked residues - */
1313 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1314 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1315 token = strtok(NULL,TOKENS);
1316 ALFontMask(mask,fonts,relnum[sx],sy,relnum[ex],ey,(unsigned char) atoi(token));
1317 }else if(strcmp(token,"INVERSE")==0){
1318 /* invert the masked residues - */
1319 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1320 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1321 token = strtok(NULL,TOKENS);
1322 ALInverseMask(mask,inverse,relnum[sx],sy,relnum[ex],ey);
1323 }else if(strcmp(token,"SCOL")==0){
1324 if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
1325 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1326 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1327 token = strtok(NULL,TOKENS);
1328 ALSColMask(mask,s_colour,relnum[sx],sy,relnum[ex],ey,nseq,(unsigned char) atoi(token));
1329 }else if(strcmp(token,"CCOL")==0){
1330 if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
1331 ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
1332 ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
1333 token = strtok(NULL,TOKENS);
1334 ALColourMask(mask,c_colour,relnum[sx],sy,relnum[ex],ey,(unsigned char) atoi(token));
1336 error("Unrecognised MASK qualifier\n",1);
1338 }else if(strcmp(token,"TEXT")==0){
1339 token=strtok(NULL,TOKENS);
1341 token=strtok(NULL,"\"");
1343 token=strtok(NULL,"\"");
1344 ALCheckLegalRange(relnum[sx],sy,relnum[sx],sy,xmin,ymin,xmax,ymax);
1345 texts[relnum[sx]][sy] = (char *) malloc(sizeof(char)*(strlen(token)+1));
1346 texts[relnum[sx]][sy] = (char *) strcpy(texts[relnum[sx]][sy],token);
1347 }else if(strcmp(token,"NUMBERS")==0){
1348 error("Numbers not implemented",1);
1349 }else if(strcmp(token,"ID_FONT")==0){
1350 token = strtok(NULL,TOKENS);
1351 if(strcmp(token,"ALL")==0){
1352 token = strtok(NULL,TOKENS);
1353 for(i=1;i<nseq+1;++i)idfonts[i]= (unsigned char) atoi(token);
1356 token = strtok(NULL,TOKENS);
1357 ALCheckLegalRange(xmin,ymin,xmax,sx,xmin,ymin,xmax,ymax);
1358 idfonts[sx] = atoi(token);
1360 }else if(strcmp(token,"ID_COLOUR")==0){
1361 token = strtok(NULL,TOKENS);
1362 if(strcmp(token,"ALL")==0){
1363 token = strtok(NULL,TOKENS);
1364 for(i=1;i<nseq+1;++i)id_colour[i]= (unsigned char) atoi(token);
1367 ALCheckLegalRange(xmin,ymin,xmax,sx,xmin,ymin,xmax,ymax);
1368 token = strtok(NULL,TOKENS);
1369 id_colour[sx] = atoi(token);
1371 }else if(strcmp(token,"HELIX")==0){
1372 ALGetThreeInt(&sx,&sy,&ex);
1373 ALCheckLegalRange(relnum[sx],sy,relnum[ex],sy,xmin,ymin,xmax,ymax);
1374 ALMakeHelixText(relnum[sx],sy,relnum[ex],texts);
1375 }else if(strcmp(token,"STRAND")==0){
1376 ALGetThreeInt(&sx,&sy,&ex);
1377 ALCheckLegalRange(relnum[sx],sy,relnum[ex],sy,xmin,ymin,xmax,ymax);
1378 ALMakeStrandText(relnum[sx],sy,relnum[ex],texts);
1379 }else if(strcmp(token,"COIL")==0){
1380 ALGetThreeInt(&sx,&sy,&ex);
1381 ALCheckLegalRange(relnum[sx],sy,relnum[ex],sy,xmin,ymin,xmax,ymax);
1382 ALMakeCoilText(relnum[sx],sy,relnum[ex],texts);
1383 }else if(strcmp(token,"CALCONS")==0){
1384 /* calculate conservation for the range */
1385 ALGetFourInt(&sx,&sy,&ex,&ey);
1386 ALCheckLegalRange(relnum[sx],relnum[sy],relnum[ex],relnum[ey],xmin,ymin,xmax,ymax);
1387 consval = ALCalCons(bloc,relnum[sx],relnum[sy],relnum[ex],relnum[ey],
1388 consval,bloc[1].slen);
1389 /* fprintf(std_err,"Conservation Values\n"); */
1390 /* for(k=1;k<bloc[1].slen-1;++k){*/
1391 /* fprintf(std_err,"%d:%d\n",k,consval[k]);*/
1393 }else if(strcmp(token,"RELATIVE_TO")==0){
1394 token = strtok(NULL,TOKENS);
1395 relative_seq = atoi(token);
1396 fprintf(stderr,"RELATIVE SEQ %d\n",relative_seq);
1397 fprintf(stderr,"bloc[relative_seq].slen+1] %d\n",
1398 bloc[relative_seq].slen+1);
1399 token = strtok(NULL,TOKENS);
1401 /* there is a first residue definition */
1402 firstres = atoi(token);
1403 fprintf(stderr,"First position is number: %d\n",firstres);
1407 if(relative_seq != 0){
1409 for(i=1;i<bloc[1].slen+1;++i){
1410 /* for now assume all gaps are blanks */
1411 if(bloc[relative_seq].seq[i] != ' '){
1416 /* increase the max allowed X value to the max of xmax and k */
1417 /* leave the minimum value at 1 since otherwise we will not be able to mix
1418 absolute and relative numbers without the Check routine skwawking */
1419 if(k > xmax ) xmax = k;
1421 for(i=1;i<bloc[1].slen+1;++i){
1426 fprintf(std_err,"%s",buff);
1427 error("Unrecognised Step 2 command\n",1);
1431 ALReportInfo(nseq,std_err);
1433 ALCheckSinglePage(nseq,bloc[1].slen,silent);
1436 totalpage = npage * Csheet;
1438 /* get how many blocks of sequence we can fit per page */
1439 nspage = Cheight/(nseq+CtopSpace+Vspacing);
1445 if(!silent)fprintf(std_err,"Will write a maximum of %d blocks of sequence per page\n",nspage);
1446 if(!silent)fprintf(std_err,"Background region: %d %d %d %d\n",
1447 background_region[0],
1448 background_region[1],
1449 background_region[2],
1450 background_region[3]);
1451 if(!silent && singlepage)fprintf(std_err,"Bounding box: %d %d %d %d\n",
1459 if((Cwidth - Cidwidth > 0)){
1460 if(!silent)fprintf(std_err,"Saving (%d) Pages to file\n",totalpage/nspage);
1462 fprintf(std_err,"This pointsize is too large to print even a single character on the page\n");
1463 fprintf(std_err,"Try a smaller pointsize - or\n");
1464 fprintf(std_err,"Try reducing the Identifier width\n");
1465 fprintf(std_err,"Increase the paper size\n");
1466 fprintf(std_err,"You could do some PostScrip-ery to print partial characters\n");
1467 fprintf(std_err,"After creating an alignment on a single page - see the CookBook\n");
1474 while(k < totalpage){
1476 Ytemp = start_seq+Cheight-CtopSpace - 1;
1477 if(Ytemp > nseq) Ytemp = nseq;
1478 for(i=0;i<npage;++i){
1480 if(nspage > 1){ /* more than one block per page */
1481 /* fprintf(stderr,"nbp nspage %d %d\n",nbp,nspage);*/
1482 if(k>0 && nbp == 0){ /* if not the first page, then setup page*/
1483 PSSetupPage(orientation,nbpage+1,outf);
1484 if(background_colour != 99){
1485 ALColourBackground(outf,background_colour,background_region);
1489 /* if this is not the first block on the page, then */
1490 /* translate the block of alignment back to origin */
1491 fprintf(outf,"%d %d translate\n",0,-lastY);
1493 /* get new position for drawing and translate to this posn*/
1494 lastY = Yspace*( Cheight-(nseq+CtopSpace)*(nbp+1) - (nbp*Vspacing) );
1495 fprintf(outf,"%d %d translate\n",0,lastY);
1497 if(k>0)PSSetupPage(orientation,k+1,outf);
1498 if(background_colour != 99){
1499 ALColourBackground(outf,background_colour,background_region);
1502 if(id_only_on_first == 1 && nbp > 0 ){
1503 /* save the Cseqwidth, then reset it to Cwidth - also set Cidwidth to 0*/
1504 tempCseqwidth = Cseqwidth;
1505 tempCidwidth = Cidwidth;
1510 Xtemp = start_aa+Cseqwidth-1;
1511 if(Xtemp > bloc[1].slen) Xtemp = bloc[1].slen;
1513 fprintf(outf,"2 setlinecap\n");
1514 fprintf(outf," %.2f setlinewidth\n",LineWidthFactor*pointsize);
1516 ALDrawFills(fills,use_colour,s_colour,start_aa,nseq-Ytemp+1,Xtemp,nseq-start_seq+1,Cidwidth,CseqVoffset,outf);
1517 ALDrawLines(lines,use_colour,
1522 start_aa,nseq-Ytemp+1,Xtemp,nseq-start_seq+1,Cidwidth,CseqVoffset,outf);
1523 if(!(id_only_on_first == 1 && (nbp > 0 || k > 0))){
1524 /* don't output ID string if this is not the first block on the first page*/
1525 ALOutId(bloc,use_colour,
1526 id_colour,idfonts,start_seq,Ytemp,CseqVoffset,number_seqs,outf);
1528 ALOutSeq(bloc,fonts,texts,inverse,use_colour,c_colour,
1529 text_colour,background_colour,start_seq,Ytemp,start_aa,CseqVoffset,outf);
1532 if(use_colour)PSSetColour(number_colour,outf);
1534 ALOutTicks(ticks,start_aa,Cidwidth,Ytemp-start_seq+1,bloc[1].slen,outf);
1535 ALOutNumbers(numbers,start_aa,Cidwidth,Ytemp-start_seq+2,bloc[1].slen,outf);
1537 ALOutNumbers(numbers,start_aa,Cidwidth,Ytemp-start_seq+1,bloc[1].slen,outf);
1540 start_aa += Cseqwidth;
1544 if(nbp == nspage || k == totalpage-1){ /* put showpage command for page or last page */
1554 start_seq = Ytemp + 1;
1555 if(id_only_on_first == 1 && nbp > 0){
1556 /* reset the values - not strictly necessary */
1557 Cseqwidth = tempCseqwidth;
1558 Cidwidth = tempCidwidth;
1564 void ALShadeChars(struct seqdat *bloc,
1566 int start_x,int start_y,int end_x,int end_y,
1571 /* shade residues in charlist by grey value */
1575 for(i=start_x;i<end_x+1;++i){
1576 for(j=start_y,jpos=(maxY-start_y+1);j<end_y+1;++j,--jpos){
1577 if(strchr(charlist,bloc[j].seq[i])!=NULL){
1578 ALFilRes(fill,i,jpos,grey);
1583 void ALSColChars(struct seqdat *bloc,unsigned char **colour,int start_x,
1584 int start_y,int end_x,int end_y,int maxY,char *charlist,unsigned char colnum)
1586 /* colour residue backgrounds in charlist by colnum value */
1590 for(i=start_x;i<end_x+1;++i){
1591 for(j=start_y,jpos=(maxY-start_y+1);j<end_y+1;++j,--jpos){
1592 if(strchr(charlist,bloc[j].seq[i])!=NULL){
1593 ALColRes(colour,i,jpos,colnum);
1599 void ALSColMask(unsigned char **mask,unsigned char **colour,
1600 int start_x,int start_y,int end_x,int end_y,int maxY,
1601 unsigned char colnum)
1603 /* colour residue backgrounds in mask by colnum value */
1607 for(i=start_x;i<end_x+1;++i){
1608 for(j=start_y,jpos=(maxY-start_y+1);j<end_y+1;++j,--jpos){
1610 ALColRes(colour,i,jpos,colnum);
1615 void ALInverseChars(struct seqdat *bloc,unsigned char **inverse,
1616 int start_x,int start_y,int end_x,int end_y,char *charlist)
1618 /* Invert the characters within the range */
1619 /* 18/Jan/93: Allow inverted chars to be reverted */
1623 for(i=start_x;i<end_x+1;++i){
1624 for(j=start_y;j<end_y+1;++j){
1625 if(strchr(charlist,bloc[j].seq[i])!=NULL){
1626 if(inverse[i][j] == 1){
1627 inverse[i][j] = (unsigned char) 0;
1629 inverse[i][j] = (unsigned char ) 1;
1635 void ALInverseMask(unsigned char **mask,unsigned char **inverse,
1636 int start_x,int start_y,int end_x,int end_y)
1637 /* Invert the characters within the range of the mask*/
1638 /* 18/Jan/93: Allow inverted chars to be reverted */
1642 for(i=start_x;i<end_x+1;++i){
1643 for(j=start_y;j<end_y+1;++j){
1645 if(inverse[i][j] == 1){
1646 inverse[i][j] = (unsigned char) 0;
1648 inverse[i][j] = (unsigned char ) 1;
1655 void ALFontChars(struct seqdat *bloc,unsigned char **fonts,
1656 int start_x,int start_y,int end_x,int end_y,char *charlist,unsigned char fontnum)
1658 /* set the characters within the range to the fontnum */
1662 for(i=start_x;i<end_x+1;++i){
1663 for(j=start_y;j<end_y+1;++j){
1664 if(strchr(charlist,bloc[j].seq[i])!=NULL){
1665 fonts[i][j] = fontnum;
1670 void ALFontRegion(unsigned char **fonts,
1671 int start_x,int start_y,int end_x,int end_y,
1672 unsigned char fontnum)
1673 /* set the characters within the range to the fontnum */
1677 for(i=start_x;i<end_x+1;++i){
1678 for(j=start_y;j<end_y+1;++j){
1679 fonts[i][j] = fontnum;
1683 void ALFontMask(unsigned char **mask,unsigned char **fonts,
1684 int start_x,int start_y,int end_x,int end_y,
1685 unsigned char fontnum)
1687 /* set the characters within the range to the fontnum */
1691 for(i=start_x;i<end_x+1;++i){
1692 for(j=start_y;j<end_y+1;++j){
1694 fonts[i][j] = fontnum;
1700 void ALColourChars(struct seqdat *bloc,unsigned char **colour,
1701 int start_x,int start_y,int end_x,int end_y,
1702 char *charlist,unsigned char colournum)
1704 /* set the characters within the range to the colour defined by colournum */
1708 for(i=start_x;i<end_x+1;++i){
1709 for(j=start_y;j<end_y+1;++j){
1710 if(strchr(charlist,bloc[j].seq[i])!=NULL){
1711 colour[i][j] = colournum;
1716 void ALColourRegion(unsigned char **colour,
1717 int start_x,int start_y,int end_x,int end_y,
1718 unsigned char colournum)
1720 /* set the characters within the range to the colournum */
1724 for(i=start_x;i<end_x+1;++i){
1725 for(j=start_y;j<end_y+1;++j){
1726 colour[i][j] = colournum;
1731 void ALColourMask(unsigned char **mask,unsigned char **colour,
1732 int start_x,int start_y,int end_x,int end_y,
1733 unsigned char colournum)
1735 /* set the characters within the range to the colournum */
1739 for(i=start_x;i<end_x+1;++i){
1740 for(j=start_y;j<end_y+1;++j){
1741 if(mask[i][j] == 1){
1742 colour[i][j] = colournum;
1749 void ALSubChars(struct seqdat *bloc,
1750 int start_x,int start_y,int end_x,int end_y,
1751 char oldchar,char newchar)
1753 /* substitute oldchar for newchar at each position in bloc */
1757 for(i=start_x;i<end_x+1;++i){
1758 for(j=start_y;j<end_y+1;++j){
1759 if(bloc[j].seq[i] == oldchar) bloc[j].seq[i] = newchar;
1765 void ALSurroundChars(struct seqdat *bloc,unsigned char **lines,
1766 int start_x,int start_y,int end_x,int end_y,
1767 int maxY,char *charlist)
1770 within the range of start_x etc. Draw lines such that every character that
1771 is present within charlist is surrounded by a box.
1775 char above,below,left,right;
1777 for(i=start_x;i<end_x+1;++i){
1778 for(j=start_y,jpos=(maxY-start_y+1);j<end_y+1;++j,--jpos){
1779 if(strchr(charlist,bloc[j].seq[i]) != NULL){
1780 /* fprintf(std_err,"%d %d %c %c\n",i,j,bloc[j].seq[i]*/
1784 below = bloc[j+1].seq[i];
1789 above = bloc[j-1].seq[i];
1794 left = bloc[j].seq[i-1];
1799 right = bloc[j].seq[i+1];
1802 if(strchr(charlist,above)== NULL){
1803 ALLineRes(lines,i,jpos,LINE_TOP);
1805 if(strchr(charlist,below)== NULL){
1806 ALLineRes(lines,i,jpos,LINE_BOTTOM);
1808 if(strchr(charlist,left)==NULL){
1809 ALLineRes(lines,i,jpos,LINE_LEFT);
1811 if(strchr(charlist,right)==NULL){
1812 ALLineRes(lines,i,jpos,LINE_RIGHT);
1818 void ALSurroundMask(unsigned char **mask,struct seqdat *bloc,unsigned char **lines,
1819 int start_x,int start_y,int end_x,int end_y,
1822 within the range of start_x etc. Draw lines such that every
1823 masked position is isolated from every non-masked position
1827 char above,below,left,right;
1829 /* fprintf(stdout,"ALSurroundMask: %d %d %d %d\n",start_x,start_y,end_x,end_y);*/
1831 for(i=start_x;i<end_x+1;++i){
1832 for(j=start_y,jpos=(maxY-start_y+1);j<end_y+1;++j,--jpos){
1833 if(mask[i][j] == 1){
1834 /* fprintf(std_err,"%d %d %c %c\n",i,j,bloc[j].seq[i]*/
1838 below = mask[i][j+1];
1843 above = mask[i][j-1];
1848 left = mask[i-1][j];
1853 right = mask[i+1][j];
1856 fprintf(stdout,"IN ALSurroundMask\n");
1857 fprintf(stdout,"%d %d (%d %d %d %d)\n",i,j,above,below,left,right);
1860 if(mask[i][j] != above){
1861 ALLineRes(lines,i,jpos,LINE_TOP);
1863 if(mask[i][j] != below){
1864 ALLineRes(lines,i,jpos,LINE_BOTTOM);
1866 if(mask[i][j] != left){
1867 ALLineRes(lines,i,jpos,LINE_LEFT);
1869 if(mask[i][j] != right){
1870 ALLineRes(lines,i,jpos,LINE_RIGHT);
1877 void ALFilRegion(signed char **fill,
1878 int start_x,int start_y,int end_x,int end_y,
1879 int *Yindx,float grey)
1882 for(i=start_x;i<end_x+1;++i){
1883 for(j=start_y;j<end_y+1;++j){
1884 ALFilRes(fill,i,Yindx[j],grey);
1889 void ALShadeMask(unsigned char **mask,signed char **fill,
1890 int start_x,int start_y,int end_x,int end_y,int *Yindx,
1895 for(i=start_x;i<end_x+1;++i){
1896 for(j=start_y;j<end_y+1;++j){
1898 ALFilRes(fill,i,Yindx[j],grey);
1905 void ALColRegion(unsigned char **colour,
1906 int start_x,int start_y,int end_x,int end_y,
1907 int *Yindx,unsigned char colnum)
1910 for(i=start_x;i<end_x+1;++i){
1911 for(j=start_y;j<end_y+1;++j){
1912 ALColRes(colour,i,Yindx[j],colnum);
1917 void ALColRRegion(unsigned char **colour,
1918 int start_x,int start_y,int end_x,int end_y,
1919 unsigned char colnum)
1920 /* version of ALColRegion that is indexed by characters rather than position */
1925 for(i=start_x;i<end_x+1;++i){
1926 for(j=start_y;j<end_y+1;++j){
1927 colour[i][j] = colnum;
1932 void ALBoxRegion(unsigned char **lines,
1933 int start_x,int start_y,int end_x,int end_y,
1937 for(i=start_x;i<end_x+1;++i){
1938 ALLineRes(lines,i,Yindx[end_y],LINE_BOTTOM);
1939 ALLineRes(lines,i,Yindx[start_y],LINE_TOP);
1941 for(i=start_y;i<end_y+1;++i){
1942 ALLineRes(lines,start_x,Yindx[i],LINE_LEFT);
1943 ALLineRes(lines,end_x,Yindx[i],LINE_RIGHT);
1946 void ALDoLine(unsigned char **lines,
1947 int start_x,int start_y,int end,
1948 int type,int *Yindx)
1951 if(type == LINE_TOP || type == LINE_BOTTOM){
1952 for(i=start_x;i<end+1;++i){
1953 ALLineRes(lines,i,Yindx[start_y],type);
1956 for(i=start_y;i<end+1;++i){
1957 ALLineRes(lines,start_x,Yindx[i],type);
1964 void ALDrawFills(signed char **fill,int use_colour,unsigned char **colour,
1965 int start_x,int start_y,int end_x,int end_y,int XOffset,int YOffset,FILE *outf)
1967 /* for values of fill >= 0 draw box and fill in with grey value */
1968 /* 6/12/92: add colour option */
1976 for(i=end_x;i>(start_x-1);--i){
1977 for(j=end_y;j>(start_y-1);--j){
1978 if((int) fill[i][j] >= 0 || use_colour){
1981 Revise to use ML function 27th Oct 1992
1982 fprintf(outf," newpath\n");
1983 fprintf(outf,"%.2f %.2f moveto \n",(float)(i-start_x)*Xspace-Xshift+XOffset,
1984 (float)(j-start_y+1)*Yspace-Yshift+YOffset);
1985 fprintf(outf,"%.2f %.2f lineto \n",(float)(i-start_x)*Xspace-Xshift+XOffset,
1986 (float)(j-start_y+0)*Yspace-Yshift+YOffset);
1987 fprintf(outf,"%.2f %.2f lineto \n",(float)(i-start_x+1)*Xspace-Xshift+XOffset,
1988 (float)(j-start_y+0)*Yspace-Yshift+YOffset);
1989 fprintf(outf,"%.2f %.2f lineto \n",(float)(i-start_x+1)*Xspace-Xshift+XOffset,
1990 (float)(j-start_y+1)*Yspace-Yshift+YOffset);
1991 fprintf(outf,"%.2f %.2f lineto \n",(float)(i-start_x)*Xspace-Xshift+XOffset,
1992 (float)(j-start_y+1)*Yspace-Yshift+YOffset);
1993 fprintf(outf,"closepath %.2f setgray fill 0 setgray \n",(float)fill[i][j]/(float)precis);
1995 fprintf(outf," newpath\n");
1996 fprintf(outf,"%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f ML\n",
1997 (float)(i-start_x)*Xspace-Xshift+XOffset,
1998 (float)(j-start_y+1)*Yspace-Yshift+YOffset,
1999 (float)(i-start_x)*Xspace-Xshift+XOffset,
2000 (float)(j-start_y+0)*Yspace-Yshift+YOffset,
2001 (float)(i-start_x+1)*Xspace-Xshift+XOffset,
2002 (float)(j-start_y+0)*Yspace-Yshift+YOffset,
2003 (float)(i-start_x+1)*Xspace-Xshift+XOffset,
2004 (float)(j-start_y+1)*Yspace-Yshift+YOffset,
2005 (float)(i-start_x)*Xspace-Xshift+XOffset,
2006 (float)(j-start_y+1)*Yspace-Yshift+YOffset);
2007 if(use_colour && fill[i][j] < 0){
2008 /* 6/1/1995 - only set colour if grey is not set */
2009 /* set to colour number */
2010 fprintf(outf,"closepath C%-d fill \n",colour[i][j]);
2012 fprintf(outf,"closepath %.2f setgray fill 0 setgray \n",(float)fill[i][j]/(float)precis);
2019 void ALFilRes(signed char **fill,int i,int j,float grey)
2023 /* ALBoxRes(lines,i,j);
2024 fill[i+Cidwidth][j+CseqVoffset] = grey * precis;
2026 fill[i][j] = grey * precis;
2029 void ALColRes(unsigned char **colour,int i,int j,int colnum)
2032 colour[i][j] = colnum;
2036 void ALBoxRes(unsigned char **lines,int i,int j)
2039 ALLineRes(lines,i,j,LINE_TOP);
2040 ALLineRes(lines,i,j,LINE_BOTTOM);
2041 ALLineRes(lines,i,j,LINE_LEFT);
2042 ALLineRes(lines,i,j,LINE_RIGHT);
2047 unsigned char **lines,
2049 unsigned char value)
2053 j = j + CseqVoffset;
2055 ALLineChar(lines,i,j,value);
2058 void ALLineChar(unsigned char **lines,int i,int j,unsigned char value)
2061 lines[i][j] = lines[i][j] | value;
2064 void ALDrawLines(unsigned char **lines,int use_colour,
2065 unsigned char **left_line_colour,
2066 unsigned char **right_line_colour,
2067 unsigned char **top_line_colour,
2068 unsigned char **bottom_line_colour,
2069 int start_x,int start_y,int end_x,int end_y,
2070 int XOffset,int YOffset,FILE *outf)
2072 /* draw the lines that are indicated by the lines array in the range of the
2073 array indicated by start_x etc
2082 fprintf(outf,"C100\n");
2086 for(i=end_x;i>(start_x-1);--i){
2087 for(j=end_y;j>(start_y-1);--j){
2088 if(lines[i][j] != 0){
2089 if((LINE_LEFT & lines[i][j]) == LINE_LEFT){
2090 PSSetColour(left_line_colour[i][j],outf);
2091 PSline((float)(i-start_x)*Xspace-Xshift+XOffset,
2092 (float)(j-start_y+1)*Yspace-Yshift+YOffset,
2093 (float)(i-start_x)*Xspace-Xshift+XOffset,
2094 (float)(j-start_y+0)*Yspace-Yshift+YOffset,outf);
2096 if((LINE_RIGHT & lines[i][j]) == LINE_RIGHT){
2097 PSSetColour(right_line_colour[i][j],outf);
2098 PSline((float)(i-start_x+1)*Xspace-Xshift+XOffset,
2099 (float)(j-start_y+1)*Yspace-Yshift+YOffset,
2100 (float)(i-start_x+1)*Xspace-Xshift+XOffset,
2101 (float)(j-start_y+0)*Yspace-Yshift+YOffset,outf);
2103 if((LINE_TOP & lines[i][j]) == LINE_TOP){
2104 PSSetColour(top_line_colour[i][j],outf);
2105 PSline((float)(i-start_x)*Xspace-Xshift+XOffset,
2106 (float)(j-start_y+1)*Yspace-Yshift+YOffset,
2107 (float)(i-start_x+1)*Xspace-Xshift+XOffset,
2108 (float)(j-start_y+1)*Yspace-Yshift+YOffset,outf);
2110 if((LINE_BOTTOM & lines[i][j]) == LINE_BOTTOM){
2111 PSSetColour(bottom_line_colour[i][j],outf);
2112 PSline((float)(i-start_x)*Xspace-Xshift+XOffset,
2113 (float)(j-start_y+0)*Yspace-Yshift+YOffset,
2114 (float)(i-start_x+1)*Xspace-Xshift+XOffset,
2115 (float)(j-start_y+0)*Yspace-Yshift+YOffset,outf);
2122 fprintf(outf,"C99\n");
2127 void PSline(float x1,float y1,float x2,float y2,FILE *outf)
2130 fprintf(outf,"%.2f %.2f %.2f %.2f L\n ",x1,y1,x2,y2);
2135 void ALSimpleBox(int x1,int y1,int x2,int y2,float pfactor, /* multiply pointsize by this to get linewidth */
2138 /* draw a box to include character coordinates x1,y1 to x2,y2 */
2139 /* x1 < x2 y1< y2 */
2141 float lshift = Xspace/6;
2142 float rshift = Xspace - lshift;
2153 PSDrawBox((float)x1,(float)y1,(float)x2,(float)y2,pfactor,outf);
2156 void PSDrawBox(float x1,float y1,float x2,float y2,float pfactor,FILE *out)
2159 fprintf(out,"%f setlinewidth\n ",pointsize*pfactor);
2160 fprintf(out,"%f %f moveto %f %f lineto %f %f lineto %f %f lineto %f %f lineto closepath stroke\n",
2161 x1,y1,x2,y1,x2,y2,x1,y2,x1,y1);
2164 void ALOutTicks(char *array,int start_aa,int xpos,int ypos,int len,FILE *out)
2173 right = start_aa + Cseqwidth;
2174 if(right > len)right = len;
2175 for(j=start_aa;j<right;j++){
2176 if(array[j] != '\0'){
2177 PSPutChar(xpos,ypos,array[j],out);
2183 void ALOutNumbers(char **array,int start_aa,int xpos,int ypos,int len,FILE *out)
2192 right = start_aa + Cseqwidth;
2193 if(right > len)right = len;
2194 for(j=start_aa;j<right;j++){
2195 if(array[j][0] != '\0'){
2196 PSPutText(xpos,ypos,array[j],out);
2202 char *ALCreateTicks(int start, int interval, int len)
2204 /* create ticks at the desired interval starting with residue start */
2208 temp = (char *) malloc(sizeof(char) * len);
2209 /* first set all ticks to '\0' */
2213 for(i=0;i<len;i+=interval){
2223 char **ALCreateNumbers(int start,int interval,int nres,int nwidth)
2225 /* create character array of numbers from start to nres at interval*/
2229 temp = (char **) malloc(nres*sizeof(char *));
2230 for(i=0;i<nres;++i){
2231 temp[i] = (char *) malloc(sizeof(char) *nwidth);
2234 for(i=start;i<nres;i+=interval){
2236 sprintf(temp[i+1],"%-d",i+1);
2238 sprintf(temp[i],"%-d",i);
2245 char **ALCreateNum2(
2246 int nstart, /* starting number */
2247 int ninterval, /* interval for numbers */
2248 int nend, /* end of number range */
2249 int nres, /* total length of sequence */
2250 int xstart, /* starting location for writing numbers */
2251 int nwidth) /* width of the number string */
2253 /* create character array of numbers from start to nres at interval*/
2257 temp = (char **) malloc(nres*sizeof(char *));
2258 for(i=0;i<nres;++i){
2259 temp[i] = (char *) malloc(sizeof(char) *nwidth);
2263 for(i=nstart;i<nend;i+=ninterval){
2265 sprintf(temp[xp+1],"%-d",i+1);
2267 sprintf(temp[xp],"%-d",i);
2275 void ALReportInfo(int nseq,FILE *out)
2278 fprintf(out,"Number of Sequences: %d\n",nseq);
2279 fprintf(out,"Total Vertical Space per page: %d\n",Cheight);
2282 void ALReserveSpace(int location,int nspace)
2285 extern int TVspace,CseqVoffset;
2294 CseqVoffset += nspace;
2295 CbottomSpace += nspace;
2300 void PSSetupPage(int orientation,int npage,FILE *outf)
2303 fprintf(outf,"%%%%Page: ? %d\n",npage);
2304 PSSetOrientation(orientation,outf);
2305 PSSetFont(0,outf); /* set default font for document */
2308 void ALOutSeq(struct seqdat *bloc,unsigned char **fonts,char ***texts,unsigned char **inverse,
2310 unsigned char **colour,
2311 unsigned char **text_colour,
2312 unsigned char background_colour,
2313 int start_seq,int end_seq,int start_aa,int ypos,FILE *outf)
2316 extern int Xspace,Yspace;
2317 extern int Cidwidth;
2321 unsigned char current_col;
2327 current_col = background_colour;
2329 right = start_aa + Cseqwidth;
2330 if(right > bloc[1].slen-1)right = bloc[1].slen;
2332 for(i=end_seq;i>(start_seq-1);--i){
2333 xpos = Cidwidth * Xspace;
2334 for(j=start_aa;j<right;++j){
2335 if(texts[j][i] != NULL || bloc[i].seq[j] != ' '){
2336 if(fonts[j][i]!=0)PSSetFont(fonts[j][i],outf);
2337 if(inverse[j][i] != 0)PSSetGrey(1,outf);
2338 if(use_colour && colour[j][i] != current_col){
2339 PSSetColour(colour[j][i],outf);
2340 current_col = colour[j][i];
2342 if(bloc[i].seq[j] != ' '){
2343 PSPutChar(xpos,ypos,bloc[i].seq[j],outf);
2345 if(texts[j][i] != NULL){
2346 if(text_colour[j][i] != current_col){
2347 PSSetColour(text_colour[j][i],outf);
2348 current_col = text_colour[j][i];
2350 if(texts[j][i][0] == '@'){
2351 PSPutSpecialText(xpos,ypos,Xspace,Yspace,texts[j][i],
2352 text_colour[j][i],background_colour,0.9,outf);
2354 PSPutText(xpos,ypos,texts[j][i],outf);
2357 if(inverse[j][i] != 0)PSSetGrey(0,outf);
2358 if(fonts[j][i]!=0)PSSetFont(0,outf);
2366 PSSetColour(100,outf);
2372 void ALOutId(struct seqdat *bloc,int use_colour,
2373 unsigned char *colour,
2374 unsigned char *fonts,
2375 int start_seq,int end_seq,int ypos,int numbers,
2380 extern int Xspace,Yspace;
2387 temp = (char *) malloc(sizeof(char) * (MAXilen + 5));
2390 for(i=end_seq;i>(start_seq-1);--i){
2391 if(use_colour)PSSetColour(colour[i],outf);
2392 if(fonts[i] != 0)PSSetFont(fonts[i],outf);
2394 sprintf(temp,"%4d:%s",i,bloc[i].id);
2396 sprintf(temp,"%s",bloc[i].id);
2398 PSPutText(xpos,ypos,temp,outf);
2400 if(fonts[i] != 0)PSSetFont(0,outf);
2402 free((char *) temp);
2406 void PSPutText(int x,int y,char *text,FILE *outf)
2409 fprintf(outf," %d %d moveto (%s) show \n",x,y,text);
2412 void PSPutChar(int x,int y,char c,FILE *outf)
2415 /* fprintf(outf," %d %d moveto (%c) show \n",x,y,c);*/
2416 fprintf(outf,"(%c) %d %d P\n",c,x,y);
2419 void PSShowPage(FILE *outf)
2422 fprintf(outf,"showpage\n");
2425 void ALSetFont(char *font,int point,FILE *outf)
2428 fprintf(outf,"/%s findfont %d scalefont setfont\n",font,point);
2431 void PSSetFont(unsigned char number,FILE *outf)
2434 fprintf(outf,"F%-d\n ",number);
2437 void PSSetColour(unsigned char number,FILE *outf)
2440 fprintf(outf,"C%-d\n ",number);
2443 void ALDefineFont(int number,char *font,float point,FILE *outf)
2445 /* define a PostScript function called /Fnumber which selects the
2446 font at point pointsize */
2448 fprintf(outf,"/F%-d {/%s findfont %.2f scalefont setfont } def\n",
2452 void ALDefineColour(int number,char *type,float red,float green,float blue,FILE *outf)
2454 /* define a PostScript function called /Cnumber which selects the
2455 colour defined by red,green, blue intensities
2457 new addition - if type is equal to "HSB" then define an hsb colour using red, green blue as
2458 the hue saturation and brightness.
2461 if(strcmp(type,"HSB")==0){
2462 /* set an HSB colour */
2463 fprintf(outf,"/C%-d {%f %f %f sethsbcolor } def\n", number,red,green,blue);
2465 /* set an RGB colour */
2466 fprintf(outf,"/C%-d {%f %f %f setrgbcolor } def\n", number,red,green,blue);
2470 void ALCheckSinglePage(int nseq,int len,int silent)
2473 extern FILE *std_err;
2477 if(Cheight-CtopSpace < nseq){
2478 if(!silent)fprintf(std_err,"Not enough height to print all sequences on a single page at this pointsize\n");
2479 if(!silent)fprintf(std_err,"Pointsize: %.2f\n",pointsize);
2480 if(!silent)fprintf(std_err,"Need a pointsize of < : %.2f\n",(float) height/(nseq+ CtopSpace));
2481 Csheet = nseq/(Cheight-CtopSpace) + 1;
2482 if(!silent)fprintf(std_err,"Will split alignment into %d segments\n",Csheet);
2485 npage = len/(Cwidth - Cidwidth) + 1;
2489 void ALSetPageLimits(void)
2490 /* Use the current width height and pointsize values to calculate:
2498 Xspace = pointsize + pointsize * XspaceFactor;
2499 Yspace = pointsize + pointsize * YspaceFactor;
2501 Cwidth = width/Xspace;
2502 Cheight = height/Yspace;
2504 Cseqwidth = Cwidth - Cidwidth;
2506 Xshift = Xspace * XshiftFactor;
2507 Yshift = Yspace * YshiftFactor;
2510 void PSSetOrientation(int orientation,FILE *outf)
2513 switch(orientation){
2525 void PSPreamble(FILE *out,int singlepage,int *b_box,int screensize)
2527 char *Alscript_Version = ALSCRIPT_VERSION;
2528 fprintf(out,"%%!PS-Adobe-2.0\n");
2529 fprintf(out,"%%%%Creator: %s\n",Alscript_Version);
2530 fprintf(out,"%%%%Title: Alscript Output\n");
2531 fprintf(out,"%% Barto,n G. J. (1993)\n");
2532 fprintf(out,"%% ALSCRIPT - A Tool to format multiple sequence alignments\n");
2533 fprintf(out,"%% Protein Engineering, 6, 37-40\n");
2534 fprintf(out,"%%\n");
2535 if(singlepage == 1){
2536 fprintf(out,"%%%%BoundingBox: %d %d %d %d\n",
2537 b_box[0],b_box[1],b_box[2],b_box[3]);
2539 fprintf(out,"/P {moveto show} def\n");
2540 fprintf(out,"/L {moveto lineto stroke} def\n");
2542 "/ML {moveto lineto lineto lineto lineto} def\n");
2543 fprintf(out,"2 setlinecap\n"); /* projecting line caps */
2544 ALDefineColour(99,"RGB",1.0,1.0,1.0,out); /* white */
2545 ALDefineColour(100,"RGB",0.0,0.0,0.0,out); /* black */
2546 /* modify the screening - suggested by Michael D. Baron */
2547 fprintf(out,"%d currentscreen 3 -1 roll pop setscreen\n",screensize);
2551 void PSLandscape(FILE *out)
2557 fprintf(out,"%d %d translate\n",xoff+height,yoff);
2558 fprintf(out,"90 rotate\n");
2562 void PSPortrait(FILE *out)
2567 fprintf(out,"%d %d translate\n",xoff,yoff);
2574 extern FILE *std_err;
2575 fprintf(std_err,"%s",s);
2578 void ALGetFourInt(int *sx,int *sy,int *ex,int *ey)
2583 token = strtok(NULL,TOKENS);
2585 token = strtok(NULL,TOKENS);
2587 token = strtok(NULL,TOKENS);
2589 token = strtok(NULL,TOKENS);
2592 void ALGetThreeInt(int *sy,int *ex,int *ey)
2597 token = strtok(NULL,TOKENS);
2599 token = strtok(NULL,TOKENS);
2601 token = strtok(NULL,TOKENS);
2604 void ALGetTwoInt(int *sy,int *ex)
2609 token = strtok(NULL,TOKENS);
2611 token = strtok(NULL,TOKENS);
2615 char ALChekSpace(const char *token)
2617 if(strcmp(token,"SPACE") == 0){
2624 void PSSetGrey(float grey,FILE *outf)
2626 fprintf(outf," %.2f setgray\n",grey);
2629 int save_pir(struct seqdat *bloc,int nseq,FILE *pirf)
2636 for(i=1;i<(nseq+1);++i){
2637 fprintf(pirf,">P1;%s\n",bloc[i].id);
2638 fprintf(pirf,"%s\n",bloc[i].title);
2640 for(j=1;j<bloc[i].slen;++j){
2642 /* convert spaces to dashes */
2643 if(bloc[i].seq[j] == ' ')bloc[i].seq[j] = '.';
2644 fputc(bloc[i].seq[j],pirf);
2650 fprintf(pirf,"*\n");
2655 int save_msf(struct seqdat *bloc,int nseq,FILE *msff)
2661 fprintf(msff,"\njunk.msf MSF: %d Type: P January 01, 1776 12:00 Check: 7110 ..\n\n",bloc[1].slen-1);
2663 for(i=1;i<(nseq+1);++i){
2664 fprintf(msff,"Name: %20s Len: %7d Check: 0 Weight: 1.00\n",
2665 bloc[i].id,bloc[1].slen-1);
2667 fprintf(msff,"\n//\n\n\n");
2672 while(s < bloc[1].slen){
2674 if(e > bloc[1].slen) e = bloc[1].slen;
2676 for(i=1;i<(nseq+1);++i){
2677 fprintf(msff,"%10s ",bloc[i].id);
2679 if(bloc[i].seq[j] == ' ')bloc[i].seq[j]='.';
2680 fputc(bloc[i].seq[j],msff);
2685 fprintf(msff,"\n\n");
2691 void ALGetAllRange(int *sx, int *sy, int *ex, int *ey,int dex,int dey)
2692 /* checks the next token if it is ALL then return box around whole alignment
2693 else return box according to the integers found
2698 token = strtok(NULL,TOKENS);
2700 if(strcmp(token,"ALL")==0){
2707 ALGetThreeInt(sy,ex,ey);
2709 if(*ex > dex) *ex = dex;
2710 if(*ey > dey) *ey = dey;
2714 unsigned char **mask,
2715 struct seqdat *bloc,
2716 int sx,int sy,int ex,int ey,
2724 char *seen; /* array of characters that are seen at this position */
2725 int *freq; /* array of frequencies of the characters */
2726 int nc; /* number of different character types at this position */
2728 int mc; /* maximum character present */
2729 int imc; /* location of max character */
2734 seen = (char *) GJmalloc(sizeof(char) *ns);
2735 freq = (int *) GJmalloc(sizeof(int) *ns);
2742 /* fprintf(stdout,"In ALidmask\n");*/
2744 for(i=sx;i<(ex+1);++i){
2745 /* for each position get the list of characters seen and their frequencies */
2746 for(j=sy;j<(ey+1);++j){
2747 iseen = Ifound(bloc,i,j,seen,nc);
2751 seen[nc] = bloc[j].seq[i];
2757 for(k=0;k<nc;++k)fprintf(stdout,"%c ",seen[k]);
2758 for(k=0;k<nc;++k)fprintf(stdout,"%d ",freq[k]);
2759 fprintf(stdout,"\n");
2761 /* find the most frequent character that is legal and not illegal*/
2764 if(legal != NULL && illegal != NULL){
2765 if( strchr(legal,seen[k]) != NULL
2766 && strchr(illegal,seen[k]) == NULL
2771 }else if(legal != NULL){
2772 if( strchr(legal,seen[k]) != NULL
2777 }else if(illegal != NULL){
2778 if( strchr(illegal,seen[k]) == NULL
2791 /* only select the character if it is >= id_cut */
2793 /* fprintf(stdout,"At %d %c\n",i,fchar);*/
2794 for(j=sy;j<(ey+1);++j){
2795 if(bloc[j].seq[i] == fchar){
2797 /* fprintf(stdout,"%d %d \n",i,j);*/
2812 unsigned char **mask,
2813 struct seqdat *bloc,
2814 int sx,int sy,int ex,int ey,
2821 char *seen; /* array of characters that are seen at this position */
2822 int *freq; /* array of frequencies of the characters */
2823 int nc; /* number of different character types at this position */
2825 int mc; /* maximum character present */
2826 int imc; /* location of max character */
2831 seen = (char *) GJmalloc(sizeof(char) *ns);
2832 freq = (int *) GJmalloc(sizeof(int) *ns);
2839 /* fprintf(stdout,"In ALidmask\n");*/
2841 for(i=sx;i<(ex+1);++i){
2842 /* for each position get the list of characters seen and their frequencies */
2843 for(j=sy;j<(ey+1);++j){
2844 iseen = Ifound(bloc,i,j,seen,nc);
2848 seen[nc] = bloc[j].seq[i];
2853 /* for(k=0;k<nc;++k)fprintf(stdout,"%c ",seen[k]);
2854 for(k=0;k<nc;++k)fprintf(stdout,"%d ",freq[k]);
2855 fprintf(stdout,"\n");
2857 /* find the most frequent character that is legal and not illegal*/
2860 if(legal != NULL && illegal != NULL){
2861 if( strchr(legal,seen[k]) != NULL
2862 && strchr(illegal,seen[k]) == NULL
2867 }else if(legal != NULL){
2868 if( strchr(legal,seen[k]) != NULL
2873 }else if(illegal != NULL){
2874 if( strchr(illegal,seen[k]) == NULL
2887 /* fprintf(stdout,"At %d %c\n",i,fchar);*/
2888 for(j=sy;j<(ey+1);++j){
2889 if(bloc[j].seq[i] == fchar){
2891 /* fprintf(stdout,"%d %d \n",i,j);*/
2904 int Ifound(struct seqdat *bloc,
2913 if(bloc[j].seq[i] == seen[k]){
2921 unsigned char **mask,
2922 struct seqdat *bloc,
2923 int sx,int sy,int ex,int ey,
2929 for(i=sx;i<(ex+1);++i){
2930 /* for each position mask the characters that are identical to sequence ns */
2931 for(j=sy;j<(ey+1);++j){
2932 if(bloc[j].seq[i] == bloc[ns].seq[i]){
2940 unsigned char **mask,
2941 int sx,int sy,int ex,int ey)
2946 for(i=sx;i<(ex+1);++i){
2947 /* NOT on each mask element ie 1 goes to 0, 0 to 1 */
2948 for(j=sy;j<(ey+1);++j){
2951 }else if(mask[i][j]==0){
2959 void ALsub_mask(unsigned char **mask,struct seqdat *bloc,
2960 int sx,int sy,int ex,int ey,char cchar)
2965 for(i=sx;i<(ex+1);++i){
2966 /* substitute all characters in the mask for cchar */
2967 for(j=sy;j<(ey+1);++j){
2969 bloc[j].seq[i] = cchar;
2975 void ALMask(unsigned char **mask,
2976 int sx,int sy,int ex,int ey)
2981 for(i=sx;i<(ex+1);++i){
2982 /* substitute all characters in the mask for cchar */
2983 for(j=sy;j<(ey+1);++j){
2989 void ALConsMask(unsigned char **mask,
2990 int sx,int sy,int ex,int ey,int *consval,int conscut)
2995 for(i=sx;i<(ex+1);++i){
2996 /* set mask at all positions that are >= conscut in the consval array */
2997 for(j=sy;j<(ey+1);++j){
2998 if(consval[i] >= conscut){
3006 void ALDrawHorizLine(
3007 float Xpos, /* bottom left hand corner of character posn */
3009 float Xspace, /* horizontal width of character position */
3010 float Yspace, /* vertical height of character position */
3011 float width_fac,FILE *outf) /* proportion of vertical height that the line will fill */
3019 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3020 ytop = Ypos + Yspace; /* top edge of character */
3021 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3023 /* width_fac defines the width of the line in terms of the height of the characters */
3025 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3027 fprintf(outf,"%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f ML\n",
3029 xright,ymid-hline_w,
3030 xright,ymid+hline_w,
3032 Xpos,ymid-hline_w,outf);
3035 void ALDrawRightArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3042 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3043 ytop = Ypos + Yspace; /* top edge of character */
3044 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3046 /* width_fac defines the width of the Arrow in terms of the height of the characters */
3048 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3050 PSmoveto(Xpos,Ypos,outf);
3051 PSlineto(xright,ymid,outf);
3052 PSlineto(Xpos,ytop,outf);
3053 PSlineto(Xpos,Ypos,outf);
3057 void ALDrawLeftArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3064 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3065 ytop = Ypos + Yspace; /* top edge of character */
3066 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3068 /* width_fac defines the width of the Arrow in terms of the height of the characters */
3070 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3072 PSmoveto(xright,Ypos,outf);
3073 PSlineto(xright,ytop,outf);
3074 PSlineto(Xpos,ymid,outf);
3075 PSlineto(xright,Ypos,outf);
3079 void ALDrawUpArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3087 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3088 ytop = Ypos + Yspace; /* top edge of character */
3089 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3090 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3092 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3094 PSmoveto(Xpos,Ypos,outf);
3095 PSlineto(xright,Ypos,outf);
3096 PSlineto(xmid,ytop,outf);
3097 PSlineto(Xpos,Ypos,outf);
3100 void ALDrawDownArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3108 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3109 ytop = Ypos + Yspace; /* top edge of character */
3110 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3111 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3113 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3115 PSmoveto(Xpos,ytop,outf);
3116 PSlineto(xright,ytop,outf);
3117 PSlineto(xmid,Ypos,outf);
3118 PSlineto(Xpos,ytop,outf);
3121 /* Draw a small up arrow. mok 980917 */
3122 void ALDrawSmallUpArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3130 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3131 ytop = Ypos + Yspace; /* top edge of character */
3132 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3133 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3135 PSmoveto(xmid, ytop, outf);
3136 x = Xpos + (xright-Xpos)/5.0; y = Ypos + 2.0*(ytop-Ypos)/3.0;
3138 x = Xpos + 2.0*(xright-Xpos)/5.0;
3139 PSlineto(x, y, outf);
3140 PSlineto (x, Ypos, outf);
3141 x = Xpos + 3.0*(xright-Xpos)/5.0;
3142 PSlineto (x, Ypos, outf);
3143 PSlineto(x, y, outf);
3144 x = Xpos + 4.0*(xright-Xpos)/5.0;
3145 PSlineto(x, y, outf);
3146 PSlineto(xmid, ytop, outf);
3149 /* Draw a small down arrow. mok 980917 */
3150 void ALDrawSmallDownArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3158 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3159 ytop = Ypos + Yspace; /* top edge of character */
3160 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3161 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3163 PSmoveto(xmid, Ypos, outf);
3164 x = Xpos + 4.0*(xright-Xpos)/5.0; y = Ypos + (ytop-Ypos)/3.0;
3166 x = Xpos + 3.0*(xright-Xpos)/5.0;
3167 PSlineto(x, y, outf);
3168 PSlineto (x, ytop, outf);
3169 x = Xpos + 2.0*(xright-Xpos)/5.0;
3170 PSlineto (x, ytop, outf);
3171 PSlineto(x, y, outf);
3172 x = Xpos + (xright-Xpos)/5.0;
3173 PSlineto(x, y, outf);
3174 PSlineto(xmid, Ypos, outf);
3177 void ALDrawCircle(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3185 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3186 ytop = Ypos + Yspace; /* top edge of character */
3187 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3188 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3190 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3194 fprintf(outf,"%.2f %.2f %.2f %d %d arc\n",xmid,ymid,(ytop - Ypos)*0.5,0,360);
3198 /* Draw a diamond. mok 980917 */
3199 void ALDrawDiamond(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3207 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3208 ytop = Ypos + Yspace; /* top edge of character */
3209 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3210 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3212 PSmoveto(Xpos, ymid, outf);
3213 PSlineto(xmid, ytop, outf);
3214 PSlineto(xright, ymid, outf);
3215 PSlineto(xmid, Ypos, outf);
3216 PSlineto(Xpos, ymid, outf);
3219 /* Draw a bar. mok 980917 */
3220 void ALDrawBar(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3226 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3228 y1 = Ypos + 2.0*(Ypos+Yspace)/5.0;
3229 y2 = Ypos + 3.0*(Ypos+Yspace)/5.0;
3231 PSmoveto(Xpos, y1, outf);
3232 PSlineto(xright, y1, outf);
3233 PSlineto(xright, y2, outf);
3234 PSlineto(Xpos, y2, outf);
3235 PSlineto(Xpos, y1, outf);
3238 void ALDrawPseudoEllipse(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,
3242 /* draws a pseudo ellipse in the box bounded by Xpos,Ypos, Xpos+Xspace, Ypos+Yspace */
3247 float xefact = 0.2; /* this shifts the guide points by 0.2 towards the axis */
3248 /* should not really be hard wired */
3253 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3254 ytop = Ypos + Yspace; /* top edge of character */
3255 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3256 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3257 xbit = Xspace * xefact;
3258 ybit = Yspace * yefact;
3260 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3264 PSmoveto(xmid,Ypos,outf);
3266 fprintf(outf,"%.2f %.2f %.2f %.2f %.2f %.2f curveto\n",
3267 Xpos+xbit,Ypos+ybit,Xpos+xbit,ytop-ybit,xmid,ytop);
3268 fprintf(outf,"%.2f %.2f %.2f %.2f %.2f %.2f curveto\n",
3269 xright-xbit,ytop-ybit,xright-xbit,Ypos+ybit,xmid,Ypos);
3272 void ALDrawLeftSemiEnd(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3280 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3281 ytop = Ypos + Yspace; /* top edge of character */
3282 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3283 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3285 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3289 fprintf(outf,"%.2f %.2f %.2f %d %d arc\n",xmid,ymid,(ytop - Ypos) *0.5,270,90);
3291 PSlineto(xright,ytop,outf);
3292 PSlineto(xright,Ypos,outf);
3293 PSlineto(xmid,Ypos,outf);
3296 void ALDrawRightSemiEnd(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
3304 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3305 ytop = Ypos + Yspace; /* top edge of character */
3306 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3307 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3309 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3312 fprintf(outf,"%f %f %f %d %d arc\n",xmid,ymid,(ytop - Ypos) *0.5,90,270);
3314 PSlineto(Xpos,Ypos,outf);
3315 PSlineto(Xpos,ytop,outf);
3316 PSlineto(xmid,ytop,outf);
3318 void ALDrawRightHalfHorizLine(
3319 float Xpos, /* bottom left hand corner of character posn */
3321 float Xspace, /* horizontal width of character position */
3322 float Yspace, /* vertical height of character position */
3323 float width_fac, FILE *outf) /* proportion of vertical height that the line will fill */
3325 /* draw line from midpoint to right of position */
3334 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3335 ytop = Ypos + Yspace; /* top edge of character */
3336 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3337 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3339 /* width_fac defines the width of the line in terms of the height of the characters */
3341 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3343 PSmoveto(xmid,ymid-hline_w,outf);
3344 PSlineto(xmid,ymid+hline_w,outf);
3345 PSlineto(xright,ymid+hline_w,outf);
3346 PSlineto(xright,ymid-hline_w,outf);
3347 PSlineto(xmid,ymid-hline_w,outf);
3350 void ALDrawLeftHalfHorizLine(
3351 float Xpos, /* bottom left hand corner of character posn */
3353 float Xspace, /* horizontal width of character position */
3354 float Yspace, /* vertical height of character position */
3355 float width_fac, FILE *outf) /* proportion of vertical height that the line will fill */
3357 /* draw line from midpoint to left of position */
3365 xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
3366 ytop = Ypos + Yspace; /* top edge of character */
3367 ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
3368 xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
3370 /* width_fac defines the width of the line in terms of the height of the characters */
3372 hline_w = 0.5 * (width_fac * (ytop - Ypos));
3374 PSmoveto(xmid,ymid-hline_w,outf);
3375 PSlineto(xmid,ymid+hline_w,outf);
3376 PSlineto(Xpos,ymid+hline_w,outf);
3377 PSlineto(Xpos,ymid-hline_w,outf);
3378 PSlineto(xmid,ymid-hline_w,outf);
3381 void PSmoveto(float x,float y,FILE *outf)
3383 fprintf(outf,"%.2f %.2f moveto\n",x,y);
3385 void PSlineto(float x,float y,FILE *outf)
3387 fprintf(outf,"%.2f %.2f lineto\n",x,y);
3389 void PSPutSpecialText(float Xpos,float Ypos,float Xspace,float Yspace,char *text,
3390 unsigned char current_col,
3391 unsigned char background_colour,float YspaceFactor,FILE *outf)
3392 /* Handle the special text characters */
3395 Yspace *= YspaceFactor; /* shrink the Y axis a little to avoid clashes.*/
3398 if(strcmp(text,"@horizline") == 0){
3399 ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3401 }else if(strcmp(text,"@fhorizline") == 0){
3402 ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3404 ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3405 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3407 }else if(strcmp(text,"@thickhorizline") == 0){
3408 ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
3410 }else if(strcmp(text,"@fthickhorizline") == 0){
3411 ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
3413 ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
3414 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3416 }else if(strcmp(text,"@thinhorizline") == 0){
3417 ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
3419 }else if(strcmp(text,"@fthinhorizline") == 0){
3420 ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
3422 ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
3423 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3425 }else if(strcmp(text,"@rightarrow") == 0){
3426 ALDrawRightArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3428 }else if(strcmp(text,"@frightarrow") == 0){
3429 /* ALDrawRightArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);*/
3430 /* temporary change to the right arrow width 20/1/1995*/
3431 ALDrawRightArrow(Xpos,Ypos,(Xspace*0.7),Yspace,0.5,outf);
3433 ALDrawRightArrow(Xpos,Ypos,(Xspace*0.7),Yspace,0.5,outf);
3434 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3436 }else if(strcmp(text,"@leftarrow") == 0){
3437 ALDrawLeftArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3439 }else if(strcmp(text,"@fleftarrow") == 0){
3440 ALDrawLeftArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3442 ALDrawLeftArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3443 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3445 }else if(strcmp(text,"@uparrow") == 0){
3446 ALDrawUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3448 }else if(strcmp(text,"@fuparrow") == 0){
3449 ALDrawUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3451 ALDrawUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3452 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3454 }else if(strcmp(text,"@suparrow") == 0){
3455 ALDrawSmallUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3457 }else if(strcmp(text,"@fsuparrow") == 0){
3458 ALDrawSmallUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3460 ALDrawSmallUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3461 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3463 }else if(strcmp(text,"@downarrow") == 0){
3464 ALDrawDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3466 }else if(strcmp(text,"@fdownarrow") == 0){
3467 ALDrawDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3469 ALDrawDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3470 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3472 }else if(strcmp(text,"@sdownarrow") == 0){
3473 ALDrawSmallDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3475 }else if(strcmp(text,"@fsdownarrow") == 0){
3476 ALDrawSmallDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3478 ALDrawSmallDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3479 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3481 }else if(strcmp(text,"@circle") == 0){
3482 ALDrawCircle(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3484 }else if(strcmp(text,"@fcircle") == 0){
3485 ALDrawCircle(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3487 ALDrawCircle(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3488 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3490 }else if(strcmp(text,"@diamond") == 0){
3491 ALDrawDiamond(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3493 }else if(strcmp(text,"@fdiamond") == 0){
3494 ALDrawDiamond(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3496 ALDrawDiamond(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3497 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3499 }else if(strcmp(text,"@bar") == 0){
3500 ALDrawBar(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3502 }else if(strcmp(text,"@fbar") == 0){
3503 ALDrawBar(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3505 ALDrawBar(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3506 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3508 }else if(strcmp(text,"@leftsemiend") == 0){
3509 ALDrawLeftSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3511 }else if(strcmp(text,"@fleftsemiend") == 0){
3512 ALDrawLeftSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3514 ALDrawLeftSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3515 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3517 }else if(strcmp(text,"@rightsemiend") == 0){
3518 ALDrawRightSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3520 }else if(strcmp(text,"@frightsemiend") == 0){
3521 ALDrawRightSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3523 ALDrawRightSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3524 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3526 }else if(strcmp(text,"@lefthelixend") == 0){
3528 ALDrawRightHalfHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
3530 ALDrawRightHalfHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
3531 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3533 ALDrawPseudoEllipse(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3534 fprintf(outf,"closepath \n C%-d \n fill \n",background_colour);
3536 ALDrawLeftHalfHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
3538 ALDrawLeftHalfHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
3539 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3541 ALDrawPseudoEllipse(Xpos,Ypos,Xspace,Yspace,0.5,outf);
3544 }else if(strcmp(text,"@righthelixend") == 0){
3546 ALDrawLeftHalfHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
3548 ALDrawLeftHalfHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
3549 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3551 ALDrawPseudoEllipse(Xpos,Ypos,Xspace,Yspace,1.0,outf);
3553 ALDrawPseudoEllipse(Xpos,Ypos,Xspace,Yspace,1.0,outf);
3554 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3556 ALDrawRightHalfHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
3558 ALDrawRightHalfHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
3559 fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
3563 fprintf(stderr,"Error: Unrecognised special character: %s\n",text);
3568 void PSstroke(FILE *outf)
3570 fprintf(outf,"stroke\n");
3573 void PSnewpath(FILE *outf)
3575 fprintf(outf,"newpath\n");
3578 void ALColourBackground(FILE *outf,int colour, int *b_region)
3586 fprintf(outf,"%d %d moveto %d %d lineto %d %d lineto %d %d lineto %d %d lineto closepath\n",
3587 x1,y1,x2,y1,x2,y2,x1,y2,x1,y1);
3588 fprintf(outf," C%-d \n fill \n",colour);
3589 /* reset the colour to white */
3590 /* fprintf(outf," C99\n");*/
3593 void ALCheckLegalRange(int sx,int sy, int ex, int ey, int xmin, int ymin, int xmax, int ymax)
3594 /* check if sx, sy, ex, ey are within the limits given by xmin, ymin, xmax, ymax */
3596 extern FILE *std_err;
3597 if( sx >= xmin && sx <= xmax
3598 && sy >= ymin && sy <= ymax
3599 && ex <= xmax && ex >= xmin
3600 && ey <= ymax && ey >= ymin){
3603 fprintf(std_err,"\n\nALSCRIPT COMMAND FILE ERROR:\n");
3604 fprintf(std_err,"Maximum legal range:\n");
3605 fprintf(std_err,"From position %d of sequence %d to position %d of sequence %d\n",
3606 xmin,ymin,xmax,ymax);
3608 fprintf(std_err,"Your range:\n");
3609 fprintf(std_err,"From position %d of sequence %d to position %d of sequence %d\n",
3612 GJerror("Range too big for alignment - try again!");
3617 void ALMakeHelixText(int sx, int sy, int ex, char ***texts)
3620 texts[sx][sy] = GJstrdup("@lefthelixend");
3621 texts[ex][sy] = GJstrdup("@righthelixend");
3622 for(i=sx+1;i<ex;++i){
3623 texts[i][sy] = GJstrdup("@fthickhorizline");
3627 void ALMakeStrandText(int sx, int sy, int ex, char ***texts)
3630 texts[ex][sy] = GJstrdup("@frightarrow");
3632 texts[i][sy] = GJstrdup("@fhorizline");
3636 void ALMakeCoilText(int sx, int sy, int ex, char ***texts)
3639 for(i=sx;i<ex+1;++i){
3640 texts[i][sy] = GJstrdup("@fthinhorizline");
3644 int ALrel(char *pos,int *relnum)
3645 /* ALrel: parses a string that defines a position in a sequence. This can
3648 to indicate position 10 10
3649 to indicate three before 10 10-3
3650 to indicate five after 10 10+5
3652 The routine looks up the relative number in *relnum before adding or
3653 subtracting numbers, the end result is therefore relative to the current
3656 It should be easy to extend this routine for the relative movement to
3657 apply to positions in another sequence rather than alignment
3658 coordinates. (e.g. 10+5:73 might mean 5 after the current position in sequence 73).
3665 int ipos,ioff; /* position and offset */
3666 extern FILE *std_in,*std_out,*std_err;
3673 if(strchr(pos,'+') != NULL){
3674 token = strtok(pos,"+");
3675 if(strlen(token)== 0){
3676 error("Error decoding position",1);
3677 fprintf(std_err,"Offending string is: %s\n",pos);
3681 token = strtok(NULL,"\0");
3682 if(strlen(token)== 0){
3683 error("Error decoding position",1);
3684 fprintf(std_err,"Offending string is: %s\n",pos);
3688 return (relnum[ipos] + ioff);
3689 }else if(strchr(pos,'-') != NULL){
3690 token = strtok(pos,"-");
3691 if(strlen(token)== 0){
3692 error("Error decoding position",1);
3693 fprintf(std_err,"Offending string is: %s\n",pos);
3697 token = strtok(NULL,"\0");
3698 if(strlen(token)== 0){
3699 error("Error decoding position",1);
3700 fprintf(std_err,"Offending string is: %s\n",pos);
3704 return (relnum[ipos] - ioff);
3707 return relnum[ipos];
3711 int *ALCalCons(struct seqdat *bloc,
3712 int sx,int sy,int ex,int ey,int *ret_val,int len)
3714 /* Calculate conservation for an alignment - this can be just a segment of an alignment */
3715 /* bloc = the alignment bloc */
3716 /* sx,sy,ex,ey = the positions over which to calculate the conservation */
3717 /* conscut = conservation number cutoff ( an integer 0 - 10) */
3718 /* ret_val = a pointer to an integer array to store the results of the calculation */
3719 /* len = the length of the array ret_val - this must be the same as the alignment length */
3729 temp = GJstrcreate(tlen+1,NULL);
3730 if(ret_val == NULL){
3731 ret_val = (int *) GJmalloc(sizeof(int) * len);
3734 for(i=sx;i<(ex+1);++i){
3735 /* calculate conservation at each position */
3737 for(j=sy;j<(ey+1);++j){
3738 temp[k] = bloc[j].seq[i];
3741 temp2 = GJstoupper(temp);
3742 /* check for all gap columns */
3744 for(j=0;j<tlen;++j){
3745 if(temp2[j] == ' ') ++gcount;
3750 tval = mzcons((unsigned char *)temp2,tlen);
3752 /* fprintf(stderr,"In calcons: i:%d tlen:%d temp:%s tval:%f\n",i,tlen,temp,tval);*/
3753 ret_val[i] = 10 * tval;
3760 float mzcons(unsigned char *pos,int n)
3761 /* calculate conservation value according to Zvelebil et al for a set
3762 of amino acids and gaps stored in string pos of length n
3763 translated from the fortran mzcons.f 6/3/1995
3767 /* -- conmat contains a table like that shown in the JMB paper
3768 order of amino acids is GAP,ARNDCQEGHILKMFPSTWYVBZX
3770 static char *acids = " ARNDCQEGHILKMFPSTWYVBZX";
3771 static int conmat[24][10] = {
3772 {1,1,1,1,1,1,1,1,1,1}, /* */
3773 {1,0,0,0,0,1,1,0,0,0}, /*A */
3774 {0,1,0,1,1,0,0,0,0,0}, /*R */
3775 {0,0,0,1,0,1,0,0,0,0}, /*N */
3776 {0,0,1,1,1,1,0,0,0,0}, /*D */
3777 {1,0,0,0,0,1,0,0,0,0}, /*C */
3778 {0,0,0,1,0,0,0,0,0,0}, /*Q */
3779 {0,0,1,1,1,0,0,0,0,0}, /*E */
3780 {1,0,0,0,0,1,1,0,0,0}, /*G */
3781 {1,1,0,1,1,0,0,0,1,0}, /*H */
3782 {1,0,0,0,0,0,0,1,0,0}, /*I */
3783 {1,0,0,0,0,0,0,1,0,0}, /*L */
3784 {1,1,0,1,1,0,0,0,0,0}, /*K */
3785 {1,0,0,0,0,0,0,0,0,0}, /*M */
3786 {1,0,0,0,0,0,0,0,1,0}, /*F */
3787 {0,0,0,0,0,1,0,0,0,1}, /*P */
3788 {0,0,0,1,0,1,1,0,0,0}, /*S */
3789 {1,0,0,1,0,1,0,0,0,0}, /*T */
3790 {1,0,0,1,0,0,0,0,1,0}, /*W */
3791 {1,0,0,1,0,0,0,0,1,0}, /*Y */
3792 {1,0,0,0,0,1,0,1,0,0}, /*V */
3793 {0,0,0,1,0,0,0,0,0,0}, /*B */
3794 {0,0,0,1,0,0,0,0,0,0}, /*Z */
3795 {1,1,1,1,1,1,1,1,1,1} /*X */
3798 int concnt,it,i,j,k,l,tcnt,ibseq;
3801 unsigned char facid;
3805 /*found: outer loop over properties
3806 set IT to the value of the first amino acid*/
3807 it = conmat[GJindex(acids,pos[0])][j];
3808 /*loop over remaining acids, if a difference occurs then
3812 if(it != conmat[GJindex(acids,pos[k])][j]){
3816 /*add tcnt to concnt*/
3819 /* check for total identity at this position*/
3823 if(facid == pos[k]){
3828 /*calculate the conservation*/
3831 }else if(concnt == 0){
3836 /*not identity, but same properties*/
3840 con = 0.9 - 0.1 * concnt;
3846 int GJindex(char *str,char c)
3850 if(t == NULL) return -1;
3851 return (int) (t - str);