8 #include "fast_tree_header.h"
9 #include "io_lib_header.h"
10 #include "util_lib_header.h"
11 #include "define_header.h"
12 #include "dp_lib_header.h"
13 //TODO: -change kick-out value
14 // -pass arrays in partTree_r
18 * \brief Source code for PartTree algorithm.
23 #define ENLARGEMENT_PER_STEP 50
28 print_fastal_tree(Tree_fastal *tree,
33 if (tree[pos].left >= num_seq)
34 print_fastal_tree(tree, tree[pos].left-num_seq, tree_file, num_seq);
35 if (tree[pos].right >= num_seq)
36 print_fastal_tree(tree, tree[pos].right-num_seq, tree_file, num_seq);
38 fprintf(tree_file, "%i %i %i\n", tree[pos].left, tree[pos].right, tree[pos].name);
45 PartTree_param *param_set;
48 //********************** UPGMA *****************************
51 * Function to write tree to file in fastal_format. Leafs in \a tree are leafs in the complete tree as well.
53 * \param tree The root node of the (sub)tree.
54 * \param param_set Parameter of PartTree.
55 * \param start_write_here Current node to write into.
56 * \return position in tree
60 tree_process_simple(NT_node tree,
61 PartTree_param *param_set,
66 // printf("T: %s\n", tree->name);
67 return atoi(tree->name);
71 Tree_fastal *tree_flat = ¶m_set->tree[start_write_here];
72 tree_flat->name = start_write_here +param_set->num_sequences;
73 if (start_write_here == param_set->pos_tree)
75 ++param_set->pos_tree;
77 start_write_here = param_set->pos_tree;
78 int left = tree_process_simple(tree->left, param_set, start_write_here);
79 start_write_here = param_set->pos_tree;
80 int right = tree_process_simple(tree->right, param_set, start_write_here);
81 tree_flat->index = NULL;
82 tree_flat->right = right;
83 tree_flat->left = left;
84 return tree_flat->name;
92 * Function to write tree to file in fastal_format. Leafs in \a tree do not need to be leafs in the complete tree.
94 * \param tree The root node of the (sub)tree.
95 * \param param_set Parameter of PartTree.
96 * \param clusters Number of sequences in each cluster.
97 * \param subgroup The sequences for each cluster.
98 * \param start_write_here Current node to write into.
99 * \return position in tree
100 * \see tree_process_simple
103 tree_process(NT_node tree,
104 PartTree_param *param_set,
107 int start_write_here)
111 int node_num = atoi(tree->name);
112 int num_in_sub = clusters[node_num+1] - clusters[node_num];
113 // printf("NUM: %i %i %i %i\n",node_num, num_in_sub, clusters[node_num+1], clusters[node_num]);
116 Tree_fastal *tree_flat = ¶m_set->tree[start_write_here];
117 tree_flat->name = start_write_here +param_set->num_sequences;
118 if (start_write_here == param_set->pos_tree)
120 ++param_set->pos_tree;
122 tree_flat->left = -1;
123 tree_flat->right = -1;
124 tree_flat->index = &subgroup[clusters[node_num]];
126 tree_flat->num_leafs = num_in_sub;
127 return tree_flat->name;
131 return(subgroup[clusters[node_num]]);
136 // printf("TREEPOS: %i\n",param_set->pos_tree);
137 Tree_fastal *tree_flat = ¶m_set->tree[start_write_here];
138 tree_flat->name = start_write_here +param_set->num_sequences;
139 if (start_write_here == param_set->pos_tree)
141 ++param_set->pos_tree;
143 start_write_here = param_set->pos_tree;
144 int left = tree_process(tree->left, param_set, clusters, subgroup, start_write_here);
145 start_write_here = param_set->pos_tree;
146 int right = tree_process(tree->right, param_set, clusters, subgroup, start_write_here);
147 tree_flat->index = NULL;
148 tree_flat->right = right;
149 tree_flat->left = left;
150 return tree_flat->name;
156 * \brief Calculates tree out of distance matrix.
158 * Calculates the upgma tree using a given distance matrix.
159 * \param mat The distance matrix.
160 * \param nseq Number of sequences.
161 * \param fname Filename for temporary storage.
162 * \param seqnames Names of the sequences.
163 * \return The calculated UPGMA Tree.
165 NT_node ** int_dist2upgma_tree_fastal (int **mat, int nseq, char *fname, char **seqnames)
170 if (upgma_node_heap (NULL))
172 printf_exit ( EXIT_FAILURE,stderr, "\nERROR: non empty heap in upgma [FATAL]");
174 NL=vcalloc (nseq, sizeof (NT_node));
176 for (a=0; a<nseq; a++)
178 NL[a]=new_declare_tree_node ();
179 upgma_node_heap (NL[a]);
180 sprintf (NL[a]->name, "%s", seqnames[a]);
184 used=vcalloc ( nseq, sizeof (int));
188 T=upgma_merge(mat, NL,used, &n, nseq);
191 vfclose (print_tree (T, "newick", vfopen (fname, "w")));
192 upgma_node_heap (NULL);
195 return read_tree (fname,&tot_node, nseq, seqnames);
204 * \brief Constructs a guide tree for multiple sequence alignment.
206 * This algorithm is an implementation of the partTree algorithm (PartTree: an algorithm to build an approximate tree from a large number of unaligned
207 * sequences. Katoh et al. 2007).
208 * \param sequence_f Filename of file with sequences.
209 * \param tree_f Filename of file where the tree will be stored.
210 * \param ktup Size of the ktups.
211 * \param subgroup Parameter for subgroupsize.
214 make_partTree(char *sequence_f,
219 param_set = vcalloc(1,sizeof(PartTree_param));
220 param_set->ktup = ktup;
221 param_set->subgroup = subgroup;
223 long *file_positions = NULL;
224 long **tmp1 = &file_positions;
225 int *seq_lengths = NULL;
226 int **tmp2 = &seq_lengths;
229 int number_of_sequences = make_pos_len_index_of_file(sequence_f, "KTUP_table", tmp1, tmp2, ktup, "DNA");
230 param_set->num_sequences = number_of_sequences;
231 param_set->ktup_positions = file_positions;
232 param_set->seq_lengths = seq_lengths;
233 param_set->threshold = 0.01;
234 param_set->ktup_table_f = fopen("KTUP_table","r");
236 Tree_fastal *tree = vcalloc(number_of_sequences-1,sizeof(Tree_fastal));
237 param_set->tree = tree;
240 partTree_r(param_set);
241 // for (i = 0; i < number_of_sequences-1; ++i)
243 // printf("%i %i %i\n", tree[i].left, tree[i].right, tree[i].name);
245 FILE * tree_file = fopen(tree_f,"w");
246 print_fastal_tree(tree, 0, tree_file, number_of_sequences);
255 * \param sequence_group Sequences to filter.
256 * \param dist_mat The distance matrix.
257 * \param seed_set_cleaned ordered_seed_set.
258 * \param param_set Parameters for PartTree algorithm.
259 * \return number in the filtered set.
262 filter(int *sequence_group,
264 int *seed_set_cleaned,
265 PartTree_param *param_set)
268 int num_in_subgroup = param_set->subgroup;
269 int *seq_lengths = param_set->seq_lengths;
270 int num_in_clean = 0;
271 double threshold = param_set->threshold;
272 // printf("threshold: %f\n", threshold);
274 for (i = 0; i < num_in_subgroup; ++i)
276 if (!seed_set_cleaned[i])
278 for (j = i+1; j < num_in_subgroup; ++j)
280 min = MIN(seq_lengths[sequence_group[i]], seq_lengths[sequence_group[j]]);
281 // printf("MINIMUM: %i\n",min);
282 min = (threshold * min);
283 // printf("MINIMUM: %f\n",min);
284 if (seed_set_cleaned[j] &&(dist_mat[i][j] < min))
286 if (seq_lengths[sequence_group[i]] < seq_lengths[sequence_group[j]])
288 seed_set_cleaned[i] = 0;
292 seed_set_cleaned[j] = 0;
297 for (i = 0; i < num_in_subgroup; ++i)
299 num_in_clean += seed_set_cleaned[i];
301 int max = num_in_subgroup -1;
304 // printf("CLEAN: %i\n", num_in_clean);
305 while (i < num_in_clean)
307 if (seed_set_cleaned[i])
313 seed_set_cleaned[i] = seed_set_cleaned[max];
314 seed_set_cleaned[max] = 0;
315 tmp = sequence_group[i];
316 sequence_group[i] = sequence_group[max];
317 sequence_group[max] = tmp;
329 * \brief Function to create a tree using the PartTree algorithm.
331 * \param param_set A \a PartTree_param object containing all necessary parameters and the data.
332 * \return The node_number.
335 partTree_r(PartTree_param *param_set)
338 int num_of_tree_nodes = param_set->num_sequences-1;
341 Tree_fastal *tree = param_set->tree;
342 // int this_node = param_set->pos_tree;
345 int tsize = param_set->tsize;
349 short *table1 = vcalloc(tsize, sizeof(short));
350 short *table2 = vcalloc(tsize, sizeof(short));
351 int *seed_set = vcalloc(param_set->subgroup, sizeof(int));
352 char **names = declare_char(param_set->subgroup, 8);
353 int **dist_mat = declare_int(param_set->subgroup, param_set->subgroup);
354 int **dist_mat2 = declare_int(param_set->subgroup, param_set->subgroup);
355 char * file_name_tmp = vtmpnam(NULL);
356 int *seed_set_cleaned = vcalloc(param_set->subgroup, sizeof(int));
357 FILE *table_f = param_set->ktup_table_f;
358 long *file_positions = param_set->ktup_positions;
359 int max_n_group = param_set->subgroup;
360 int num_in_subgroup = param_set->subgroup;
361 int *seq_lengths = param_set->seq_lengths;
362 int *clusters = vcalloc(param_set->subgroup+1, sizeof(int));
363 int *min_dist = vcalloc(param_set->num_sequences, sizeof(int));
364 int *belongs_to = vcalloc(param_set->num_sequences, sizeof(int));
373 tree[0].index = vcalloc(param_set->num_sequences,sizeof(int));
374 int *index = tree[0].index;
375 for (i = 0; i< param_set->num_sequences; ++i)
377 tree[0].name = param_set->pos_tree +param_set->num_sequences;
379 tree[0].num_leafs = param_set->num_sequences;
380 int *sequence_group2 = vcalloc(param_set->num_sequences,sizeof(int));
382 Tree_fastal *current_node;
383 for (loop_tree_node = 0; loop_tree_node < num_of_tree_nodes; ++loop_tree_node)
385 // printf("ROUND: %i\n", loop_tree_node);
386 current_node = &tree[loop_tree_node];
387 index= current_node->index;
388 if (current_node->index == NULL)
392 int num_sequences = current_node->num_leafs;
394 //if number of sequences in this group smaller than number subgoup size: make tree, finisch
395 if (num_sequences <= max_n_group)
398 dist_mat = make_distance_matrix(table_f, file_positions, index, num_sequences, dist_mat);
399 for (i = 0; i < num_sequences; ++i)
401 sprintf(names[i],"%i", current_node->index[i]);
403 NT_node **tree= (int_dist2upgma_tree_fastal (dist_mat, num_sequences, file_name_tmp , names));
404 tree_process_simple(tree[0][0], param_set,loop_tree_node);
409 for (i = 0; i < num_in_subgroup; ++i)
411 seed_set_cleaned[i] = 1;
414 //finde longest sequence and put into the first field
416 int index_longest = 0;
417 int length_of_longest = 0;
419 for(i = 0; i < num_sequences; ++i)
421 if (seq_lengths[index[i]] > length_of_longest)
424 length_of_longest = seq_lengths[index[i]];
427 int tmp = index[index_longest];
428 index[index_longest] = index[0];
431 //distance of longest to rest
433 int min= euclidean_dist(table_f, file_positions[index[0]], file_positions[index[1]], table1, table2, param_set->tsize);
434 for (i = 2; i < num_sequences; ++i)
436 tmp = euclidean_dist_half(table_f, file_positions[index[i]], table1, table2, param_set->tsize);
444 //get the new seed_set in the first n spaces
446 index[1] = index[seq_index];
447 index[seq_index] = tmp;
449 num_in_subgroup = param_set->subgroup;
452 for (i = 2; i < num_in_subgroup; ++i)
454 r = i + rand() / ( RAND_MAX / ( num_sequences-i) + 1 );
455 // printf("RANDOM: %i\n",r);
462 dist_mat = make_distance_matrix(table_f, file_positions, index, param_set->subgroup, dist_mat);
464 //Filter out sequences that are to similar & reorder
466 NT_node **upgma_tree;
469 int num_in_clean = filter(index, dist_mat, seed_set_cleaned, param_set);
470 // if (num_in_clean == 1)
473 // // dist_mat = make_distance_matrix(table_f, file_positions, index, upgma_tree, dist_mat);
474 // for (i = 0; i < param_set->subgroup; ++i)
476 // sprintf(names[i],"%i", current_node->index[i]);
478 // upgma_tree= (int_dist2upgma_tree_fastal (dist_mat, param_set->subgroup, file_name_tmp , names));
479 // tree_process_simple(upgma_tree[0][0], param_set,loop_tree_node);
485 if (num_in_clean ==1)
488 seed_set_cleaned[1] = 1;
493 for (i = 0; i < num_in_subgroup; ++i)
495 if (seed_set_cleaned[i])
498 for (j = i+1; j < num_in_subgroup; ++j)
500 if (seed_set_cleaned[j])
502 dist_mat2[row][col] = dist_mat2[col][row] = dist_mat[i][j];
509 for (i = 0; i < num_in_clean; ++i)
511 sprintf(names[i],"%i",i);
513 upgma_tree= (int_dist2upgma_tree_fastal (dist_mat2, num_in_clean, file_name_tmp , names));
516 // int *pos_tree_p = ¶m_set->pos_tree;
522 //calculate distances from n' to N
523 get_table(table1, table_f, file_positions[index[0]]);
524 for (j = num_in_clean; j < num_sequences; ++j)
526 min_dist[j] = euclidean_dist_half(table_f, file_positions[index[j]], table1, table2, param_set->tsize);
529 for(i = 1; i < num_in_clean; ++i)
531 get_table(table1, table_f, file_positions[index[i]]);
533 for (j = num_in_clean; j < num_sequences; ++j)
535 tmp = euclidean_dist_half(table_f, file_positions[index[j]], table1, table2, param_set->tsize);
536 if (tmp < min_dist[j])
544 //how_many sequences has each cluster
545 for (j = 0; j <= num_in_subgroup; ++j)
549 for (j = 0; j < num_sequences; ++j)
551 ++clusters[belongs_to[j]];
553 // for (j = 0; j <= num_in_subgroup; ++j)
555 // printf("CL: %i ",clusters[j]);
558 for(i = 1; i < num_in_clean; ++i)
560 clusters[i] += clusters[i-1];
562 clusters[num_in_clean] = clusters[num_in_clean-1];
564 for (i = 0; i < num_sequences; ++i)
566 sequence_group2[--clusters[belongs_to[i]]] = index[i];
569 for (i = 0; i < num_sequences; ++i)
571 index[i] = sequence_group2[i];
575 for (i = 0; i < num_in_clean; ++i)
577 sprintf(names[i],"%i",i);
579 tree_process(upgma_tree[0][0], param_set, clusters, index, loop_tree_node);
580 NT_node tmp_tree = upgma_tree[3][0];
581 vfree(upgma_tree[0]);
582 vfree(upgma_tree[1]);
583 vfree(upgma_tree[2]);
584 vfree(upgma_tree[3]);
596 * \brief Makes the distance matrix between all sequences.
598 * \param table_file File with the ktup tables
599 * \param file_positions Index of positions where the tabels are stored in \a table_file
600 * \param sequence_group the group of sequences
601 * \param number number of sequences
602 * \param dist_mat distance matrix
603 * \return the distance matrix. (same as \a dist_mat )
606 make_distance_matrix(FILE *table_f,
607 long *file_positions,
612 static short *table1 = NULL;
613 static short *table2;
614 int tsize = param_set->tsize;
617 table1 = vcalloc(tsize, sizeof(short));
618 table2 = vcalloc(tsize, sizeof(short));
620 int i, j, num = number-1;
621 for (i = 0; i < num; ++i)
624 dist_mat[i][j] = dist_mat[j][i]= euclidean_dist(table_f, file_positions[sequence_group[i]], file_positions[sequence_group[j]], table1, table2, tsize);
626 for (; j < number; ++j)
628 dist_mat[i][j] = dist_mat[j][i] = euclidean_dist_half(table_f, file_positions[sequence_group[j]], table1, table2, tsize);
638 * Replaces the coded sequence with coded tuples
640 * \param coded_seq The coded sequence which will be replaced by the tuple number
641 * \param ktup Size of the ktup
642 * \param ng Coded alphabet size
643 * \param length Lengths of coded sequence
646 makepointtable_fast(int *coded_seq, //sequence
647 int ktup, //ktup size
649 int length) //length of coded_seq
657 prod=vcalloc ( ktup, sizeof (int));
658 for ( a=0; a<ktup; a++)
660 prod[ktup-a-1]=(int)pow(ng,a);
666 for (point=0,a=0; a<ktup; a++)
668 point+= *coded_seq++ *prod[a];
674 point -= *p * prod[0];
687 * \brief Calculates the number of occurences for each ktup.
689 * \param tables_f File to save the tables in.
690 * \param table Table to save the result in.
691 * \param pointt Array with all ktups listed one after another. Has to end with END_ARRAY.
692 * \param length length of \a table
695 makecompositiontable_fastal(FILE* tables_f, //File to save the tables in
696 int *table, //table to calculate in
697 int *pointt, //ktups array
698 int length) //length of the table
701 while(*pointt != END_ARRAY )
706 for (point = 0; point < length; ++point)
708 if (table[point] > 0)
709 fprintf(tables_f, "%i %i\n", point, table[point]);
711 fprintf(tables_f, "*\n");
717 make_fast_tree(char *file_name,
722 make_partTree(file_name, "TREE_OUT", ktup, n);
729 * \brief Reads ktup_table from file
731 * \param table Table to save the file content in.
732 * \param tables_f File in which the tables are stored.
733 * \param index Position of the table in \a tables_f
736 get_table(short *table, //Table to save the readings in
737 FILE* tables_f, //File with tables
738 long index) //index positin of ktup-tables
740 fseek(tables_f, index, SEEK_SET);
741 const int LINE_LENGTH = 101;
742 char line[LINE_LENGTH];
743 fgets(line, LINE_LENGTH, tables_f);
749 while (line[0] != '*')
751 result = strtok( line, delims );
753 table[code] = atoi(strtok( NULL, delims));
754 fgets(line, LINE_LENGTH, tables_f);
761 * \brief calculates the euclidean ktub distance between two sequences
763 * @param ktup_f, ktup_file
764 * @param pos1 position of sequence 1 in \a ktup_f
765 * @param pos2 position of sequence 2 in \a ktup_f
766 * @param table1 Saves the number of occurences for each ktup in sequence 1
767 * @param table2 Saves the number of occurences for each ktup in sequence 2
770 euclidean_dist(FILE* ktup_f, //ktup_file
771 long pos1, //position of table1
772 long pos2, //position of table2
773 short *table1, //table to save ktups in
774 short *table2, //table to save ktups in
777 const int LINE_LENGTH = 101;
778 char line[LINE_LENGTH];
785 fseek(ktup_f, pos1, SEEK_SET);
786 fgets(line, LINE_LENGTH, ktup_f);
788 for (i = 0; i < length; ++i)
793 while (line[0] != '*')
795 result = strtok( line, delims );
797 table1[code] = atoi(strtok( NULL, delims));
798 fgets(line, LINE_LENGTH, ktup_f);
800 fseek(ktup_f, pos2, SEEK_SET);
801 fgets(line, LINE_LENGTH, ktup_f);
802 while (line[0] != '*')
804 result = strtok( line, delims );
806 table2[code] = atoi(strtok( NULL, delims));
807 fgets(line, LINE_LENGTH, ktup_f);
811 for (i = 0; i < length; ++i)
813 dist += (table1[i]-table2[i])*(table1[i]-table2[i]);
821 * \brief calculates the euclidean ktub distance between two sequences.
823 * The difference to \a euclidean_dist is, that this uses the ktups stored in \a table1
824 * @param ktup_f, ktup_file
825 * @param pos2 position of sequence 2 in \a ktup_f
826 * @param table1 Saves the number of occurences for each ktup in sequence 1
827 * @param table2 Saves the number of occurences for each ktup in sequence 2
828 * \see euclidean_dist
831 euclidean_dist_half(FILE* ktup_f, //ktup_file
832 long pos2, //position of table1
833 short *table1, //table to save ktups in
834 short *table2, //table to save ktups in
837 const int LINE_LENGTH = 101;
838 char line[LINE_LENGTH];
845 fseek(ktup_f, pos2, SEEK_SET);
846 fgets(line, LINE_LENGTH, ktup_f);
848 for (i = 0; i < length; ++i)
852 while (line[0] != '*')
854 result = strtok( line, delims );
856 table2[code] = atoi(strtok( NULL, delims));
857 fgets(line, LINE_LENGTH, ktup_f);
861 for (i = 0; i < length; ++i)
863 dist += (table1[i]-table2[i])*(table1[i]-table2[i]);
872 * Makes an index of a file
875 make_pos_len_index_of_file(char *file_name, //file with sequences
876 char *ktable_f, //file with the ktup-tables
877 long **file_positions, //array to save the positions
878 int **seq_lengths, //array to save the sequence length
879 int ktup, //length of ktup
880 char *type) //type of the seuqence
882 //preparations for recoding sequence
888 if ( strm (type, "DNA") || strm (type, "RNA"))
890 gl=declare_char (5,13);
891 sprintf ( gl[ng++], "Aa");
892 sprintf ( gl[ng++], "Gg");
893 sprintf ( gl[ng++], "TtUu");
894 sprintf ( gl[ng++], "Cc");
895 sprintf ( gl[ng++], "NnRrYyDdMmWw");
899 gl=make_group_aa ( &ng, "mafft");
901 aa=vcalloc ( 256, sizeof (int));
902 for ( a=0; a<ng; a++)
904 for ( b=0; b< strlen (gl[a]); b++)
912 int tsize=(int)pow(ng, ktup);
913 param_set->tsize = tsize;
916 int *table=vcalloc ( tsize,sizeof (int));
919 //Reading and recoding squences
920 const int LINE_LENGTH = 501;
921 int *coded_seq = vcalloc(2*LINE_LENGTH, sizeof(int));
922 int allocated_mem = 2*LINE_LENGTH;
924 (*file_positions) = vcalloc(ENLARGEMENT_PER_STEP, sizeof(long));
925 (*seq_lengths) = vcalloc(ENLARGEMENT_PER_STEP, sizeof(int));
926 int current_size = ENLARGEMENT_PER_STEP;
929 FILE *file = fopen(file_name,"r");
933 char line[LINE_LENGTH];
935 int num_of_sequences = 0;
937 int mem_for_pos = ENLARGEMENT_PER_STEP;
942 FILE *tables_f = fopen(ktable_f, "w");
947 printf("FILE NOT FOUND\n");
953 while(fgets(line, LINE_LENGTH , file)!=NULL)
955 if ( str_len >= allocated_mem - LINE_LENGTH)
957 allocated_mem += LINE_LENGTH;
958 coded_seq = vrealloc(coded_seq, allocated_mem*sizeof(int));
962 int length = strlen(line);
965 if (num_of_sequences >0)
967 (*seq_lengths)[num_of_sequences-1] = str_len;
968 // printf("len: %i\n", str_len);
970 makepointtable_fast(coded_seq,ktup,ng, str_len);
972 (*file_positions)[num_of_sequences-1] = ftell(tables_f );
973 for (i=0; i < tsize; ++i)
975 makecompositiontable_fastal(tables_f, table, coded_seq,tsize );
982 if (num_of_sequences == mem_for_pos)
984 mem_for_pos += ENLARGEMENT_PER_STEP;
985 (*file_positions) = vrealloc((*file_positions), mem_for_pos * sizeof(long));
986 (*seq_lengths) = vrealloc((*seq_lengths), mem_for_pos * sizeof(int));
992 real_len = strlen(line);
993 if (line[real_len-1] == '\n')
995 for (i = 0; i < real_len; ++i)
997 coded_seq[str_len++] = aa[line[i]];
1003 (*seq_lengths)[num_of_sequences-1] = str_len;
1005 makepointtable_fast(coded_seq,ktup,ng, str_len);
1006 (*file_positions)[num_of_sequences] = ftell(tables_f );
1007 makecompositiontable_fastal(tables_f, table, coded_seq,tsize );
1010 return num_of_sequences;
1012 /*********************************COPYRIGHT NOTICE**********************************/
1013 /*© Centro de Regulacio Genomica */
1015 /*Cedric Notredame */
1016 /*Tue Oct 27 10:12:26 WEST 2009. */
1017 /*All rights reserved.*/
1018 /*This file is part of T-COFFEE.*/
1020 /* T-COFFEE is free software; you can redistribute it and/or modify*/
1021 /* it under the terms of the GNU General Public License as published by*/
1022 /* the Free Software Foundation; either version 2 of the License, or*/
1023 /* (at your option) any later version.*/
1025 /* T-COFFEE is distributed in the hope that it will be useful,*/
1026 /* but WITHOUT ANY WARRANTY; without even the implied warranty of*/
1027 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the*/
1028 /* GNU General Public License for more details.*/
1030 /* You should have received a copy of the GNU General Public License*/
1031 /* along with Foobar; if not, write to the Free Software*/
1032 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
1033 /*............................................... |*/
1034 /* If you need some more information*/
1035 /* cedric.notredame@europe.com*/
1036 /*............................................... |*/
1040 /*********************************COPYRIGHT NOTICE**********************************/