#define maxleaves 40 //maximum number of species allowed #define maxlength 13000 // {maximum length of a string} #define labellength 100 // {maximum length of the labels for species} #define maxstringlength 800 // maximum length for identifying string #define maxoffset 10 /*{the maximal allowed offset in matching two sequences; thus there are 2*maxoffset + 1 possibilities for deviation of alignments between two strings rather than maxlength}*/ #define true 1 #define false 0 #define boolean int #define CR '\015' #include #include int dchar( int, int); void finishup(void); char capitalize( char); void readinstrings(void); void Findt4aligned(void); void Findt4corrected4(void); void readlndata(void); void countk4v2(int,int,int,int,int); int typechange(char); int translatech(char); void countfreq(int ,int,int ,int ); void Findt4grouped(void); void countk(int , int, int , int, int); void Findt4groupedamino(void); int translatech20(char); void countk20(int, int, int, int, int); struct t4 { int first; int second; int third; int fourth; int aabb; int abab; int abba; float aabbreal; float ababreal; float abbareal; float aabbx; float ababx; float abbax; }; /* {description of a tree with 4 nodes; the tree has form (( first second) ( third fourth)) aabb gives the number of sites favoring ((1 2) (3 4)) abab gives the number of sites favoring ((1 3) (2 4)) abba gives the number of sites favoring ((1 4) (2 3))} */ int gap = 3, mismatch=1; //{penalties, so d(A,B) = mismatch, d(A,-) = gap} // finalstrings: array[1..4] of strings; char finalstrings[4][maxlength]; char ch; int u, vv; int datatype; int aligned, trial; //boolean int ignoregaps; //boolean int counter[maxleaves], stringlength[maxleaves]; //stringlength is the actual number of characters, starting from position 0 int actualleaves; //int countpositions; int actuallength; int flag; int idenlength; // length of the identification string int ssize; char alldata[maxlength][maxleaves]; // {all the data strings} char labels[maxleaves][labellength]; int errorcode; char identification1[maxstringlength]; FILE * data, *t4list, *outcomment; struct t4 t4record; char result[10]; //string for input int listtype; //type of manner for constructing the list //listtype = 1 corresponds to maximum parsimony //listtype = 2 corresponds to corrected parsimony //listtype = 3 corresponds to grouped corrected parsimony int kcounts[28][28][28][28]; float freq[28]; // counts of the various symbols in the dataset boolean symbolused[28]; boolean nucleotides, amino; int alphabet; int i,j,k,l; int dchar( x,y) char x,y; //{this function gives the result 0 if x = y and mismatch if x <> y; // it gives gap if exactly one of x and y is -} { if (x == y) return(0); else if ((x == '-') || (y == '-')) return(gap); else return(mismatch); } void finishup(void) { if (errorcode != 0) { fprintf(outcomment, "Error occurred with code %d.\n", errorcode); switch (errorcode) { case 4: fprintf(outcomment, "Lengths of species labels exceeded the limit.\n"); break; case 6: fprintf(outcomment, "Maximum offset tolerance for aligning strings was exceeded.\n"); break; case 7: fprintf(outcomment, "Maximum t4list size is exceeded.\n"); break; case 8: fprintf(outcomment, "Bad symbol is present in the strings.\n"); break; case 9: fprintf(outcomment, "Excessive number of loops in the alignment process\n"); break; case 10: fprintf(outcomment, "Number of species exceeds the limit.\n"); printf( "Number of species exceeds the limit.\n"); break; case 11: fprintf(outcomment, "Lengths of strings exceeds the limit.\n"); printf( "Lengths of strings exceeds the limit.\n"); break; } } fclose (t4list); fclose (data); fclose(outcomment); exit(0); } //finishup char capitalize( char ch) //char ch; //This function capitalizes all data symbols. { // int temp; // if ((ch >= 'A') && (ch <= 'Z')) return(ch); // else if ((ch >= 'a') && (ch <= 'z')) return (ch -32); // else if (ch == '-') return (ch); // else if (ch == '?') return ('-'); // else if (ch == '.') return ('-'); switch(ch) { case 'A' :return('A'); case 'B' :return ('B'); case 'C': return('C'); case 'D': return('D'); case 'E': return('E'); case 'F': return('F'); case 'G': return('G'); case 'H': return('H'); case 'I': return('I'); case 'J': return('J'); case 'K': return('K'); case 'L': return('L'); case 'M': return('M'); case 'N': return('N'); case 'O': return('O'); case 'P': return('P'); case 'Q': return('Q'); case 'R': return('R'); case 'S': return('S'); case 'T': return('T'); case 'U': return('U'); case 'V': return('V'); case 'W': return('W'); case 'X': return('X'); case 'Y': return('Y'); case 'Z': return('Z'); case 'a': return('A'); case 'b': return('B'); case 'c': return('C'); case 'd': return('D'); case 'e': return('E'); case 'f': return('F'); case 'g': return('G'); case 'h': return('H'); case 'i': return('I'); case 'j': return('J'); case 'k': return('K'); case 'l': return('L'); case 'm': return('M'); case 'n': return('N'); case 'o': return('O'); case 'p': return('P'); case 'q': return('Q'); case 'r': return('R'); case 's': return('S'); case 't': return('T'); case 'u': return('U'); case 'v': return('V'); case 'w': return('W'); case 'x': return('X'); case 'y': return('Y'); case 'z': return('Z'); case '.': return('-'); case '-': return('-'); case '?': return('-'); default : { printf("********Bad symbol in the dataset for procedure capitalize\n"); printf("Symbol is %c\n", ch); // printf("Species number is %d\n", i1); // printf("Character number is %d\n", counter[i1]); printf("Enter an integer to continue.\n"); getchar(); errorcode = 8; return('-'); // finishup; } //default } //switch } //capitalize void readinstrings() { int i1; int done, j1; int linecounter; char letter; if (datatype == 2) // {case of the strings interwoven in pages} { aligned = true; // {read in the first page of strings} for (i1 = 0; i1< actualleaves;i1++) counter[i1] = 0; for (i1 = 0; i1< actualleaves; i1++) { for (j1 = 0; j1< 13; j1++) { ch = fgetc(data); labels[i1][j1] = ch; } linecounter = 1; while ((counter[i1] < actuallength) && (linecounter <= 50)) { letter = ' '; while (letter == ' ') letter = fgetc(data); alldata[counter[i1]][i1] = capitalize(letter); counter[i1] = counter[i1] + 1; linecounter = linecounter + 1; } // {while} readlndata(); } // {for} readlndata(); // {continue reading pages of data} while ((counter[1] + 50) < actuallength) { for (i1 = 0; i1< actualleaves; i1++) { linecounter = 1; while (linecounter <= 50) { letter = ' '; while (letter == ' ') letter = fgetc(data); alldata[counter[i1]][i1] = capitalize(letter); counter[i1] = counter[i1] + 1; linecounter = linecounter + 1; } // {while} readlndata(); } // {for} readlndata(); } //{while} // {read the last page of data} for (i1 = 0; i1< actualleaves; i1++) // {read and ignore blanks} { while (counter[i1] < actuallength) { letter = ' '; while (letter == ' ') letter = fgetc(data); alldata[counter[i1]][i1] = capitalize(letter); counter[i1] = counter[i1] + 1; } // {while} readlndata(); } // {for} for (i1 = 1; i1<= actualleaves ;i1++) stringlength[i1]= counter[i1]; } // {if datatype = 2} if ((datatype == 3)||(datatype==5)) // {case of labels followed by the entire strings} { if (datatype == 3) aligned = true; else aligned = false; for (i1 = 0; i1 < actualleaves; i1++) { counter[i1] = 0; done = false; j1 = 0; // printf("About to read string for species %d.\n", i1+1); // {read in the labels, at most labellength characters terminated by *} while (! done) { ch= fgetc(data); if (ch != '*') { labels[i1][j1] = ch; // putchar(ch); j1 = j1 + 1; if (j1 >=labellength) { done = true; errorcode = 4; finishup(); } } else done = true; // {* terminates the labeling string} } // {while not done do} // putchar('\n'); //now the label is known but not the string} // writeln('Label for ', i1, ' is read.');} // printf("Label is read.\n"); done = false; while (!done) { ch = fgetc(data); if ((ch == '\n') || (ch == '\r')) { done = true; // readlndata(); } else { if (counter[i1] >= actuallength) { done = true; readlndata(); } else { // read(data, letter); // {now another character is found} if (ch != ' ') { alldata[counter[i1]][i1] = capitalize(ch); counter[i1] = counter[i1] + 1; // putchar(ch); } } } // {if not EOLn(data)} } // {while not done do} stringlength[i1] = counter[i1]; //stringlength is the actual number of characters, starting from position 0 } // {for i1 := 1 to actualleaves, datatype 3} } // {datatype = 3} } //readinstrings void readlndata(void) // finishes reading a line from file data with no data transfer //file * data; { char ch; ch = fgetc(data); while ( (ch != '\015') && (ch != EOF) && (ch != '\n')) {ch = fgetc(data); // putchar(ch); } } //readln void Findt4aligned() { /*{This procedure builds up the total list of maximum parsimony trees on 4 species chosen from the list of ssize species in matrix tree[i] for i = 1 to ssize. The list is placed in an array t4list in the form of a record. The optimal tree is of form ((t4list.first t4list.second) (t4list.third t4list.fourth)) The record t4list.aabb tells the number of sites favoring this best tree. The record t4list.abab tells the number of sites favoring the tree ((t4list.first t4list.third) (t4list.second t4list.fourth)) that groups first and third. The record t4list.abba tells the number of sites favoring the tree ((t4list.first t4list.fourth) (t4list.second t4list.third)) that groups first and fourth. The procedure assumes that the data are all aligned already.} */ int first1, second1, third1, fourth1; int kaabb, kabab, kabba; int i1; /* {The tree for 4 species will always be allowable with the four species at nodes 1,2,3,4; the node 5 will contain nodes 1 and 2; node 6 will contain nodes 3 and 4; node 7 will be the root, containing nodes 5 and 6. The entries node[i] tell the actual species in those nodes, whereas below[i] tells the node numbers below the node.} */ for (first1 = 0; first1= kabab) && (kaabb >= kabba)) { // {if kaabb is the maximum} t4record.first = first1; t4record.second = second1; t4record.third = third1; t4record.fourth = fourth1; t4record.aabb = kaabb; t4record.abab = kabab; t4record.abba = kabba; } else if ((kabab >= kaabb) && (kabab >= kabba)) { // {kabab is the maximum} t4record.first = first1; t4record.second = third1; t4record.third = second1; t4record.fourth = fourth1; t4record.aabb = kabab; t4record.abab = kaabb; t4record.abba = kabba; } else { // {kabba is the maximum} t4record.first = first1; t4record.second = fourth1; t4record.third = second1; t4record.fourth = third1; t4record.aabb = kabba; t4record.abab = kaabb; t4record.abba = kabab; } // {write it out} fprintf(t4list, "%2d %2d %2d %2d %3d %3d %3d \n", t4record.first+1, t4record.second+1, t4record.third+1, t4record.fourth+1, t4record.aabb, t4record.abab, t4record.abba ); } // {bunch of for's} fprintf(t4list, " 0 0 0 0 0 0 0 \n"); } // {FindT4Aligned} int translatech(char ch) //{This function takes a character ch and changes it into an integer from 1 to 27.} { if (ch == 'A') return 1; else if (ch =='B') return 2; else if (ch == 'C') return 3; else if (ch == 'D') return 4; else if (ch == 'E') return 5; else if (ch == 'F') return 6; else if (ch == 'G') return 7; else if (ch == 'H') return 8; else if (ch == 'I') return 9; else if (ch == 'J') return 10; else if (ch == 'K') return 11; else if (ch == 'L') return 12; else if (ch == 'M') return 13; else if (ch == 'N') return 14; else if (ch == 'O') return 15; else if (ch == 'P') return 16; else if (ch == 'Q') return 17; else if (ch == 'R') return 18; else if (ch == 'S') return 19; else if (ch == 'T') return 20; else if (ch == 'U') return 21; else if (ch == 'V') return 22; else if (ch == 'W') return 23; else if (ch == 'X') return 24; else if (ch == 'Y') return 25; else if (ch == 'Z') return 26; else if (ch =='.') return 27; else if (ch == '-') return 27; else return 27; } // {function} void countfreq(int first1,int second1,int third1,int fourth1) //{This procedure finds the raw frequencies of all symbols in the quartet} { int i; for (i = 1; i <= 5; i++) freq[i] = 0; for (i = 1; i<= actuallength; i++) { freq[typechange(alldata[i][first1])] = freq[typechange(alldata[i][first1])] + 1; freq[typechange(alldata[i][second1])] = freq[typechange(alldata[i][second1])] + 1; freq[typechange(alldata[i][third1])] = freq[typechange(alldata[i][third1])] + 1; freq[typechange(alldata[i][fourth1])] = freq[typechange(alldata[i][fourth1])] + 1; } } int typechange(char x) //{changes A to 1, C to 2, G to 3, T to 4, - to 5} { if (x == 'A') return 1; else if (x == 'C') return 2; else if (x == 'G') return 3; else if (x== 'T') return 4; else return 5; } void countk4v2(int first1, int second1, int third1, int fourth1, int i1) { int i,j,k,l; i = typechange(alldata[i1][first1]); j = typechange(alldata[i1][second1]); k = typechange(alldata[i1][third1]); l = typechange(alldata[i1][fourth1]); kcounts[i][j][k][l] = kcounts[i][j][k][l]+1; } // countk4v2 void Findt4corrected4() { /*{This procedure builds up the total list of maximum parsimony trees on 4 species chosen from the list of ssize species in matrix tree[i] for i = 1 to ssize. The list is placed in an array t4list in the form of a record. The optimal tree is of form ((t4list.first t4list.second) (t4list.third t4list.fourth)) The record t4list.aabb tells the number of sites favoring this best tree. The record t4list.abab tells the number of sites favoring the tree ((t4list.first t4list.third) (t4list.second t4list.fourth)) that groups first and third. The record t4list.abba tells the number of sites favoring the tree ((t4list.first t4list.fourth) (t4list.second t4list.third)) that groups first and fourth. The procedure assumes that the data are all aligned already. It assumes that the symbols are nucleotides.} */ int first1, second1, third1, fourth1; int kaabb, kabab, kabba; int i1; int typelimit; float kaabbreal, kababreal, kabbareal; float temp, tempinti, tempintj; /* {The tree for 4 species will always be allowable with the four species at nodes 1,2,3,4; the node 5 will contain nodes 1 and 2; node 6 will contain nodes 3 and 4; node 7 will be the root, containing nodes 5 and 6. The entries node[i] tell the actual species in those nodes, whereas below[i] tells the node numbers below the node.} */ if (ignoregaps) typelimit = 4; else typelimit = 5; for (first1 = 0; first1= kababreal) && (kaabbreal >= kabbareal)) { // {if kaabb is the maximum} t4record.first = first1; t4record.second = second1; t4record.third = third1; t4record.fourth = fourth1; t4record.aabbreal = kaabbreal; t4record.ababreal = kababreal; t4record.abbareal = kabbareal; } else if ((kababreal >= kaabbreal) && (kababreal >= kabbareal)) { // {kabab is the maximum} t4record.first = first1; t4record.second = third1; t4record.third = second1; t4record.fourth = fourth1; t4record.aabbreal = kababreal; t4record.ababreal = kaabbreal; t4record.abbareal = kabbareal; } else { // {kabba is the maximum} t4record.first = first1; t4record.second = fourth1; t4record.third = second1; t4record.fourth = third1; t4record.aabbreal = kabbareal; t4record.ababreal = kaabbreal; t4record.abbareal = kababreal; } // {write it out} fprintf(t4list, "%2d %2d %2d %2d %10.2f %10.2f %10.2f \n", t4record.first+1, t4record.second+1, t4record.third+1, t4record.fourth+1, t4record.aabbreal, t4record.ababreal, t4record.abbareal ); } // {bunch of for's} fprintf(t4list, " 0 0 0 0 0 0 0 \n"); } // {FindT4corrected4} void countk(int first1, int second1, int third1, int fourth1, int i1) { int i,j,k,l; i = translatech(alldata[i1][first1]); j = translatech(alldata[i1][second1]); k = translatech(alldata[i1][third1]); l = translatech(alldata[i1][fourth1]); kcounts[i][j][k][l] = kcounts[i][j][k][l]+1; } void Findt4grouped() { /*{This procedure builds up the total list of maximum parsimony trees on 4 species chosen from the list of ssize species in matrix tree[i] for i = 1 to ssize. The list is placed in an array t4list in the form of a record. The optimal tree is of form ((t4list.first t4list.second) (t4list.third t4list.fourth)) The record t4list.aabb tells the number of sites favoring this best tree. The record t4list.abab tells the number of sites favoring the tree ((t4list.first t4list.third) (t4list.second t4list.fourth)) that groups first and third. The record t4list.abba tells the number of sites favoring the tree ((t4list.first t4list.fourth) (t4list.second t4list.third)) that groups first and fourth. The procedure assumes that the data are all aligned already. It assumes that the symbols are from the alphabet, not necessarily even amino acids.} */ int first1, second1, third1, fourth1; float kaabb, kabab, kabba; int i1, i2, i, j; int typelimit; float kaabbreal, kababreal, kabbareal; float temp; float totalfreq; float dcoeff0, dcoeff1, dcoeff2, ccoeff; float realkaaaa; float kaaaa, kabbb, kabaa, kaaba, kaaab; /* {The tree for 4 species will always be allowable with the four species at nodes 1,2,3,4; the node 5 will contain nodes 1 and 2; node 6 will contain nodes 3 and 4; node 7 will be the root, containing nodes 5 and 6. The entries node[i] tell the actual species in those nodes, whereas below[i] tells the node numbers below the node.} */ if (ignoregaps) typelimit = 4; else typelimit = 5; for (first1 = 0; first1= kababreal) && (kaabbreal >= kabbareal)) { // {if kaabb is the maximum} t4record.first = first1; t4record.second = second1; t4record.third = third1; t4record.fourth = fourth1; t4record.aabbreal = kaabbreal; t4record.ababreal = kababreal; t4record.abbareal = kabbareal; } else if ((kababreal >= kaabbreal) && (kababreal >= kabbareal)) { // {kabab is the maximum} t4record.first = first1; t4record.second = third1; t4record.third = second1; t4record.fourth = fourth1; t4record.aabbreal = kababreal; t4record.ababreal = kaabbreal; t4record.abbareal = kabbareal; } else { // {kabba is the maximum} t4record.first = first1; t4record.second = fourth1; t4record.third = second1; t4record.fourth = third1; t4record.aabbreal = kabbareal; t4record.ababreal = kaabbreal; t4record.abbareal = kababreal; } // {write it out} fprintf(t4list, "%2d %2d %2d %2d %10.2f %10.2f %10.2f \n", t4record.first+1, t4record.second+1, t4record.third+1, t4record.fourth+1, t4record.aabbreal, t4record.ababreal, t4record.abbareal ); } // {bunch of for's} fprintf(t4list, " 0 0 0 0 0 0 0 \n"); } // {FindT4grouped} int translatech20(char ch) { if (ch == 'A') return 1; else if (ch == 'C') return 2; else if (ch == 'D') return 3; else if (ch == 'E') return 4; else if (ch == 'F') return 5; else if (ch == 'G') return 6; else if (ch == 'H') return 7; else if (ch == 'I') return 8; else if (ch == 'K') return 9; else if (ch == 'L') return 10; else if (ch == 'M') return 11; else if (ch == 'N') return 12; else if (ch == 'P') return 13; else if (ch == 'Q') return 14; else if (ch == 'R') return 15; else if (ch == 'S') return 16; else if (ch == 'T') return 17; else if (ch == 'V') return 18; else if (ch == 'W') return 19; else if (ch == 'Y') return 20; else return 21; } void countk20(int first1, int second1, int third1, int fourth1, int i1) { int i,j,k,l; i = translatech20(alldata[i1][first1]); j = translatech20(alldata[i1][second1]); k = translatech20(alldata[i1][third1]); l = translatech20(alldata[i1][fourth1]); kcounts[i][j][k][l] = kcounts[i][j][k][l]+1; } void Findt4groupedamino() { /*{This procedure builds up the total list of maximum parsimony trees on 4 species chosen from the list of ssize species in matrix tree[i] for i = 1 to ssize. The list is placed in an array t4list in the form of a record. The optimal tree is of form ((t4list.first t4list.second) (t4list.third t4list.fourth)) The record t4list.aabb tells the number of sites favoring this best tree. The record t4list.abab tells the number of sites favoring the tree ((t4list.first t4list.third) (t4list.second t4list.fourth)) that groups first and third. The record t4list.abba tells the number of sites favoring the tree ((t4list.first t4list.fourth) (t4list.second t4list.third)) that groups first and fourth. The procedure assumes that the data are all aligned already. It assumes that the symbols are amino acids.} */ int first1, second1, third1, fourth1; float kaabb, kabab, kabba; int i1, i2, i, j; float kaabbreal, kababreal, kabbareal; float temp; float totalfreq; float dcoeff0, dcoeff1, dcoeff2, ccoeff; float realkaaaa; float kaaaa, kabbb, kabaa, kaaba, kaaab; /* {The tree for 4 species will always be allowable with the four species at nodes 1,2,3,4; the node 5 will contain nodes 1 and 2; node 6 will contain nodes 3 and 4; node 7 will be the root, containing nodes 5 and 6. The entries node[i] tell the actual species in those nodes, whereas below[i] tells the node numbers below the node.} */ for (first1 = 0; first1= kababreal) && (kaabbreal >= kabbareal)) { // {if kaabb is the maximum} t4record.first = first1; t4record.second = second1; t4record.third = third1; t4record.fourth = fourth1; t4record.aabbreal = kaabbreal; t4record.ababreal = kababreal; t4record.abbareal = kabbareal; t4record.aabbx = kaabb; t4record.ababx = kabab; t4record.abbax = kabba; } else if ((kababreal >= kaabbreal) && (kababreal >= kabbareal)) { // {kabab is the maximum} t4record.first = first1; t4record.second = third1; t4record.third = second1; t4record.fourth = fourth1; t4record.aabbreal = kababreal; t4record.ababreal = kaabbreal; t4record.abbareal = kabbareal; t4record.aabbx = kabab; t4record.ababx = kaabb; t4record.abbax = kabba; } else { // {kabba is the maximum} t4record.first = first1; t4record.second = fourth1; t4record.third = second1; t4record.fourth = third1; t4record.aabbreal = kabbareal; t4record.ababreal = kaabbreal; t4record.abbareal = kababreal; t4record.aabbx = kabba; t4record.ababx = kaabb; t4record.abbax = kabab; } // {write it out} fprintf(t4list, "%2d %2d %2d %2d %10.2f %10.2f %10.2f * %10.2f %10.2f %10.2f \n", t4record.first+1, t4record.second+1, t4record.third+1, t4record.fourth+1, t4record.aabbreal, t4record.ababreal, t4record.abbareal, t4record.aabbx, t4record.ababx, t4record.abbax ); } // {bunch of for's} fprintf(t4list, " 0 0 0 0 0 0 0 \n"); //return 0; } // {FindT4groupedamino} void main () { int i1, j1; int answer; int done; // boolean char ch; void rdlndata(); int findt4aligned(); void readinstrings(); void finishup(); data = fopen("CreateT4.data", "r"); outcomment = fopen ("CreateT4k.output", "w"); t4list = fopen ("T4klist.CreateT4k", "w"); fscanf(data,"%d%d%d%d", &actualleaves, &actuallength, &flag, &datatype); printf("Actualleaves = %d, Actuallength = %d\n", actualleaves, actuallength); readlndata(); printf("About to read identification strings.\n"); done = false; idenlength = 0; while (!done) { ch = fgetc(data); if ((ch =='\n')||(ch == '\015') || (ch == EOF)||(ch =='\r')) done = true; else if (idenlength >= maxstringlength-1) done = true; else identification1[idenlength] = ch; if (!done) idenlength++; } printf("Identification string length %d\n", idenlength); for (i1=0; i1 maxleaves) || (actualleaves < 0)) { fprintf (outcomment, "Wrong number of species\n"); errorcode = 10; finishup(); } if ((actuallength > maxlength) || (actuallength < 0)) { fprintf (outcomment, "Wrong length of strings\n"); errorcode = 11; finishup(); } // {put blanks in the label positions} for (i1 = 0; i1< actualleaves; i1++) for (j1 = 0; j1< labellength; j1++) labels[i1][j1] = ' '; ssize = actualleaves; readinstrings(); putchar('\n'); for (i1=0; i1 2) listtype = 1; if (!(nucleotides) && (listtype == 2)) listtype = 3; if (listtype < 1) listtype = 1; // {prepare t4list} fprintf(t4list, "%d ", actualleaves); if (ignoregaps) fprintf(t4list, " 1 "); else fprintf(t4list, " 0 "); fprintf(t4list, "number of species; code 1 to ignore gaps, 0 to treat as symbol"); fprintf(t4list, " List of numbers of sites favoring the given trees.\n"); if (listtype == 1) fprintf(t4list, " Maximum Parsimony. "); else if (listtype == 2) fprintf(t4list, " Higher Order Parsimony for nucleotide strings. "); else if (listtype == 3) fprintf(t4list, " Grouped Higher Order Parsimony. "); if (ignoregaps) fprintf(t4list, " Sites containing gaps for quartets were ignored. "); else fprintf(t4list, " Sites containing gaps for quartets were counted. "); for (i1=0; i1