int gmx_dih(int argc,char *argv[]) { const char *desc[] = { "g_dih can do two things. The default is to analyze dihedral transitions", "by merely computing all the dihedral angles defined in your topology", "for the whole trajectory. When a dihedral flips over to another minimum", "an angle/time plot is made.[PAR]", "The opther option is to discretize the dihedral space into a number of", "bins, and group each conformation in dihedral space in the", "appropriate bin. The output is then given as a number of dihedral", "conformations sorted according to occupancy." }; static int mult = -1; static bool bSA = FALSE; t_pargs pa[] = { { "-sa", FALSE, etBOOL, {&bSA}, "Perform cluster analysis in dihedral space instead of analysing dihedral transitions." }, { "-mult", FALSE, etINT, {&mult}, "mulitiplicity for dihedral angles (by default read from topology)" } }; FILE *out; t_xrama *xr; t_topology *top; real **dih,*time; real dd; int i,nframes,maxframes=1000; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPX, NULL, NULL, ffREAD }, { efOUT, NULL, NULL, ffWRITE } }; #define NFILE asize(fnm) CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); if (mult != -1) fprintf(stderr,"Using %d for dihedral multiplicity rather than topology values\n",mult); snew(xr,1); init_rama(ftp2fn(efTRX,NFILE,fnm), ftp2fn(efTPX,NFILE,fnm),xr,3); top=read_top(ftp2fn(efTPX,NFILE,fnm),NULL); /* Brute force malloc, may be too big... */ snew(dih,xr->ndih); for(i=0; (i<xr->ndih); i++) snew(dih[i],maxframes); snew(time,maxframes); fprintf(stderr,"\n"); nframes = 0; while (new_data(xr)) { for(i=0; (i<xr->ndih); i++) { dd=xr->dih[i].ang*RAD2DEG; while (dd < 0) dd+=360; while (dd > 360) dd-=360; dih[i][nframes]=dd; } time[nframes]=xr->t; nframes++; if (nframes > maxframes) { maxframes += 1000; for(i=0; (i<xr->ndih); i++) srenew(dih[i],maxframes); srenew(time,maxframes); } } fprintf(stderr,"\nCalculated all dihedrals, now analysing...\n"); out=ftp2FILE(efOUT,NFILE,fnm,"w"); if (bSA) { /* Cluster and structure analysis */ ana_cluster(out,xr,dih,time,top,nframes,mult); } else { /* Analyse transitions... */ ana_trans(out,xr,dih,time,top,nframes); } fclose(out); thanx(stderr); return 0; }
static void analyze_clusters(int nf, t_clusters *clust, real **rmsd, int natom, t_atoms *atoms, rvec *xtps, real *mass, rvec **xx, real *time, int ifsize, atom_id *fitidx, int iosize, atom_id *outidx, char *trxfn, char *sizefn, char *transfn, char *ntransfn, char *clustidfn, bool bAverage, int write_ncl, int write_nst, real rmsmin,bool bFit, FILE *log,t_rgb rlo,t_rgb rhi) { FILE *fp=NULL; char buf[STRLEN],buf1[40],buf2[40],buf3[40],*trxsfn; int trxout=0,trxsout=0; int i,i1,cl,nstr,*structure,first=0,midstr; bool *bWrite=NULL; real r,clrmsd,midrmsd; rvec *xav=NULL; matrix zerobox; clear_mat(zerobox); ffprintf1(stderr,log,buf,"\nFound %d clusters\n\n",clust->ncl); trxsfn=NULL; if (trxfn) { /* do we write all structures? */ if (write_ncl) { trxsfn = parse_filename(trxfn, max(write_ncl,clust->ncl)); snew(bWrite,nf); } ffprintf2(stderr,log,buf,"Writing %s structure for each cluster to %s\n", bAverage ? "average" : "middle", trxfn); if (write_ncl) { /* find out what we want to tell the user: Writing [all structures|structures with rmsd > %g] for {all|first %d} clusters {with more than %d structures} to %s */ if (rmsmin>0.0) sprintf(buf1,"structures with rmsd > %g",rmsmin); else sprintf(buf1,"all structures"); buf2[0]=buf3[0]='\0'; if (write_ncl>=clust->ncl) { if (write_nst==0) sprintf(buf2,"all "); } else sprintf(buf2,"the first %d ",write_ncl); if (write_nst) sprintf(buf3," with more than %d structures",write_nst); sprintf(buf,"Writing %s for %sclusters%s to %s\n",buf1,buf2,buf3,trxsfn); ffprintf(stderr,log,buf); } /* Prepare a reference structure for the orientation of the clusters */ if (bFit) reset_x(ifsize,fitidx,natom,NULL,xtps,mass); trxout = open_trx(trxfn,"w"); /* Calculate the average structure in each cluster, * * all structures are fitted to the first struture of the cluster */ snew(xav,natom); } if (transfn || ntransfn) ana_trans(clust, nf, transfn, ntransfn, log,rlo,rhi); if (clustidfn) { fp=xvgropen(clustidfn,"Clusters",xvgr_tlabel(),"Cluster #"); fprintf(fp,"@ s0 symbol 2\n"); fprintf(fp,"@ s0 symbol size 0.2\n"); fprintf(fp,"@ s0 linestyle 0\n"); for(i=0; i<nf; i++) fprintf(fp,"%8g %8d\n",time[i],clust->cl[i]); ffclose(fp); } if (sizefn) { fp=xvgropen(sizefn,"Cluster Sizes","Cluster #","# Structures"); fprintf(fp,"@g%d type %s\n",0,"bar"); } snew(structure,nf); fprintf(log,"\n%3s | %3s %4s | %6s %4s | cluster members\n", "cl.","#st","rmsd","middle","rmsd"); for(cl=1; cl<=clust->ncl; cl++) { /* prepare structures (fit, middle, average) */ if (xav) for(i=0; i<natom;i++) clear_rvec(xav[i]); nstr=0; for(i1=0; i1<nf; i1++) if (clust->cl[i1] == cl) { structure[nstr] = i1; nstr++; if (trxfn && (bAverage || write_ncl) ) { if (bFit) reset_x(ifsize,fitidx,natom,NULL,xx[i1],mass); if (nstr == 1) first = i1; else if (bFit) do_fit(natom,mass,xx[first],xx[i1]); if (xav) for(i=0; i<natom; i++) rvec_inc(xav[i],xx[i1][i]); } } if (sizefn) fprintf(fp,"%8d %8d\n",cl,nstr); clrmsd = 0; midstr = 0; midrmsd = 10000; for(i1=0; i1<nstr; i1++) { r = 0; if (nstr > 1) { for(i=0; i<nstr; i++) if (i < i1) r += rmsd[structure[i]][structure[i1]]; else r += rmsd[structure[i1]][structure[i]]; r /= (nstr - 1); } if ( r < midrmsd ) { midstr = structure[i1]; midrmsd = r; } clrmsd += r; } clrmsd /= nstr; /* dump cluster info to logfile */ if (nstr > 1) { sprintf(buf1,"%5.3f",clrmsd); if (buf1[0] == '0') buf1[0] = ' '; sprintf(buf2,"%5.3f",midrmsd); if (buf2[0] == '0') buf2[0] = ' '; } else { sprintf(buf1,"%5s",""); sprintf(buf2,"%5s",""); } fprintf(log,"%3d | %3d%s | %6g%s |",cl,nstr,buf1,time[midstr],buf2); for(i=0; i<nstr; i++) { if ((i % 7 == 0) && i) sprintf(buf,"\n%3s | %3s %4s | %6s %4s |","","","","",""); else buf[0] = '\0'; i1 = structure[i]; fprintf(log,"%s %6g",buf,time[i1]); } fprintf(log,"\n"); /* write structures to trajectory file(s) */ if (trxfn) { if (write_ncl) for(i=0; i<nstr; i++) bWrite[i]=FALSE; if ( cl < write_ncl+1 && nstr > write_nst ) { /* Dump all structures for this cluster */ /* generate numbered filename (there is a %d in trxfn!) */ sprintf(buf,trxsfn,cl); trxsout = open_trx(buf,"w"); for(i=0; i<nstr; i++) { bWrite[i] = TRUE; if (rmsmin>0.0) for(i1=0; i1<i && bWrite[i]; i1++) if (bWrite[i1]) bWrite[i] = rmsd[structure[i1]][structure[i]] > rmsmin; if (bWrite[i]) write_trx(trxsout,iosize,outidx,atoms,i,time[structure[i]],zerobox, xx[structure[i]],NULL); } close_trx(trxsout); } /* Dump the average structure for this cluster */ if (bAverage) { for(i=0; i<natom; i++) svmul(1.0/nstr,xav[i],xav[i]); } else { for(i=0; i<natom; i++) copy_rvec(xx[midstr][i],xav[i]); if (bFit) reset_x(ifsize,fitidx,natom,NULL,xav,mass); } if (bFit) do_fit(natom,mass,xtps,xav); r = cl; write_trx(trxout,iosize,outidx,atoms,cl,time[midstr],zerobox,xav,NULL); } } /* clean up */ if (trxfn) { close_trx(trxout); sfree(xav); if (write_ncl) sfree(bWrite); } sfree(structure); if (trxsfn) sfree(trxsfn); }