ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/dnacgr/dnacgr.c
Revision: 1.3
Committed: Sun Apr 22 17:54:01 2001 UTC (15 years, 7 months ago) by indraneel
Branch: MAIN
CVS Tags: HEAD_NEW, HEAD
Changes since 1.2: +1 -1 lines
Log Message:
oops, forgot to change the maintainer email address

Line File contents
1 /* Copyright (C) 2000 by Indraneel Majumdar<indraneel@indialine.org> */
2
3 /* GNU LESSER GENERAL PUBLIC LICENSE
4 Version 2.1, February 1999
5
6 You should have received a copy of the GNU Lesser General Public
7 License along with this library; if not, write to the Free Software
8 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
9 */
10 /* Program to plot Chaos Game Representation of a DNA or RNA sequence. */
11
12
13 /* this file should be linked with
14 -lreadline -lncurses -lm -lvgagl -lvga -lpng -lz */
15
16 #include<stdio.h>
17 #include<stdlib.h>
18 #include<vgagl.h>
19 #include<vga.h>
20 #include<math.h>
21 #include<readline/readline.h>
22 #include<png.h>
23
24 #define VGAMODE 12 /* 1024 x 768 at 256 colors */
25 #define TEXT 0 /* text mode */
26
27 /* initialise buffers for svgalib */
28 GraphicsContext *physicalscreen;
29 GraphicsContext *templatescreen, *fileplotscreen, *randomplotscreen;
30
31 /* stores probability data */
32 struct P_ATGC
33 {
34 double a, t, g, c;
35 }
36 P;
37
38 struct point
39 {
40 double x, y;
41 }
42 A, T, G, C;
43
44 /* stores input file name */
45 struct file_identity
46 {
47 char name[105]; /* filepath and name has to be < 100 characters */
48 int flag; /* set this 0 for random plot */
49 }
50 seqfile, outfile;
51
52 /* global flags for user choice */
53 struct all_flags
54 {
55 int file, prob, cycles, grid, seq, reload, counts, refresh, print;
56 }
57 flags;
58
59 char sequence_table[16][16][5]; /* stores sequence chart */
60 int probability_table[16][16]; /* stores counts of bases per 10000 */
61 long int CYCLES, CYCLES_FIRST, CYCLES_LAST; /* iterations */
62
63 /* user input for probabilities for random plot */
64 void
65 get_atgc_probabilities ()
66 {
67 vga_setmode (TEXT);
68 P.a = P.t = P.g = P.c = 1.000000;
69 while ((P.a + P.t + P.g) > 1.000001)
70 {
71 printf ("\nEnter probabilities for A, T, G\n"
72 "(probability for C is calculated automagically)\n"
73 "Probabilities=>");
74 scanf ("%lf,%lf,%lf", &P.a, &P.t, &P.g);
75 getchar (); /* discard the entered newline character */
76 }
77 P.c = 1.000001 - (P.a + P.t + P.g);
78 flags.prob = 1 - flags.prob; /* reverse global flag */
79 vga_setmode (VGAMODE);
80 }
81
82 /* user input for iterations */
83 int
84 get_cycles ()
85 {
86 long int cycles;
87 cycles = CYCLES_FIRST = 0;
88 vga_setmode (TEXT);
89 if (seqfile.flag == 0)
90 {
91 printf ("\nEnter number of points to plot\n" "Points to plot=>");
92 scanf ("%d", &cycles);
93 }
94 else
95 {
96 do
97 { /* filter user's input for errors, discard -ve numbers */
98 printf ("\nEnter start point for plot\n" "First base=>");
99 scanf ("%d", &CYCLES_FIRST);
100 printf ("\nEnter end point for plot\n"
101 "(enter '0' for entire file)\n" "Last base=>");
102 scanf ("%d", &cycles);
103 }
104 while ((cycles != 0) && ((cycles < 0) || (cycles < CYCLES_FIRST)));
105 if ((cycles == 0) || (CYCLES_FIRST < 1))
106 CYCLES_FIRST = 1; /*so display looks better */
107 }
108 getchar (); /* discard newline character */
109 vga_setmode (VGAMODE);
110 flags.cycles = 1 - flags.cycles; /* reverse global flag */
111 return (cycles); /* return end point of loop */
112 }
113
114 /* user's input for sequence input file */
115 void
116 get_seqfile ()
117 {
118 FILE *fopen (), *file_pointer; /* to check if file exists */
119 char *filename_pointer, *malloc (); /*readline requires this */
120 int length;
121 filename_pointer = malloc (100); /* length of filename<100 */
122 vga_setmode (TEXT);
123 file_pointer = 0; /* initialise pointer to NULL */
124 seqfile.flag = 1;
125 while ((file_pointer == 0) && (seqfile.flag == 1))
126 {
127 printf ("\nEnter full path of DNA sequence file\n"
128 "(enter '*' for random number plot)\n");
129 filename_pointer = readline ("Filename=> "); /* makes it easy to locate files */
130 strncpy (seqfile.name, filename_pointer, 100);
131 if (seqfile.name[0] == '*')
132 {
133 sprintf (seqfile.name, "RANDOM NUMBER PLOT"); /* give a title to the plot */
134 seqfile.flag = 0; /* set flag for plot type */
135 }
136 else
137 {
138 length = strlen (seqfile.name);
139 if (seqfile.name[length - 1] == ' ')
140 seqfile.name[length - 1] = '\0'; /* discard last blank which maybe entered by readline input */
141 seqfile.flag = 1; /* set flag that disk file is being used */
142 file_pointer = fopen (seqfile.name, "r"); /* check if file exists */
143 }
144 }
145 if (seqfile.flag == 1)
146 fclose (file_pointer); /* close file if exists */
147 free (filename_pointer);
148 flags.file = 1 - flags.file; /* reverse global flag */
149 vga_setmode (VGAMODE);
150 }
151
152 /* generate (x,y) random point from 0 to 1 */
153 struct point
154 get_random_point ()
155 {
156 struct point p;
157 p.x = ((double) rand () / RAND_MAX);
158 p.y = ((double) rand () / RAND_MAX);
159 return (p);
160 }
161
162 /* make border of plot and print filename */
163 void
164 draw_border ()
165 {
166 gl_line (A.x, A.y, T.x, T.y, 3);
167 gl_line (T.x, T.y, G.x, G.y, 3);
168 gl_line (G.x, G.y, C.x, C.y, 3);
169 gl_line (C.x, C.y, A.x, A.y, 3);
170 gl_setfontcolors (0, 32);
171 gl_write (A.x - 25, A.y - 25, "DNA base 'A'");
172 gl_write (T.x - 25, T.y + 30, "DNA base 'T'");
173 gl_write (G.x - 50, G.y + 30, "DNA base 'G'");
174 gl_write (C.x - 50, C.y - 25, "DNA base 'C'");
175 gl_setfontcolors (0, 42); /*same color as file data */
176 gl_printf (A.x + 100, T.y + 50, "%s", seqfile.name);
177 }
178
179 /* draw the grid (lines are 37.5 pixels apart) */
180 void
181 draw_grid ()
182 {
183 int num;
184 float x, y, loopx, loopy = 0;
185 x = C.x;
186 y = T.y;
187 loopx = A.x;
188 loopy = A.y;
189 num = 0;
190 gl_setfontcolors (0, 52);
191 gl_write (500, A.y - 20, "sequence resolution = 9 bp"); /* for a 600x600 pixel plot difference in base in any of last 9 bases gives different points (advertise this) */
192 while (loopx <= x)
193 {
194 gl_line (loopx, A.y - 10, loopx, y + 10, 8);
195 gl_printf (loopx, y + 15, "%d", num); /* grid number */
196 loopx = loopx + 37.5;
197 num++;
198 }
199 num = 0;
200 while (loopy <= y)
201 {
202 gl_line (A.x - 10, loopy, x + 10, loopy, 8);
203 gl_printf (x + 15, loopy, "%d", num); /* grid number */
204 loopy = loopy + 37.5;
205 num++;
206 }
207 flags.grid = 1 - flags.grid; /* reverse global flag */
208 }
209
210 /* plot random plot to virtual screen and copy to real screen (this makes plot and refresh faster)*/
211 void
212 plot_random_sequence (long int cycles)
213 {
214 long int loop;
215 double a, t, g, c;
216 struct point p, pix;
217 gl_setcontext (templatescreen); /*change to template virtual screen */
218 gl_copyscreen (randomplotscreen); /*copy template to working virtual screen ie randomplotscreen */
219 gl_setcontext (randomplotscreen); /* change to working virtual screen */
220 a = P.a;
221 t = a + P.t;
222 g = t + P.g;
223 c = g + P.c; /* convert user input to 0 to 1 */
224 loop = 0;
225 pix.x = 600;
226 pix.y = 350;
227 while (loop < cycles)
228 {
229 p = get_random_point ();
230 /* test against user input probability and scale pixel to fit within borders. point is located midway between previous point and corner for chosen base. This is the CGR */
231 if (p.x <= a)
232 {
233 pix.x = (pix.x + A.x) / 2;
234 pix.y = (pix.y + A.y) / 2;
235 }
236 else if (p.x <= t)
237 {
238 pix.x = (pix.x + T.x) / 2;
239 pix.y = (pix.y + T.y) / 2;
240 }
241 else if (p.x <= g)
242 {
243 pix.x = (pix.x + G.x) / 2;
244 pix.y = (pix.y + G.y) / 2;
245 }
246 else if (p.x <= c)
247 {
248 pix.x = (pix.x + C.x) / 2;
249 pix.y = (pix.y + C.y) / 2;
250 }
251 gl_setpixel (pix.x, pix.y, 44); /*plot the pixel */
252 loop++;
253 }
254 gl_copyscreen (physicalscreen); /* copy to monitor or stdout */
255 gl_setcontext (physicalscreen); /* change working screen to real screen */
256 CYCLES = loop; /* record actual number of points plotted */
257 }
258
259 /* plots CGR from disk file sequence to virtual screen and copies to real screen (makes plotting and refresh faster)*/
260 void
261 plot_file_sequence (long int cycles)
262 {
263 long int loop, base_count, first_base;
264 int base, array_row, array_col, array_box, stop;
265 int a, t, g, c;
266 struct point pix;
267 char file_header[200]; /* non sequence lines at start of file */
268 FILE *fopen (), *file_pointer;
269 gl_setcontext (templatescreen); /* change to template virtual screen */
270 gl_copyscreen (fileplotscreen); /* copy template to working screen */
271 gl_setcontext (fileplotscreen); /* change to working virtual screen */
272 loop = stop = base_count = base = 0;
273 first_base = CYCLES_FIRST - 1;
274 a = t = g = c = 0;
275 /* initialise the counts table for each new plot */
276 for (array_row = 0; array_row < 16; array_row++)
277 {
278 for (array_col = 0; array_col < 16; array_col++)
279 {
280 probability_table[array_row][array_col] = 0;
281 }
282 }
283 pix.x = 600;
284 pix.y = 350;
285 file_pointer = fopen (seqfile.name, "r"); /* open file for reading */
286 fgets (file_header, 200, file_pointer); /* first line is not checked for sequence (assumed to contain file information and is shown on display */
287 gl_setfontcolors (0, 42);
288 gl_write (50, T.y + 60, "File data:");
289 gl_printf (50, T.y + 80, "%s", file_header); /* show first line */
290 base = getc (file_pointer); /* get first base of next line */
291 base = tolower (base); /* convert to lowercase */
292 /* sequence description must start with a,t,u,g,c, or blank (fasta format), please write checkpoints for other sequence formats and add here */
293 while ((base != 'a') && (base != 't') && (base != 'u') && (base != 'g')
294 && (base != 'c') && (base != ' '))
295 {
296 ungetc (base, file_pointer); /* move back */
297 fgets (file_header, 200, file_pointer); /* remove the whole line */
298 base = getc (file_pointer); /* get first base of next line */
299 base = tolower (base);
300 }
301 ungetc (base, file_pointer); /* move back if sequence has started */
302 /* check for EOF and whether last base to plot has been reached */
303 while ((stop == 0) && ((base = getc (file_pointer)) != EOF))
304 {
305 base = tolower (base);
306 if ((base == 'a') || (base == 't') || (base == 'u') || (base == 'g')
307 || (base == 'c'))
308 {
309 /* check whether base is to be plotted (user input for start and end points) */
310 if ((cycles == 0) || ((loop >= first_base) && (loop < cycles)))
311 {
312 /* set pixel according to CGR theory (point is halfway between previous point and corner of current chosen base) */
313 if (base == 'a')
314 {
315 pix.x = (pix.x + A.x) / 2;
316 pix.y = (pix.y + A.y) / 2;
317 a++;
318 }
319 else if ((base == 't') || (base == 'u'))
320 {
321 pix.x = (pix.x + T.x) / 2;
322 pix.y = (pix.y + T.y) / 2;
323 t++;
324 }
325 else if (base == 'g')
326 {
327 pix.x = (pix.x + G.x) / 2;
328 pix.y = (pix.y + G.y) / 2;
329 g++;
330 }
331 else if (base == 'c')
332 {
333 pix.x = (pix.x + C.x) / 2;
334 pix.y = (pix.y + C.y) / 2;
335 c++;
336 }
337 gl_setpixel (pix.x, pix.y, 44); /* plot the pixel */
338 array_row = (pix.x - 300) / 37.5;
339 array_col = (pix.y - 50) / 37.5; /* scale the pixel location and update the counts table */
340 probability_table[array_row][array_col]++;
341 base = 'x'; /* make base non atugc blank */
342 base_count++; /* update count of actual points plotted */
343 }
344 loop++; /* increment counter for bases checked */
345 if ((cycles != 0) && (loop == cycles))
346 stop = 1; /* check for end point */
347 } /* no counter increments for non atugc even if not plotted */
348 }
349 fclose (file_pointer);
350 CYCLES = base_count; /* record actual points plotted */
351 CYCLES_LAST = loop; /* record actual last base checked */
352 if (base_count == 0)
353 CYCLES_FIRST = base_count = 1; /* if user input for first base was > total bases in file */
354 /* calculate probability of atgc based on total points plotted */
355 P.a = (double) a / base_count;
356 P.t = (double) t / base_count;
357 P.g = (double) g / base_count;
358 P.c = (double) c / base_count;
359 /* prepare counts table to show counts out of 10000 */
360 for (array_row = 0; array_row < 16; array_row++)
361 {
362 for (array_col = 0; array_col < 16; array_col++)
363 {
364 /* convert display to integer */
365 array_box =
366 (probability_table[array_row][array_col] * 10000) / base_count;
367 /* update table */
368 probability_table[array_row][array_col] = array_box;
369 }
370 }
371 gl_copyscreen (physicalscreen); /* copy working screen to monitor or stdout */
372 gl_setcontext (physicalscreen); /* change working screen to real screen */
373 }
374
375 /* to show the sequence chart at the drop of a finger */
376 void
377 make_sequence_table ()
378 {
379 int row, col, position;
380 int base;
381 row = col = position = 0;
382 /* pass all calculations to helper for all 1024 positions */
383 while (position < 4)
384 { /* no place to print more than 4 bases */
385 while (col < 16)
386 {
387 while (row < 16)
388 {
389 base = help_sequence_table (col, row, position);
390 sequence_table[row][col][position] = base;
391 row++;
392 }
393 col++;
394 row = 0;
395 }
396 position++;
397 col = 0;
398 }
399 /* add a blank to all ends so they can be printed as strings */
400 row = col = 0;
401 while (col < 16)
402 {
403 while (row < 16)
404 {
405 sequence_table[row][col][4] = '\0';
406 row++;
407 }
408 col++;
409 row = 0;
410 }
411 }
412
413 /* this returns value of a base at any position of any table */
414 /* (first position is position 0 and so on..) */
415 int
416 help_sequence_table (int row, int col, int position)
417 {
418 int base;
419 int divisor, checkx, checky; /*checkxy - even is 0, odd is 1 */
420 divisor = pow (2, position); /* convert divisor to position power of 2 */
421 row = row / divisor;
422 col = col / divisor; /* now it is easier to handle as everything becomes odd or even */
423 checkx = checky = 1;
424 /* check odd or even */
425 if ((row % 2) == 0)
426 checkx = 0;
427 if ((col % 2) == 0)
428 checky = 0;
429 /* the bottom is true when ATGC represents a square */
430 if ((checkx == 0) && (checky == 0))
431 base = 'A';
432 else if ((checkx == 1) && (checky == 0))
433 base = 'T';
434 else if ((checkx == 1) && (checky == 1))
435 base = 'G';
436 else if ((checkx == 0) && (checky == 1))
437 base = 'C';
438 return (base); /* done */
439 }
440
441 /* display the table when asked */
442 void
443 display_sequence_table ()
444 {
445 int row, col, startx, starty;
446 gl_setfontcolors (0, 92);
447 gl_printf (20, 200, "(sequence ending for point)");
448 startx = 302;
449 starty = 53;
450 row = col = 0;
451 while (col < 16)
452 {
453 while (row < 16)
454 {
455 /* print the table as strings of 4 chars */
456 gl_write (startx + row * 37.5, starty + col * 37.5,
457 sequence_table[row][col]);
458 /* oops, must have goofed up somewhere, interchange row and col for correct output */
459 row++;
460 }
461 col++;
462 row = 0;
463 }
464 }
465
466 /* display the counts table */
467 void
468 display_probability_table ()
469 {
470 int row, col, startx, starty;
471 gl_setfontcolors (0, 40);
472 gl_printf (20, 220, "(counts per 10'000 total points)");
473 gl_setfontcolors (31, 40); /* change background to white to see better */
474 startx = 302;
475 starty = 63;
476 row = col = 0;
477 while (col < 16)
478 {
479 while (row < 16)
480 {
481 gl_printf (startx + row * 37.5, starty + col * 37.5, "%d",
482 probability_table[row][col]);
483 row++;
484 }
485 col++;
486 row = 0;
487 }
488 }
489
490 /* display total probability, points plotted, user's input of first base, lase base checked */
491 void
492 display_parameters ()
493 {
494 gl_setfontcolors (0, 48);
495 gl_write (50, 60, "Probabilities are:");
496 gl_printf (20, 80, "A = %6.4f", P.a);
497 gl_printf (20, 100, "T = %6.4f", P.t);
498 gl_printf (150, 100, "G = %6.4f", P.g);
499 gl_printf (150, 80, "C = %6.4f", P.c);
500 gl_printf (50, 120, "Total points: %d", CYCLES); /* total points plotted */
501 /* only if disk file is read */
502 if (seqfile.flag == 1)
503 {
504 gl_printf (20, 140, "First base: %d", CYCLES_FIRST); /* user's input echoed with minor changes in case of wrong input */
505 gl_printf (20, 160, "Last base: %d", CYCLES_LAST); /* display last base actually checked */
506 }
507 }
508
509 /*keep template for use by fileplotscreen and randomplotscreen for fresh plots*/
510 void
511 make_templatescreen ()
512 {
513 gl_setcontext (templatescreen); /*change to virtual screen */
514 gl_clearscreen (0);
515 gl_setfontcolors (0, 44);
516 gl_printf (5, 5,
517 " HELP MENU: file iterations probability counts grid sequence refresh Print Reload about quit");
518 gl_setfontcolors (0, vga_white ());
519 gl_printf (50, 650, "dnacgr-0.2");
520 draw_grid ();
521 draw_border ();
522 gl_setcontext (physicalscreen); /*change to real screen */
523 }
524
525 /* prepare virtual screens randomplotscreen and fileplot screen and show on real screen */
526 void
527 make_display (long int cycles)
528 {
529 make_templatescreen ();
530 if (seqfile.flag == 0)
531 {
532 plot_random_sequence (cycles);
533 }
534 else
535 plot_file_sequence (cycles);
536 display_parameters ();
537 flags.reload = 1 - flags.reload; /* reverse global flag */
538 }
539
540 /* to save time just refresh the screen, do not replot any data */
541 void
542 display_refresh (int input_grid)
543 {
544 if (seqfile.flag == 0)
545 {
546 gl_setcontext (randomplotscreen);
547 gl_copyscreen (physicalscreen);
548 gl_setcontext (physicalscreen);
549 }
550 else
551 {
552 gl_setcontext (fileplotscreen);
553 gl_copyscreen (physicalscreen);
554 gl_setcontext (physicalscreen);
555 }
556 if (input_grid == 1)
557 {
558 draw_grid ();
559 draw_border ();
560 } /* draw grid if required */
561 display_parameters (); /* parameters are always displayed */
562 flags.refresh = 1 - flags.refresh; /* reverse global flag */
563 }
564
565 /* save the color table to file for use with screen memory dump */
566 /* unused code */
567 void
568 save_color_table ()
569 {
570 FILE *fopen (), *file_pointer;
571 int color, r, g, b;
572 color = 0;
573 file_pointer = fopen ("clrtbl.dnacgr", "w");
574 for (color = 0; color < 256; color++)
575 {
576 gl_getpalettecolor (color, &r, &g, &b);
577 fprintf (file_pointer, "%d\t%d\t%d\t%d\n", color, r * 4, g * 4, b * 4);
578 }
579 fclose (file_pointer);
580 }
581
582 /* ask user for output filename. .png extension is added automatically */
583 void
584 get_output_filename ()
585 {
586 char *filename_pointer, *malloc ();
587 vga_setmode (TEXT);
588 filename_pointer = malloc (100);
589 printf ("\nEnter new filename for saving image file\n");
590 filename_pointer = readline ("Filename=> ");
591 strncpy (outfile.name, filename_pointer, 100);
592 strcat (outfile.name, ".png");
593 free (filename_pointer);
594 vga_setmode (VGAMODE);
595 }
596
597 /* this just dumps screen memory to file, you need color tables to use this dump */
598 /* unused code */
599 void
600 print_file ()
601 {
602 FILE *fopen (), *file_pointer;
603 char *saved_screen_ptr, *malloc ();
604 saved_screen_ptr = malloc (1024 * 768);
605 gl_getbox (0, 0, 1024, 768, saved_screen_ptr);
606 file_pointer = fopen (outfile.name, "w");
607 fwrite (saved_screen_ptr, 1, 1024 * 768, file_pointer);
608 fclose (file_pointer);
609 free (saved_screen_ptr);
610 flags.print = 1 - flags.print;
611 }
612
613 /* print to png file. modified from code donated by Sergio Masci <sergio@titan.demon.co.uk> */
614 void
615 print_png_file ()
616 {
617 FILE *fopen (), *fp;
618 char *malloc ();
619 int xred, xgreen, xblue;
620 int adj, bits_per_colour, j;
621 char *rp;
622 png_struct *png_ptr;
623 png_info *info_ptr;
624 png_colorp palette;
625
626 fp = fopen (outfile.name, "wb");
627
628 // allocate the necessary structures
629 png_ptr = (png_struct *) malloc (sizeof (png_struct));
630
631 info_ptr = (png_info *) malloc (sizeof (png_info));
632
633 // initialize the structures
634 png_info_init (info_ptr);
635 png_write_init (png_ptr);
636
637 // set up the output control
638 png_init_io (png_ptr, fp);
639
640 // set the file information here
641 info_ptr->width = 1024;
642 info_ptr->height = 768;
643 info_ptr->bit_depth = 8;
644 info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
645
646 //----------------------
647
648 // set the palette
649 info_ptr->valid |= PNG_INFO_PLTE;
650 info_ptr->palette = (png_color *) malloc (256 * sizeof (png_color));
651 info_ptr->num_palette = 256;
652
653
654
655 bits_per_colour = 6;
656
657 adj = 8 - bits_per_colour;
658
659
660 for (j = 0; j < 256; j++)
661 {
662 vga_getpalette (j, &xred, &xgreen, &xblue);
663
664 info_ptr->palette[j].red = xred << adj;
665 info_ptr->palette[j].green = xgreen << adj;
666 info_ptr->palette[j].blue = xblue << adj;
667 }
668
669 // write the file information
670 png_write_info (png_ptr, info_ptr);
671
672 rp = malloc (1024);
673
674 for (j = 0; j < 768; j++)
675 {
676 gl_getbox (0, j, 1024, 1, rp);
677
678 // Write a row at a time.
679 png_write_rows (png_ptr, &rp, 1);
680 }
681
682 free (rp);
683
684 //----------------------
685
686 // write the rest of the file
687 png_write_end (png_ptr, NULL);
688
689 // clean up after the write, and free any memory allocated
690 png_write_destroy (png_ptr);
691
692 if (info_ptr->palette)
693 { // a palette was used, so free it
694 free (info_ptr->palette);
695 }
696
697 // free the structures
698 free (png_ptr);
699 free (info_ptr);
700
701 fclose (fp);
702 }
703
704
705 /* add your name here if you add a significant functionality to this code */
706 /* do not change the copyright notice */
707 void
708 show_about_screen ()
709 {
710 int key;
711 vga_setmode (VGAMODE);
712 gl_clearscreen (31);
713 gl_setfontcolors (31, 0);
714 gl_printf (360, 250,
715 " DNA-CGR (version 0.2)\nProgram to visualise patterns in DNA\n\n Copyright (C) 2000\n\n by\n\n Indraneel Majumdar\n\n <indraneel@123india.com>\n\n\n Copyright Policy - GNU-LGPL\n\n (see file LGPL-2.1 for details)\n\n (press 'L' to show License)");
716 key = getchar ();
717 if (key == 'L')
718 {
719 vga_setmode (TEXT);
720 system ("/usr/bin/less /usr/share/common-licenses/LGPL-2.1");
721 vga_setmode (VGAMODE);
722 }
723 }
724
725 /* background process to handle all keypresses */
726 void
727 user_request_handler ()
728 {
729 long int cycles;
730 int user_key;
731 struct all_flags input;
732 /* set initial values of local flags for first run */
733 input.file = 0;
734 input.prob = 1;
735 input.cycles = 0;
736 input.grid = 0;
737 input.seq = 0;
738 input.reload = 0;
739 input.counts = 0;
740 input.refresh = 1;
741 input.print = 1;
742 user_key = 'x';
743 while (user_key != 'q')
744 {
745 switch (user_key)
746 {
747 case 'f':
748 input.file = 1 - input.file;
749 input.reload = 1 - input.reload; /* reload file (replot) */
750 break;
751 case 'p':
752 if (seqfile.flag == 0)
753 {
754 input.prob = 1 - input.prob;
755 input.reload = 1 - input.reload; /* replot */
756 }
757 break;
758 case 'i':
759 input.cycles = 1 - input.cycles;
760 input.reload = 1 - input.reload; /* replot from file */
761 break;
762 case 'g':
763 input.grid = 1 - input.grid;
764 if (input.grid == 1)
765 {
766 draw_grid ();
767 draw_border ();
768 }
769 else
770 input.refresh = 1 - input.refresh; /* just refresh screen */
771 break;
772 case 's':
773 input.seq = 1 - input.seq;
774 if (input.seq == 0)
775 input.refresh = 1 - input.refresh; /*just refresh screen */
776 break;
777 case 'R':
778 input.reload = 1 - input.reload; /* user's request to reload file */
779 break;
780 case 'c':
781 if (seqfile.flag == 1)
782 input.counts = 1 - input.counts;
783 /* switch off counts display (refresh screen) */
784 if ((seqfile.flag == 1) && (input.counts == 0))
785 input.refresh = 1 - input.refresh;
786 break;
787 case 'r':
788 input.refresh = 1 - input.refresh; /* refresh screen */
789 break;
790 case 'P':
791 get_output_filename ();
792 input.refresh = 1 - input.refresh;
793 input.print = 1 - input.print;
794 break;
795 case 'a':
796 show_about_screen (); /* version, names of author(s), copyright */
797 input.refresh = 1 - input.refresh;
798 break;
799 default:
800 break;
801 }
802 user_key = 'x';
803 /* do not change the sequence below (the sequence of operations is required at least for first run) */
804 if (input.file == flags.file)
805 get_seqfile ();
806 /* next step explicitly checks for probabilities on first run (probabilities are required only for random number plot) */
807 if (
808 ((seqfile.flag == 0) && ((P.a + P.t + P.g + P.c) == 0)
809 && (input.prob = 1 - input.prob)) || ((seqfile.flag == 0)
810 && (input.prob ==
811 flags.
812 prob)))
813 get_atgc_probabilities ();
814 if (input.cycles == flags.cycles)
815 cycles = get_cycles (); /* iterations */
816 if (input.reload == flags.reload)
817 make_display (cycles); /* replot */
818 if (input.refresh == flags.refresh)
819 display_refresh (input.grid); /*just refresh */
820 if (input.seq == 1)
821 display_sequence_table ();
822 /* counts table displayed only if sequence file is used */
823 if ((seqfile.flag == 1) && (input.counts == 1))
824 display_probability_table ();
825 user_key = vga_getkey (); /* read key without waiting */
826 if (input.print == flags.print)
827 print_png_file ();
828 }
829 }
830
831 int
832 main ()
833 {
834 int x, y;
835 x = y = 0;
836 vga_init (); /* initialise display for svgalib */
837 if (vga_hasmode (VGAMODE) == 0)
838 exit (1); /* check if mode 12 is supported */
839 /* set corner points of border */
840 A.x = 300;
841 A.y = 50;
842 T.x = 300;
843 T.y = 650;
844 G.x = 900;
845 G.y = 650;
846 C.x = 900;
847 C.y = 50;
848 srand (time (0)); /* initialise random number generator */
849
850 vga_setmode (VGAMODE); /* set 1024x768 at 256 colors */
851
852 /* define fileplotscreen as virtual screen */
853 gl_setcontextvgavirtual (VGAMODE);
854 fileplotscreen = gl_allocatecontext ();
855 gl_getcontext (fileplotscreen);
856
857 /* define randomplotscreen as virtual screen */
858 gl_setcontextvgavirtual (VGAMODE);
859 randomplotscreen = gl_allocatecontext ();
860 gl_getcontext (randomplotscreen);
861
862 /* define templatescreen as virtual screen */
863 gl_setcontextvgavirtual (VGAMODE);
864 templatescreen = gl_allocatecontext ();
865 gl_getcontext (templatescreen);
866
867 /* define physicalscreen as real screen */
868 gl_setcontextvga (VGAMODE);
869 physicalscreen = gl_allocatecontext ();
870 gl_getcontext (physicalscreen);
871
872 gl_setcontext (physicalscreen); /* change to physicalscreen */
873 /* save_color_table(); output to file clrtbl.dnacgr */
874
875 /* define fonts globally */
876 gl_setfont (8, 8, gl_font8x8);
877 gl_setwritemode (FONT_COMPRESSED + WRITEMODE_OVERWRITE);
878 show_about_screen (); /* whom you can't flame if you lose your job */
879 make_sequence_table (); /* this is not modified later */
880 user_request_handler (); /* main loop */
881
882 /* free all memory */
883 gl_freecontext (fileplotscreen);
884 gl_freecontext (randomplotscreen);
885 gl_freecontext (templatescreen);
886 vga_setmode (TEXT); /* just to be safe */
887 }