📄 treesub.c
字号:
matout (F0, x, 1, com.ntime);
puts ("initial err in LSDistance()");
}
SetAncestor();
i=nls2((com.ntime>20&&noisy>=3?F0:NULL),
ss,x,com.ntime,fun_LS,NULL,testx,com.ns*(com.ns-1)/2,1e-6);
return (i);
}
double PairDistanceML(int is, int js)
{
/* This calculates the ML distance between is and js, the sum of ML branch
lengths along the path between is and js.
LSdistance() has to be called once to set ancestor before calling this
routine.
*/
int it, a;
double dij=0;
if(is==js) return(0);
if(is<js) { it=is; is=js; js=it; }
it=is*(is-1)/2+js;
for (a=is; a!=ancestor[it]; a=nodes[a].father)
dij += nodes[a].branch;
for (a=js; a!=ancestor[it]; a=nodes[a].father)
dij += nodes[a].branch;
return(dij);
}
int GroupDistances()
{
/* This calculates average group distances by summing over the ML
branch lengths */
int newancestor=0, i,j, ig,jg;
/* int ngroup=2, Ningroup[10], group[200]={1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; */ /* dloop for HC200.paup */
int ngroup=10, Ningroup[10], group[115]={
10, 9, 9, 9, 9, 9, 9, 9, 9, 10,
9, 9, 3, 3, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 2, 2, 2, 2, 2, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
6, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8}; /* dloop data for Anne Yoder, ns=115 */
double dgroup, npairused;
/* ngroup=2; for(j=0;j<com.ns; j++) group[j]=1+(group[j]>2); */
for(j=0;j<ngroup;j++) Ningroup[j]=0;
for(j=0;j<com.ns; j++) Ningroup[group[j]-1]++;
printf("\n# sequences in group:");
matIout(F0,Ningroup,1,ngroup);
if(ancestor==NULL) {
newancestor=1;
ancestor=(int*)realloc(ancestor, com.ns*(com.ns-1)/2*sizeof(int));
if(ancestor==NULL) error2("oom ancestor");
}
SetAncestor();
for(ig=0; ig<ngroup; ig++) {
printf("\ngroup %2d",ig+1);
for(jg=0; jg<ig+1; jg++) {
dgroup=0; npairused=0;
for(i=0;i<com.ns;i++) for(j=0;j<com.ns;j++) {
if(i!=j && group[i]==ig+1 && group[j]==jg+1) {
dgroup += PairDistanceML(i, j);
npairused++;
}
}
dgroup/=npairused;
printf("%9.4f", dgroup);
/* printf("%6.1f", dgroup/0.2604*5); */ /* 0.2604, 0.5611 */
}
}
if(newancestor==1) free(ancestor);
return(0);
}
#endif
#ifdef NODESTRUCTURE
void BranchToNode (void)
{
/* tree.root need to be specified before calling this
*/
int i, from, to;
tree.nnode=tree.nbranch+1;
/*
if (tree.root<0 || tree.root>com.ns*2-2)
{ printf ("root at %d", tree.root+1); error2("tree root"); }
*/
FOR (i,tree.nnode)
{ nodes[i].father=nodes[i].ibranch=-1; nodes[i].nson=0; }
FOR (i,tree.nbranch) {
from=tree.branches[i][0];
to =tree.branches[i][1];
nodes[from].sons[nodes[from].nson++]=to;
nodes[to].father=from;
nodes[to].ibranch=i;
}
/*
printf("\nNode\n%7s%7s%7s%7s%7s\n","father","node","branch","nson:","sons");
FOR (i, tree.nnode) {
printf ("\n%7d%7d%7d:%6d ",
nodes[i].father+1, i+1, nodes[i].ibranch+1, nodes[i].nson);
FOR(j, nodes[i].nson) printf (" %2d", nodes[i].sons[j]+1);
}
*/
}
void NodeToBranchSub (int inode);
void NodeToBranchSub (int inode)
{
int i, ison;
FOR (i, nodes[inode].nson) {
tree.branches[tree.nbranch][0]=inode;
tree.branches[tree.nbranch][1]=ison=nodes[inode].sons[i];
nodes[ison].ibranch=tree.nbranch++;
if(nodes[ison].nson>0) NodeToBranchSub(ison);
}
}
void NodeToBranch (void)
{
tree.nbranch=0;
NodeToBranchSub (tree.root);
if (tree.nnode!=tree.nbranch+1) puts ("nd!=nb+1");
}
void ClearNode (int inode)
{
/* a source of confusion. Try not to use this routine.
*/
nodes[inode].father=nodes[inode].ibranch=-1;
nodes[inode].nson=0;
nodes[inode].branch=nodes[inode].divtime=0;
/* nodes[inode].label=0; */
/* nodes[inode].branch=0; clear node structure only, not branch lengths */
/* FOR (i, com.ns) nodes[inode].sons[i]=-1; */
}
int ReadaTreeB (FILE *ftree, int popline)
{
char line[255];
int i,j, state=0, YoungAncestor=0, nodemark[NS*2-1]={0};
fscanf (ftree, "%d", &tree.nbranch);
FOR (j, tree.nbranch) {
FOR (i,2) {
if (fscanf (ftree, "%d", & tree.branches[j][i]) != 1) state=-1;
tree.branches[j][i]--;
if(tree.branches[j][i]<0 || tree.branches[j][i]>com.ns*2-1)
error2("ReadaTreeB: node numbers out of range");
}
nodemark[tree.branches[j][1]]++;
if (tree.branches[j][0]<com.ns)
{ YoungAncestor=1; nodemark[tree.branches[j][0]]++; }
printf ("\nBranch #%3d: %3d -> %3d",j+1,tree.branches[j][0]+1,tree.branches[j][1]+1);
}
if(popline) fgets(line, 254, ftree);
for(i=0,tree.root=-1; i<tree.nbranch; i++)
if(nodemark[tree.branches[i][0]]==0) tree.root=tree.branches[i][0];
for(i=0; i<com.ns; i++)
if(nodemark[i]==0) {
matIout(F0,nodemark,1,com.ns);
error2("branch specification of tree");
}
if(YoungAncestor) puts("Ancestors in the data? Check lkl carefully.");
/*
com.ntime = com.clock ? (tree.nbranch+1)-com.ns+(tree.root<com.ns)
: tree.nbranch;
*/
BranchToNode ();
return (state);
}
int OutaTreeB (FILE *fout)
{
int j;
char *fmt[]={" %3d..%-3d", " %2d..%-2d"};
FOR (j, tree.nbranch)
fprintf(fout, fmt[0], tree.branches[j][0]+1,tree.branches[j][1]+1);
return (0);
}
int GetTreeFileType(FILE *ftree, int *ntree, int *pauptree, int shortform);
int GetTreeFileType(FILE *ftree, int *ntree, int *pauptree, int shortform)
{
/* paupstart="begin trees" and paupend="translate" identify paup tree files.
paupch=";" will be the last character before the list of trees.
Modify if necessary.
*/
int i,k, lline=32000, ch=0, paupch=';';
char line[32000];
char *paupstart="begin tree", *paupend="translate";
*pauptree=0;
k=fscanf(ftree,"%d%d",&i,ntree);
if(k==2 && i==com.ns) return(0); /* old paml style */
else if(k==1) { *ntree=i; return(0); } /* phylip & molphy style */
while(ch!='(' && !isalnum(ch)) ch=fgetc(ftree); /* treeview style */
if(ch=='(') { *ntree=-1; ungetc(ch,ftree); return(0); }
puts("\n# seqs in tree file does not match. Read as the nexus format.");
for ( ; ; ) {
if(fgets(line,lline,ftree)==NULL) error2("tree err1: EOF");
strcase(line,0);
if (strstr(line,paupstart)) { *pauptree=1; *ntree=-1; break; }
}
if(shortform) return(0);
for ( ; ; ) {
if(fgets(line,lline,ftree)==NULL) error2("tree err2: EOF");
strcase(line,0);
if (strstr(line,paupend)) break;
}
for ( ; ; ) {
if((ch=fgetc(ftree))==EOF) error2("tree err3: EOF");
if (ch==paupch) break;
}
if(fgets(line,lline,ftree)==NULL) error2("tree err4: EOF");
return(0);
}
int PaupTreeRubbish(FILE *ftree);
int PaupTreeRubbish(FILE *ftree)
{
/* This reads out the string in front of the tree in the nexus format,
typically "tree PAUP_1 = [&U]" with "[&U]" optional
*/
int ch;
char line[10000], *paup1="tree", treename[64], c;
fscanf(ftree,"%s",line);
strcase(line,0);
if (strstr(line,paup1)==NULL) return(-1);
fscanf(ftree, "%s%s%c", treename, line, &c);
for (; ;) {
if((ch=fgetc(ftree))==EOF) {
puts("err or end of treefile: expect ]");
return(-1);
}
else if (ch==']') break;
else if (ch=='(') error2("err treefile: strange");
}
return(0);
}
int ReadaTreeN (FILE *ftree, int *haslength, int *haslabel, int popline)
{
/* Read a tree from ftree, using the parenthesis node representation of trees.
*length_label = 1 if the tree has lengths and
= 2 if the tree has labels
= 3 if the tree has lengths and labels
Branch lengths are read in nodes[].branch, and branch (node) labels (integers) are
preceeded by # and read in nodes[].label.
Both names and numbers for species are accepted.
Species names are considered case-sensitive, with trailing blanks ignored;
they have to match the names in the sequence data file.
*/
int cnode, cfather=-1; /* current node and father */
int inodeb=0; /* node number that will have the next branch length */
int i,j, level=0, hasname, ch=' ', lline=10000;
char check[NS], line[10000], delimiters[]="(),:#$;";
*haslength=0, *haslabel=0;
tree.nnode=com.ns; tree.nbranch=0;
FOR(i,2*com.ns-1) {
nodes[i].father=nodes[i].ibranch=-1;
nodes[i].nson=0; nodes[i].label=0; nodes[i].branch=0;
if(com.clock<3 || i>com.ns) nodes[i].divtime=0; /* note clock==3 */
}
while(isspace(ch)) ch=fgetc(ftree); /* skip spaces */
ungetc(ch,ftree);
if (isdigit(ch)) { ReadaTreeB(ftree,popline); return(0); }
FOR(i,com.ns) check[i]=0;
for (;;) {
ch = fgetc (ftree);
if (ch==EOF) return(-1);
else if (!isgraph(ch)) continue;
else if (ch=='(') {
level++;
cnode=tree.nnode++;
if (cfather>=0) {
nodes[cfather].sons[nodes[cfather].nson++] = cnode;
nodes[cnode].father=cfather;
tree.branches[tree.nbranch][0]=cfather;
tree.branches[tree.nbranch][1]=cnode;
nodes[cnode].ibranch=tree.nbranch++;
}
else
tree.root=cnode;
cfather=cnode;
}
else if (ch==')') { level--; inodeb=cfather; cfather=nodes[cfather].father; }
else if (ch==':') { *haslength=1; fscanf(ftree,"%lf",&nodes[inodeb].branch); }
else if (ch=='#'||ch=='$') { *haslabel=1; fscanf(ftree,"%lf",&nodes[inodeb].label); }
else if (ch==',') ;
else if (ch==';' && level!=0) error2("; in treefile");
else { /* read species name or number */
line[0]=(char)ch; line[1]=(char)fgetc(ftree);
/* if(line[1]==(char)EOF) error2("eof in tree file"); */
/* this breaks down if the name has numbers such as 123ad */
if (com.ns<10 && isdigit(line[0]) && line[0]!='0' && isdigit(line[1]))
{ ungetc(line[1], ftree); line[1]=0; }
else
for (i=1; i<lline; ) { /* read species name until a delimiter */
if (strchr(delimiters,line[i]) || line[i]==(char)EOF || line[i]=='\n')
{ ungetc(line[i],ftree); line[i]=0; break; }
line[++i]=(char)fgetc(ftree);
}
for(j=i-1;j>0;j--) /* trim spaces*/
if(isgraph(line[j])) break; else line[j]=0;
for(i=0,hasname=0; line[i]; i++) /* name or number? */
if(!isdigit(line[i])) { hasname=1; break; }
if (hasname) { /* name */
for (i=0; i<com.ns; i++) if (!strcmp(line,com.spname[i])) break;
if ((cnode=i)==com.ns)
printf("\nSpecies %s?\n", line);
}
else { /* number */
sscanf(line, "%d", &cnode); cnode--;
if (cnode<0 || cnode>=com.ns) {
printf("\nReadaTreeN: species %d not in data.\n",cnode+1);
exit(-1);
}
}
nodes[cnode].father=cfather;
nodes[cfather].sons[nodes[cfather].nson++]=cnode;
tree.branches[tree.nbranch][0]=cfather;
tree.branches[tree.nbranch][1]=cnode;
nodes[cnode].ibranch=tree.nbranch++;
check[inodeb=cnode]++;
}
if (level<=0) break;
}
/* read breanch length and label for the root if any */
for ( ; ; ) {
while(isspace(ch=fgetc(ftree)) && ch!='\n') ;
if (ch==':') fscanf(ftree, "%lf", &nodes[tree.root].branch);
else if (ch=='#'||ch=='$') { *haslabel=1; fscanf(ftree,"%lf",&nodes[tree.root].label); }
else { ungetc(ch,ftree); break; }
}
if (popline) fgets (line, lline, ftree);
if (tree.nnode != tree.nbranch+1) {
printf ("\nnnode%6d != nb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -