t_topology *read_top(char *fn) { int step,natoms; real t,lambda; t_topology *top; snew(top,1); read_tpx(fn,&step,&t,&lambda,NULL,NULL, &natoms,NULL,NULL,NULL,top); return top; }
int cmain(int argc,char *argv[]) { int step,natoms; real t,lambda; t_inputrec ir; t_topology top; matrix box; rvec *x,*v,*f; t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efXML, "-r", NULL, ffREAD }, { efXML, "-o", NULL, ffWRITE } }; #define NFILE asize(fnm) CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,0,NFILE,fnm,0,NULL,0,NULL,0,NULL); init_top(&top); if (opt2bSet("-r",NFILE,fnm)) read_xml(opt2fn("-r",NFILE,fnm),&step,&t,&lambda,&ir, box,&natoms,&x,&v,&f,&top); else { t_tpxheader tpx; read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&tpx,FALSE); snew(x,tpx.natoms); snew(v,tpx.natoms); f = NULL; read_tpx(ftp2fn(efTPX,NFILE,fnm),&step,&t,&lambda,&ir, box,&natoms,x,v,f,&top); } /*write_xml(opt2fn("-o",NFILE,fnm),step,t,lambda,&ir,box,natoms,x,v,f,&top);*/ return 0; }
int main(int argc,char *argv[]) { static char *desc[] = { "The [TT]pmetest[tt] program tests the scaling of the PME code. When only given", "a [TT].tpr[tt] file it will compute PME for one frame. When given a trajectory", "it will do so for all the frames in the trajectory. Before the PME", "routine is called the coordinates are sorted along the X-axis.[PAR]", "As an extra service to the public the program can also compute", "long-range Coulomb energies for components of the system. When the", "[TT]-groups[tt] flag is given to the program the energy groups", "from the [TT].tpr[tt] file will be read, and half an energy matrix computed." }; t_commrec *cr,*mcr; static t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efTRN, "-o", NULL, ffWRITE }, { efLOG, "-g", "pme", ffWRITE }, { efTRX, "-f", NULL, ffOPTRD }, { efXVG, "-x", "ener-pme", ffWRITE } }; #define NFILE asize(fnm) /* Command line options ! */ static gmx_bool bVerbose=FALSE; static gmx_bool bOptFFT=FALSE; static gmx_bool bSort=FALSE; static int ewald_geometry=eewg3D; static int nnodes=1; static int pme_order=0; static rvec grid = { -1, -1, -1 }; static real rc = 0.0; static real dtol = 0.0; static gmx_bool bGroups = FALSE; static t_pargs pa[] = { { "-np", FALSE, etINT, {&nnodes}, "Number of nodes, must be the same as used for [TT]grompp[tt]" }, { "-v", FALSE, etBOOL,{&bVerbose}, "Be loud and noisy" }, { "-sort", FALSE, etBOOL,{&bSort}, "Sort coordinates. Crucial for domain decomposition." }, { "-grid", FALSE, etRVEC,{&grid}, "Number of grid cells in X, Y, Z dimension (if -1 use from [TT].tpr[tt])" }, { "-order", FALSE, etINT, {&pme_order}, "Order of the PME spreading algorithm" }, { "-groups", FALSE, etBOOL, {&bGroups}, "Compute half an energy matrix based on the energy groups in your [TT].tpr[tt] file" }, { "-rc", FALSE, etREAL, {&rc}, "Rcoulomb for Ewald summation" }, { "-tol", FALSE, etREAL, {&dtol}, "Tolerance for Ewald summation" } }; FILE *fp; t_inputrec *ir; t_topology top; t_tpxheader tpx; t_nrnb nrnb; t_nsborder *nsb; t_forcerec *fr; t_mdatoms *mdatoms; char title[STRLEN]; int natoms,step,status,i,ncg,root; real t,lambda,ewaldcoeff,qtot; rvec *x,*f,*xbuf; int *index; gmx_bool bCont; real *charge,*qbuf,*qqbuf; matrix box; /* Start the actual parallel code if necessary */ cr = init_par(&argc,&argv); root = 0; if (MASTER(cr)) CopyRight(stderr,argv[0]); /* Parse command line on all processors, arguments are passed on in * init_par (see above) */ parse_common_args(&argc,argv, PCA_KEEP_ARGS | PCA_NOEXIT_ON_ARGS | PCA_BE_NICE | PCA_CAN_SET_DEFFNM | (MASTER(cr) ? 0 : PCA_QUIET), NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); #ifndef GMX_MPI if (nnodes > 1) gmx_fatal(FARGS,"GROMACS compiled without MPI support - can't do parallel runs"); #endif /* Open log files on all processors */ open_log(ftp2fn(efLOG,NFILE,fnm),cr); snew(ir,1); if (MASTER(cr)) { /* Read tpr file etc. */ read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&tpx,FALSE,NULL,NULL); snew(x,tpx.natoms); read_tpx(ftp2fn(efTPX,NFILE,fnm),&step,&t,&lambda,ir, box,&natoms,x,NULL,NULL,&top); /* Charges */ qtot = 0; snew(charge,natoms); for(i=0; (i<natoms); i++) { charge[i] = top.atoms.atom[i].q; qtot += charge[i]; } /* Grid stuff */ if (opt2parg_bSet("-grid",asize(pa),pa)) { ir->nkx = grid[XX]; ir->nky = grid[YY]; ir->nkz = grid[ZZ]; } /* Check command line parameters for consistency */ if ((ir->nkx <= 0) || (ir->nky <= 0) || (ir->nkz <= 0)) gmx_fatal(FARGS,"PME grid = %d %d %d",ir->nkx,ir->nky,ir->nkz); if (opt2parg_bSet("-rc",asize(pa),pa)) ir->rcoulomb = rc; if (ir->rcoulomb <= 0) gmx_fatal(FARGS,"rcoulomb should be > 0 (not %f)",ir->rcoulomb); if (opt2parg_bSet("-order",asize(pa),pa)) ir->pme_order = pme_order; if (ir->pme_order <= 0) gmx_fatal(FARGS,"pme_order should be > 0 (not %d)",ir->pme_order); if (opt2parg_bSet("-tol",asize(pa),pa)) ir->ewald_rtol = dtol; if (ir->ewald_rtol <= 0) gmx_fatal(FARGS,"ewald_tol should be > 0 (not %f)",ir->ewald_rtol); } else { init_top(&top); } /* Add parallellization code here */ snew(nsb,1); if (MASTER(cr)) { ncg = top.blocks[ebCGS].multinr[0]; for(i=0; (i<cr->nnodes-1); i++) top.blocks[ebCGS].multinr[i] = min(ncg,(ncg*(i+1))/cr->nnodes); for( ; (i<MAXNODES); i++) top.blocks[ebCGS].multinr[i] = ncg; } if (PAR(cr)) { /* Set some variables to zero to avoid core dumps */ ir->opts.ngtc = ir->opts.ngacc = ir->opts.ngfrz = ir->opts.ngener = 0; #ifdef GMX_MPI /* Distribute the data over processors */ MPI_Bcast(&natoms,1,MPI_INT,root,MPI_COMM_WORLD); MPI_Bcast(ir,sizeof(*ir),MPI_BYTE,root,MPI_COMM_WORLD); MPI_Bcast(&qtot,1,GMX_MPI_REAL,root,MPI_COMM_WORLD); #endif /* Call some dedicated communication routines, master sends n-1 times */ if (MASTER(cr)) { for(i=1; (i<cr->nnodes); i++) { mv_block(i,&(top.blocks[ebCGS])); mv_block(i,&(top.atoms.excl)); } } else { ld_block(root,&(top.blocks[ebCGS])); ld_block(root,&(top.atoms.excl)); } if (!MASTER(cr)) { snew(charge,natoms); snew(x,natoms); } #ifdef GMX_MPI MPI_Bcast(charge,natoms,GMX_MPI_REAL,root,MPI_COMM_WORLD); #endif } ewaldcoeff = calc_ewaldcoeff(ir->rcoulomb,ir->ewald_rtol); if (bVerbose) pr_inputrec(stdlog,0,"Inputrec",ir); /* Allocate memory for temp arrays etc. */ snew(xbuf,natoms); snew(f,natoms); snew(qbuf,natoms); snew(qqbuf,natoms); snew(index,natoms); /* Initialize the PME code */ init_pme(stdlog,cr,ir->nkx,ir->nky,ir->nkz,ir->pme_order, natoms,FALSE,bOptFFT,ewald_geometry); /* MFlops accounting */ init_nrnb(&nrnb); /* Initialize the work division */ calc_nsb(stdlog,&(top.blocks[ebCGS]),cr->nnodes,nsb,0); nsb->nodeid = cr->nodeid; print_nsb(stdlog,"pmetest",nsb); /* Initiate forcerec */ mdatoms = atoms2md(stdlog,&top.atoms,ir->opts.nFreeze,ir->eI, ir->delta_t,0,ir->opts.tau_t,FALSE,FALSE); snew(fr,1); init_forcerec(stdlog,fr,ir,&top,cr,mdatoms,nsb,box,FALSE,NULL,NULL,FALSE); /* First do PME based on coordinates in tpr file, send them to * other processors if needed. */ if (MASTER(cr)) fprintf(stdlog,"-----\n" "Results based on tpr file %s\n",ftp2fn(efTPX,NFILE,fnm)); #ifdef GMX_MPI if (PAR(cr)) { MPI_Bcast(x[0],natoms*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD); MPI_Bcast(box[0],DIM*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD); MPI_Bcast(&t,1,GMX_MPI_REAL,root,MPI_COMM_WORLD); } #endif do_my_pme(stdlog,0,bVerbose,ir,x,xbuf,f,charge,qbuf,qqbuf,box,bSort, cr,nsb,&nrnb,&(top.atoms.excl),qtot,fr,index,NULL, bGroups ? ir->opts.ngener : 1,mdatoms->cENER); /* If we have a trajectry file, we will read the frames in it and compute * the PME energy. */ if (ftp2bSet(efTRX,NFILE,fnm)) { fprintf(stdlog,"-----\n" "Results based on trx file %s\n",ftp2fn(efTRX,NFILE,fnm)); if (MASTER(cr)) { sfree(x); natoms = read_first_x(&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); if (natoms != top.atoms.nr) gmx_fatal(FARGS,"natoms in trx = %d, in tpr = %d",natoms,top.atoms.nr); fp = xvgropen(ftp2fn(efXVG,NFILE,fnm),"PME Energy","Time (ps)","E (kJ/mol)"); } else fp = NULL; do { /* Send coordinates, box and time to the other nodes */ #ifdef GMX_MPI if (PAR(cr)) { MPI_Bcast(x[0],natoms*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD); MPI_Bcast(box[0],DIM*DIM,GMX_MPI_REAL,root,MPI_COMM_WORLD); MPI_Bcast(&t,1,GMX_MPI_REAL,root,MPI_COMM_WORLD); } #endif rm_pbc(&top.idef,nsb->natoms,box,x,x); /* Call the PME wrapper function */ do_my_pme(stdlog,t,bVerbose,ir,x,xbuf,f,charge,qbuf,qqbuf,box,bSort,cr, nsb,&nrnb,&(top.atoms.excl),qtot,fr,index,fp, bGroups ? ir->opts.ngener : 1,mdatoms->cENER); /* Only the master processor reads more data */ if (MASTER(cr)) bCont = read_next_x(status,&t,natoms,x,box); /* Check whether we need to continue */ #ifdef GMX_MPI if (PAR(cr)) MPI_Bcast(&bCont,1,MPI_INT,root,MPI_COMM_WORLD); #endif } while (bCont); /* Finish I/O, close files */ if (MASTER(cr)) { close_trx(status); ffclose(fp); } } if (bVerbose) { /* Do some final I/O about performance, might be useful in debugging */ fprintf(stdlog,"-----\n"); print_nrnb(stdlog,&nrnb); } /* Finish the parallel stuff */ if (gmx_parallel_env_initialized()) gmx_finalize(cr); /* Thank the audience, as usual */ if (MASTER(cr)) thanx(stderr); return 0; }
int gmx_nmeig(int argc, char *argv[]) { const char *desc[] = { "[TT]g_nmeig[tt] calculates the eigenvectors/values of a (Hessian) matrix,", "which can be calculated with [TT]mdrun[tt].", "The eigenvectors are written to a trajectory file ([TT]-v[tt]).", "The structure is written first with t=0. The eigenvectors", "are written as frames with the eigenvector number as timestamp.", "The eigenvectors can be analyzed with [TT]g_anaeig[tt].", "An ensemble of structures can be generated from the eigenvectors with", "[TT]g_nmens[tt]. When mass weighting is used, the generated eigenvectors", "will be scaled back to plain Cartesian coordinates before generating the", "output. In this case, they will no longer be exactly orthogonal in the", "standard Cartesian norm, but in the mass-weighted norm they would be.[PAR]", "This program can be optionally used to compute quantum corrections to heat capacity", "and enthalpy by providing an extra file argument [TT]-qcorr[tt]. See the GROMACS", "manual, Chapter 1, for details. The result includes subtracting a harmonic", "degree of freedom at the given temperature.", "The total correction is printed on the terminal screen.", "The recommended way of getting the corrections out is:[PAR]", "[TT]g_nmeig -s topol.tpr -f nm.mtx -first 7 -last 10000 -T 300 -qc [-constr][tt][PAR]", "The [TT]-constr[tt] option should be used when bond constraints were used during the", "simulation [BB]for all the covalent bonds[bb]. If this is not the case, ", "you need to analyze the [TT]quant_corr.xvg[tt] file yourself.[PAR]", "To make things more flexible, the program can also take virtual sites into account", "when computing quantum corrections. When selecting [TT]-constr[tt] and", "[TT]-qc[tt], the [TT]-begin[tt] and [TT]-end[tt] options will be set automatically as well.", "Again, if you think you know it better, please check the [TT]eigenfreq.xvg[tt]", "output." }; static gmx_bool bM = TRUE, bCons = FALSE; static int begin = 1, end = 50, maxspec = 4000; static real T = 298.15, width = 1; t_pargs pa[] = { { "-m", FALSE, etBOOL, {&bM}, "Divide elements of Hessian by product of sqrt(mass) of involved " "atoms prior to diagonalization. This should be used for 'Normal Modes' " "analysis" }, { "-first", FALSE, etINT, {&begin}, "First eigenvector to write away" }, { "-last", FALSE, etINT, {&end}, "Last eigenvector to write away" }, { "-maxspec", FALSE, etINT, {&maxspec}, "Highest frequency (1/cm) to consider in the spectrum" }, { "-T", FALSE, etREAL, {&T}, "Temperature for computing quantum heat capacity and enthalpy when using normal mode calculations to correct classical simulations" }, { "-constr", FALSE, etBOOL, {&bCons}, "If constraints were used in the simulation but not in the normal mode analysis (this is the recommended way of doing it) you will need to set this for computing the quantum corrections." }, { "-width", FALSE, etREAL, {&width}, "Width (sigma) of the gaussian peaks (1/cm) when generating a spectrum" } }; FILE *out, *qc, *spec; int status, trjout; t_topology top; gmx_mtop_t mtop; int ePBC; rvec *top_x; matrix box; real *eigenvalues; real *eigenvectors; real rdum, mass_fac, qcvtot, qutot, qcv, qu; int natoms, ndim, nrow, ncol, count, nharm, nvsite; char *grpname; int i, j, k, l, d, gnx; gmx_bool bSuck; atom_id *index; t_tpxheader tpx; int version, generation; real value, omega, nu; real factor_gmx_to_omega2; real factor_omega_to_wavenumber; real *spectrum = NULL; real wfac; output_env_t oenv; const char *qcleg[] = { "Heat Capacity cV (J/mol K)", "Enthalpy H (kJ/mol)" }; real * full_hessian = NULL; gmx_sparsematrix_t * sparse_hessian = NULL; t_filenm fnm[] = { { efMTX, "-f", "hessian", ffREAD }, { efTPX, NULL, NULL, ffREAD }, { efXVG, "-of", "eigenfreq", ffWRITE }, { efXVG, "-ol", "eigenval", ffWRITE }, { efXVG, "-os", "spectrum", ffOPTWR }, { efXVG, "-qc", "quant_corr", ffOPTWR }, { efTRN, "-v", "eigenvec", ffWRITE } }; #define NFILE asize(fnm) parse_common_args(&argc, argv, PCA_BE_NICE, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv); /* Read tpr file for volume and number of harmonic terms */ read_tpxheader(ftp2fn(efTPX, NFILE, fnm), &tpx, TRUE, &version, &generation); snew(top_x, tpx.natoms); read_tpx(ftp2fn(efTPX, NFILE, fnm), NULL, box, &natoms, top_x, NULL, NULL, &mtop); if (bCons) { nharm = get_nharm(&mtop, &nvsite); } else { nharm = 0; nvsite = 0; } top = gmx_mtop_t_to_t_topology(&mtop); bM = TRUE; ndim = DIM*natoms; if (opt2bSet("-qc", NFILE, fnm)) { begin = 7+DIM*nvsite; end = DIM*natoms; } if (begin < 1) { begin = 1; } if (end > ndim) { end = ndim; } printf("Using begin = %d and end = %d\n", begin, end); /*open Hessian matrix */ gmx_mtxio_read(ftp2fn(efMTX, NFILE, fnm), &nrow, &ncol, &full_hessian, &sparse_hessian); /* Memory for eigenvalues and eigenvectors (begin..end) */ snew(eigenvalues, nrow); snew(eigenvectors, nrow*(end-begin+1)); /* If the Hessian is in sparse format we can calculate max (ndim-1) eigenvectors, * and they must start at the first one. If this is not valid we convert to full matrix * storage, but warn the user that we might run out of memory... */ if ((sparse_hessian != NULL) && (begin != 1 || end == ndim)) { if (begin != 1) { fprintf(stderr, "Cannot use sparse Hessian with first eigenvector != 1.\n"); } else if (end == ndim) { fprintf(stderr, "Cannot use sparse Hessian to calculate all eigenvectors.\n"); } fprintf(stderr, "Will try to allocate memory and convert to full matrix representation...\n"); snew(full_hessian, nrow*ncol); for (i = 0; i < nrow*ncol; i++) { full_hessian[i] = 0; } for (i = 0; i < sparse_hessian->nrow; i++) { for (j = 0; j < sparse_hessian->ndata[i]; j++) { k = sparse_hessian->data[i][j].col; value = sparse_hessian->data[i][j].value; full_hessian[i*ndim+k] = value; full_hessian[k*ndim+i] = value; } } gmx_sparsematrix_destroy(sparse_hessian); sparse_hessian = NULL; fprintf(stderr, "Converted sparse to full matrix storage.\n"); } if (full_hessian != NULL) { /* Using full matrix storage */ nma_full_hessian(full_hessian, nrow, bM, &top, begin, end, eigenvalues, eigenvectors); } else { /* Sparse memory storage, allocate memory for eigenvectors */ snew(eigenvectors, ncol*end); nma_sparse_hessian(sparse_hessian, bM, &top, end, eigenvalues, eigenvectors); } /* check the output, first 6 eigenvalues should be reasonably small */ bSuck = FALSE; for (i = begin-1; (i < 6); i++) { if (fabs(eigenvalues[i]) > 1.0e-3) { bSuck = TRUE; } } if (bSuck) { fprintf(stderr, "\nOne of the lowest 6 eigenvalues has a non-zero value.\n"); fprintf(stderr, "This could mean that the reference structure was not\n"); fprintf(stderr, "properly energy minimized.\n"); } /* now write the output */ fprintf (stderr, "Writing eigenvalues...\n"); out = xvgropen(opt2fn("-ol", NFILE, fnm), "Eigenvalues", "Eigenvalue index", "Eigenvalue [Gromacs units]", oenv); if (output_env_get_print_xvgr_codes(oenv)) { if (bM) { fprintf(out, "@ subtitle \"mass weighted\"\n"); } else { fprintf(out, "@ subtitle \"not mass weighted\"\n"); } } for (i = 0; i <= (end-begin); i++) { fprintf (out, "%6d %15g\n", begin+i, eigenvalues[i]); } ffclose(out); if (opt2bSet("-qc", NFILE, fnm)) { qc = xvgropen(opt2fn("-qc", NFILE, fnm), "Quantum Corrections", "Eigenvector index", "", oenv); xvgr_legend(qc, asize(qcleg), qcleg, oenv); qcvtot = qutot = 0; } else { qc = NULL; } printf("Writing eigenfrequencies - negative eigenvalues will be set to zero.\n"); out = xvgropen(opt2fn("-of", NFILE, fnm), "Eigenfrequencies", "Eigenvector index", "Wavenumber [cm\\S-1\\N]", oenv); if (output_env_get_print_xvgr_codes(oenv)) { if (bM) { fprintf(out, "@ subtitle \"mass weighted\"\n"); } else { fprintf(out, "@ subtitle \"not mass weighted\"\n"); } } /* Spectrum ? */ spec = NULL; if (opt2bSet("-os", NFILE, fnm) && (maxspec > 0)) { snew(spectrum, maxspec); spec = xvgropen(opt2fn("-os", NFILE, fnm), "Vibrational spectrum based on harmonic approximation", "\\f{12}w\\f{4} (cm\\S-1\\N)", "Intensity [Gromacs units]", oenv); for (i = 0; (i < maxspec); i++) { spectrum[i] = 0; } } /* Gromacs units are kJ/(mol*nm*nm*amu), * where amu is the atomic mass unit. * * For the eigenfrequencies we want to convert this to spectroscopic absorption * wavenumbers given in cm^(-1), which is the frequency divided by the speed of * light. Do this by first converting to omega^2 (units 1/s), take the square * root, and finally divide by the speed of light (nm/ps in gromacs). */ factor_gmx_to_omega2 = 1.0E21/(AVOGADRO*AMU); factor_omega_to_wavenumber = 1.0E-5/(2.0*M_PI*SPEED_OF_LIGHT); for (i = begin; (i <= end); i++) { value = eigenvalues[i-begin]; if (value < 0) { value = 0; } omega = sqrt(value*factor_gmx_to_omega2); nu = 1e-12*omega/(2*M_PI); value = omega*factor_omega_to_wavenumber; fprintf (out, "%6d %15g\n", i, value); if (NULL != spec) { wfac = eigenvalues[i-begin]/(width*sqrt(2*M_PI)); for (j = 0; (j < maxspec); j++) { spectrum[j] += wfac*exp(-sqr(j-value)/(2*sqr(width))); } } if (NULL != qc) { qcv = cv_corr(nu, T); qu = u_corr(nu, T); if (i > end-nharm) { qcv += BOLTZ*KILO; qu += BOLTZ*T; } fprintf (qc, "%6d %15g %15g\n", i, qcv, qu); qcvtot += qcv; qutot += qu; } } ffclose(out); if (NULL != spec) { for (j = 0; (j < maxspec); j++) { fprintf(spec, "%10g %10g\n", 1.0*j, spectrum[j]); } ffclose(spec); } if (NULL != qc) { printf("Quantum corrections for harmonic degrees of freedom\n"); printf("Use appropriate -first and -last options to get reliable results.\n"); printf("There were %d constraints and %d vsites in the simulation\n", nharm, nvsite); printf("Total correction to cV = %g J/mol K\n", qcvtot); printf("Total correction to H = %g kJ/mol\n", qutot); ffclose(qc); please_cite(stdout, "Caleman2011b"); } /* Writing eigenvectors. Note that if mass scaling was used, the eigenvectors * were scaled back from mass weighted cartesian to plain cartesian in the * nma_full_hessian() or nma_sparse_hessian() routines. Mass scaled vectors * will not be strictly orthogonal in plain cartesian scalar products. */ write_eigenvectors(opt2fn("-v", NFILE, fnm), natoms, eigenvectors, FALSE, begin, end, eWXR_NO, NULL, FALSE, top_x, bM, eigenvalues); thanx(stderr); return 0; }
static void clust_size(const char *ndx, const char *trx, const char *xpm, const char *xpmw, const char *ncl, const char *acl, const char *mcl, const char *histo, const char *tempf, const char *mcn, gmx_bool bMol, gmx_bool bPBC, const char *tpr, real cut, int nskip, int nlevels, t_rgb rmid, t_rgb rhi, int ndf, const output_env_t oenv) { FILE *fp, *gp, *hp, *tp; atom_id *index = NULL; int nindex, natoms; t_trxstatus *status; rvec *x = NULL, *v = NULL, dx; t_pbc pbc; char *gname; char timebuf[32]; gmx_bool bSame, bTPRwarn = TRUE; /* Topology stuff */ t_trxframe fr; t_tpxheader tpxh; gmx_mtop_t *mtop = NULL; int ePBC = -1; t_block *mols = NULL; gmx_mtop_atomlookup_t alook; t_atom *atom; int version, generation, ii, jj; real temp, tfac; /* Cluster size distribution (matrix) */ real **cs_dist = NULL; real tf, dx2, cut2, *t_x = NULL, *t_y, cmid, cmax, cav, ekin; int i, j, k, ai, aj, ci, cj, nframe, nclust, n_x, max_size = 0; int *clust_index, *clust_size, max_clust_size, max_clust_ind, nav, nhisto; t_rgb rlo = { 1.0, 1.0, 1.0 }; clear_trxframe(&fr, TRUE); sprintf(timebuf, "Time (%s)", output_env_get_time_unit(oenv)); tf = output_env_get_time_factor(oenv); fp = xvgropen(ncl, "Number of clusters", timebuf, "N", oenv); gp = xvgropen(acl, "Average cluster size", timebuf, "#molecules", oenv); hp = xvgropen(mcl, "Max cluster size", timebuf, "#molecules", oenv); tp = xvgropen(tempf, "Temperature of largest cluster", timebuf, "T (K)", oenv); if (!read_first_frame(oenv, &status, trx, &fr, TRX_NEED_X | TRX_READ_V)) { gmx_file(trx); } natoms = fr.natoms; x = fr.x; if (tpr) { snew(mtop, 1); read_tpxheader(tpr, &tpxh, TRUE, &version, &generation); if (tpxh.natoms != natoms) { gmx_fatal(FARGS, "tpr (%d atoms) and trajectory (%d atoms) do not match!", tpxh.natoms, natoms); } ePBC = read_tpx(tpr, NULL, NULL, &natoms, NULL, NULL, mtop); } if (ndf <= -1) { tfac = 1; } else { tfac = ndf/(3.0*natoms); } if (bMol) { if (ndx) { printf("Using molecules rather than atoms. Not reading index file %s\n", ndx); } GMX_RELEASE_ASSERT(mtop != NULL, "Trying to access mtop->mols from NULL mtop pointer"); mols = &(mtop->mols); /* Make dummy index */ nindex = mols->nr; snew(index, nindex); for (i = 0; (i < nindex); i++) { index[i] = i; } gname = gmx_strdup("mols"); } else { rd_index(ndx, 1, &nindex, &index, &gname); } alook = gmx_mtop_atomlookup_init(mtop); snew(clust_index, nindex); snew(clust_size, nindex); cut2 = cut*cut; nframe = 0; n_x = 0; snew(t_y, nindex); for (i = 0; (i < nindex); i++) { t_y[i] = i+1; } max_clust_size = 1; max_clust_ind = -1; do { if ((nskip == 0) || ((nskip > 0) && ((nframe % nskip) == 0))) { if (bPBC) { set_pbc(&pbc, ePBC, fr.box); } max_clust_size = 1; max_clust_ind = -1; /* Put all atoms/molecules in their own cluster, with size 1 */ for (i = 0; (i < nindex); i++) { /* Cluster index is indexed with atom index number */ clust_index[i] = i; /* Cluster size is indexed with cluster number */ clust_size[i] = 1; } /* Loop over atoms */ for (i = 0; (i < nindex); i++) { ai = index[i]; ci = clust_index[i]; /* Loop over atoms (only half a matrix) */ for (j = i+1; (j < nindex); j++) { cj = clust_index[j]; /* If they are not in the same cluster already */ if (ci != cj) { aj = index[j]; /* Compute distance */ if (bMol) { GMX_RELEASE_ASSERT(mols != NULL, "Cannot access index[] from NULL mols pointer"); bSame = FALSE; for (ii = mols->index[ai]; !bSame && (ii < mols->index[ai+1]); ii++) { for (jj = mols->index[aj]; !bSame && (jj < mols->index[aj+1]); jj++) { if (bPBC) { pbc_dx(&pbc, x[ii], x[jj], dx); } else { rvec_sub(x[ii], x[jj], dx); } dx2 = iprod(dx, dx); bSame = (dx2 < cut2); } } } else { if (bPBC) { pbc_dx(&pbc, x[ai], x[aj], dx); } else { rvec_sub(x[ai], x[aj], dx); } dx2 = iprod(dx, dx); bSame = (dx2 < cut2); } /* If distance less than cut-off */ if (bSame) { /* Merge clusters: check for all atoms whether they are in * cluster cj and if so, put them in ci */ for (k = 0; (k < nindex); k++) { if (clust_index[k] == cj) { if (clust_size[cj] <= 0) { gmx_fatal(FARGS, "negative cluster size %d for element %d", clust_size[cj], cj); } clust_size[cj]--; clust_index[k] = ci; clust_size[ci]++; } } } } } } n_x++; srenew(t_x, n_x); t_x[n_x-1] = fr.time*tf; srenew(cs_dist, n_x); snew(cs_dist[n_x-1], nindex); nclust = 0; cav = 0; nav = 0; for (i = 0; (i < nindex); i++) { ci = clust_size[i]; if (ci > max_clust_size) { max_clust_size = ci; max_clust_ind = i; } if (ci > 0) { nclust++; cs_dist[n_x-1][ci-1] += 1.0; max_size = std::max(max_size, ci); if (ci > 1) { cav += ci; nav++; } } } fprintf(fp, "%14.6e %10d\n", fr.time, nclust); if (nav > 0) { fprintf(gp, "%14.6e %10.3f\n", fr.time, cav/nav); } fprintf(hp, "%14.6e %10d\n", fr.time, max_clust_size); } /* Analyse velocities, if present */ if (fr.bV) { if (!tpr) { if (bTPRwarn) { printf("You need a [REF].tpr[ref] file to analyse temperatures\n"); bTPRwarn = FALSE; } } else { v = fr.v; /* Loop over clusters and for each cluster compute 1/2 m v^2 */ if (max_clust_ind >= 0) { ekin = 0; for (i = 0; (i < nindex); i++) { if (clust_index[i] == max_clust_ind) { ai = index[i]; gmx_mtop_atomnr_to_atom(alook, ai, &atom); ekin += 0.5*atom->m*iprod(v[ai], v[ai]); } } temp = (ekin*2.0)/(3.0*tfac*max_clust_size*BOLTZ); fprintf(tp, "%10.3f %10.3f\n", fr.time, temp); } } } nframe++; } while (read_next_frame(oenv, status, &fr)); close_trx(status); xvgrclose(fp); xvgrclose(gp); xvgrclose(hp); xvgrclose(tp); gmx_mtop_atomlookup_destroy(alook); if (max_clust_ind >= 0) { fp = gmx_ffopen(mcn, "w"); fprintf(fp, "[ max_clust ]\n"); for (i = 0; (i < nindex); i++) { if (clust_index[i] == max_clust_ind) { if (bMol) { GMX_RELEASE_ASSERT(mols != NULL, "Cannot access index[] from NULL mols pointer"); for (j = mols->index[i]; (j < mols->index[i+1]); j++) { fprintf(fp, "%d\n", j+1); } } else { fprintf(fp, "%d\n", index[i]+1); } } } gmx_ffclose(fp); } /* Print the real distribution cluster-size/numer, averaged over the trajectory. */ fp = xvgropen(histo, "Cluster size distribution", "Cluster size", "()", oenv); nhisto = 0; fprintf(fp, "%5d %8.3f\n", 0, 0.0); for (j = 0; (j < max_size); j++) { real nelem = 0; for (i = 0; (i < n_x); i++) { nelem += cs_dist[i][j]; } fprintf(fp, "%5d %8.3f\n", j+1, nelem/n_x); nhisto += static_cast<int>((j+1)*nelem/n_x); } fprintf(fp, "%5d %8.3f\n", j+1, 0.0); xvgrclose(fp); fprintf(stderr, "Total number of atoms in clusters = %d\n", nhisto); /* Look for the smallest entry that is not zero * This will make that zero is white, and not zero is coloured. */ cmid = 100.0; cmax = 0.0; for (i = 0; (i < n_x); i++) { for (j = 0; (j < max_size); j++) { if ((cs_dist[i][j] > 0) && (cs_dist[i][j] < cmid)) { cmid = cs_dist[i][j]; } cmax = std::max(cs_dist[i][j], cmax); } } fprintf(stderr, "cmid: %g, cmax: %g, max_size: %d\n", cmid, cmax, max_size); cmid = 1; fp = gmx_ffopen(xpm, "w"); write_xpm3(fp, 0, "Cluster size distribution", "# clusters", timebuf, "Size", n_x, max_size, t_x, t_y, cs_dist, 0, cmid, cmax, rlo, rmid, rhi, &nlevels); gmx_ffclose(fp); cmid = 100.0; cmax = 0.0; for (i = 0; (i < n_x); i++) { for (j = 0; (j < max_size); j++) { cs_dist[i][j] *= (j+1); if ((cs_dist[i][j] > 0) && (cs_dist[i][j] < cmid)) { cmid = cs_dist[i][j]; } cmax = std::max(cs_dist[i][j], cmax); } } fprintf(stderr, "cmid: %g, cmax: %g, max_size: %d\n", cmid, cmax, max_size); fp = gmx_ffopen(xpmw, "w"); write_xpm3(fp, 0, "Weighted cluster size distribution", "Fraction", timebuf, "Size", n_x, max_size, t_x, t_y, cs_dist, 0, cmid, cmax, rlo, rmid, rhi, &nlevels); gmx_ffclose(fp); sfree(clust_index); sfree(clust_size); sfree(index); }
int gmx_disre(int argc,char *argv[]) { const char *desc[] = { "g_disre computes violations of distance restraints.", "If necessary all protons can be added to a protein molecule ", "using the protonate program.[PAR]", "The program always", "computes the instantaneous violations rather than time-averaged,", "because this analysis is done from a trajectory file afterwards", "it does not make sense to use time averaging. However,", "the time averaged values per restraint are given in the log file.[PAR]", "An index file may be used to select specific restraints for", "printing.[PAR]", "When the optional[TT]-q[tt] flag is given a pdb file coloured by the", "amount of average violations.[PAR]", "When the [TT]-c[tt] option is given, an index file will be read", "containing the frames in your trajectory corresponding to the clusters", "(defined in another manner) that you want to analyze. For these clusters", "the program will compute average violations using the third power", "averaging algorithm and print them in the log file." }; static int ntop = 0; static int nlevels = 20; static real max_dr = 0; static gmx_bool bThird = TRUE; t_pargs pa[] = { { "-ntop", FALSE, etINT, {&ntop}, "Number of large violations that are stored in the log file every step" }, { "-maxdr", FALSE, etREAL, {&max_dr}, "Maximum distance violation in matrix output. If less than or equal to 0 the maximum will be determined by the data." }, { "-nlevels", FALSE, etINT, {&nlevels}, "Number of levels in the matrix output" }, { "-third", FALSE, etBOOL, {&bThird}, "Use inverse third power averaging or linear for matrix output" } }; FILE *out=NULL,*aver=NULL,*numv=NULL,*maxxv=NULL,*xvg=NULL; t_tpxheader header; t_inputrec ir; gmx_mtop_t mtop; rvec *xtop; gmx_localtop_t *top; t_atoms *atoms=NULL; t_forcerec *fr; t_fcdata fcd; t_nrnb nrnb; t_commrec *cr; t_graph *g; int ntopatoms,natoms,i,j,kkk; t_trxstatus *status; real t; rvec *x,*f,*xav=NULL; matrix box; gmx_bool bPDB; int isize; atom_id *index=NULL,*ind_fit=NULL; char *grpname; t_cluster_ndx *clust=NULL; t_dr_result dr,*dr_clust=NULL; char **leg; real *vvindex=NULL,*w_rls=NULL; t_mdatoms *mdatoms; t_pbc pbc,*pbc_null; int my_clust; FILE *fplog; output_env_t oenv; gmx_rmpbc_t gpbc=NULL; t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efTRX, "-f", NULL, ffREAD }, { efXVG, "-ds", "drsum", ffWRITE }, { efXVG, "-da", "draver", ffWRITE }, { efXVG, "-dn", "drnum", ffWRITE }, { efXVG, "-dm", "drmax", ffWRITE }, { efXVG, "-dr", "restr", ffWRITE }, { efLOG, "-l", "disres", ffWRITE }, { efNDX, NULL, "viol", ffOPTRD }, { efPDB, "-q", "viol", ffOPTWR }, { efNDX, "-c", "clust", ffOPTRD }, { efXPM, "-x", "matrix", ffOPTWR } }; #define NFILE asize(fnm) cr = init_par(&argc,&argv); CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL,&oenv); gmx_log_open(ftp2fn(efLOG,NFILE,fnm),cr,FALSE,0,&fplog); if (ntop) init5(ntop); read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&header,FALSE,NULL,NULL); snew(xtop,header.natoms); read_tpx(ftp2fn(efTPX,NFILE,fnm),&ir,box,&ntopatoms,xtop,NULL,NULL,&mtop); bPDB = opt2bSet("-q",NFILE,fnm); if (bPDB) { snew(xav,ntopatoms); snew(ind_fit,ntopatoms); snew(w_rls,ntopatoms); for(kkk=0; (kkk<ntopatoms); kkk++) { w_rls[kkk] = 1; ind_fit[kkk] = kkk; } snew(atoms,1); *atoms = gmx_mtop_global_atoms(&mtop); if (atoms->pdbinfo == NULL) { snew(atoms->pdbinfo,atoms->nr); } } top = gmx_mtop_generate_local_top(&mtop,&ir); g = NULL; pbc_null = NULL; if (ir.ePBC != epbcNONE) { if (ir.bPeriodicMols) pbc_null = &pbc; else g = mk_graph(fplog,&top->idef,0,mtop.natoms,FALSE,FALSE); } if (ftp2bSet(efNDX,NFILE,fnm)) { rd_index(ftp2fn(efNDX,NFILE,fnm),1,&isize,&index,&grpname); xvg=xvgropen(opt2fn("-dr",NFILE,fnm),"Inidividual Restraints","Time (ps)", "nm",oenv); snew(vvindex,isize); snew(leg,isize); for(i=0; (i<isize); i++) { index[i]++; snew(leg[i],12); sprintf(leg[i],"index %d",index[i]); } xvgr_legend(xvg,isize,(const char**)leg,oenv); } else isize=0; ir.dr_tau=0.0; init_disres(fplog,&mtop,&ir,NULL,FALSE,&fcd,NULL); natoms=read_first_x(oenv,&status,ftp2fn(efTRX,NFILE,fnm),&t,&x,box); snew(f,5*natoms); init_dr_res(&dr,fcd.disres.nres); if (opt2bSet("-c",NFILE,fnm)) { clust = cluster_index(fplog,opt2fn("-c",NFILE,fnm)); snew(dr_clust,clust->clust->nr+1); for(i=0; (i<=clust->clust->nr); i++) init_dr_res(&dr_clust[i],fcd.disres.nres); } else { out =xvgropen(opt2fn("-ds",NFILE,fnm), "Sum of Violations","Time (ps)","nm",oenv); aver=xvgropen(opt2fn("-da",NFILE,fnm), "Average Violation","Time (ps)","nm",oenv); numv=xvgropen(opt2fn("-dn",NFILE,fnm), "# Violations","Time (ps)","#",oenv); maxxv=xvgropen(opt2fn("-dm",NFILE,fnm), "Largest Violation","Time (ps)","nm",oenv); } mdatoms = init_mdatoms(fplog,&mtop,ir.efep!=efepNO); atoms2md(&mtop,&ir,0,NULL,0,mtop.natoms,mdatoms); update_mdatoms(mdatoms,ir.init_lambda); fr = mk_forcerec(); fprintf(fplog,"Made forcerec\n"); init_forcerec(fplog,oenv,fr,NULL,&ir,&mtop,cr,box,FALSE,NULL,NULL,NULL, FALSE,-1); init_nrnb(&nrnb); if (ir.ePBC != epbcNONE) gpbc = gmx_rmpbc_init(&top->idef,ir.ePBC,natoms,box); j=0; do { if (ir.ePBC != epbcNONE) { if (ir.bPeriodicMols) set_pbc(&pbc,ir.ePBC,box); else gmx_rmpbc(gpbc,natoms,box,x); } if (clust) { if (j > clust->maxframe) gmx_fatal(FARGS,"There are more frames in the trajectory than in the cluster index file. t = %8f\n",t); my_clust = clust->inv_clust[j]; range_check(my_clust,0,clust->clust->nr); check_viol(fplog,cr,&(top->idef.il[F_DISRES]), top->idef.iparams,top->idef.functype, x,f,fr,pbc_null,g,dr_clust,my_clust,isize,index,vvindex,&fcd); } else check_viol(fplog,cr,&(top->idef.il[F_DISRES]), top->idef.iparams,top->idef.functype, x,f,fr,pbc_null,g,&dr,0,isize,index,vvindex,&fcd); if (bPDB) { reset_x(atoms->nr,ind_fit,atoms->nr,NULL,x,w_rls); do_fit(atoms->nr,w_rls,x,x); if (j == 0) { /* Store the first frame of the trajectory as 'characteristic' * for colouring with violations. */ for(kkk=0; (kkk<atoms->nr); kkk++) copy_rvec(x[kkk],xav[kkk]); } } if (!clust) { if (isize > 0) { fprintf(xvg,"%10g",t); for(i=0; (i<isize); i++) fprintf(xvg," %10g",vvindex[i]); fprintf(xvg,"\n"); } fprintf(out, "%10g %10g\n",t,dr.sumv); fprintf(aver, "%10g %10g\n",t,dr.averv); fprintf(maxxv,"%10g %10g\n",t,dr.maxv); fprintf(numv, "%10g %10d\n",t,dr.nv); } j++; } while (read_next_x(oenv,status,&t,natoms,x,box)); close_trj(status); if (ir.ePBC != epbcNONE) gmx_rmpbc_done(gpbc); if (clust) { dump_clust_stats(fplog,fcd.disres.nres,&(top->idef.il[F_DISRES]), top->idef.iparams,clust->clust,dr_clust, clust->grpname,isize,index); } else { dump_stats(fplog,j,fcd.disres.nres,&(top->idef.il[F_DISRES]), top->idef.iparams,&dr,isize,index, bPDB ? atoms : NULL); if (bPDB) { write_sto_conf(opt2fn("-q",NFILE,fnm), "Coloured by average violation in Angstrom", atoms,xav,NULL,ir.ePBC,box); } dump_disre_matrix(opt2fn_null("-x",NFILE,fnm),&dr,fcd.disres.nres, j,&top->idef,&mtop,max_dr,nlevels,bThird); ffclose(out); ffclose(aver); ffclose(numv); ffclose(maxxv); if (isize > 0) { ffclose(xvg); do_view(oenv,opt2fn("-dr",NFILE,fnm),"-nxy"); } do_view(oenv,opt2fn("-dn",NFILE,fnm),"-nxy"); do_view(oenv,opt2fn("-da",NFILE,fnm),"-nxy"); do_view(oenv,opt2fn("-ds",NFILE,fnm),"-nxy"); do_view(oenv,opt2fn("-dm",NFILE,fnm),"-nxy"); } thanx(stderr); if (gmx_parallel_env_initialized()) gmx_finalize(); gmx_log_close(fplog); return 0; }
int gmx_helix(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] computes all kinds of helix properties. First, the peptide", "is checked to find the longest helical part, as determined by", "hydrogen bonds and [GRK]phi[grk]/[GRK]psi[grk] angles.", "That bit is fitted", "to an ideal helix around the [IT]z[it]-axis and centered around the origin.", "Then the following properties are computed:[PAR]", "[BB]1.[bb] Helix radius (file [TT]radius.xvg[tt]). This is merely the", "RMS deviation in two dimensions for all C[GRK]alpha[grk] atoms.", "it is calculated as [SQRT]([SUM][sum][SUB]i[sub] (x^2(i)+y^2(i)))/N[sqrt] where N is the number", "of backbone atoms. For an ideal helix the radius is 0.23 nm[BR]", "[BB]2.[bb] Twist (file [TT]twist.xvg[tt]). The average helical angle per", "residue is calculated. For an [GRK]alpha[grk]-helix it is 100 degrees,", "for 3-10 helices it will be smaller, and ", "for 5-helices it will be larger.[BR]", "[BB]3.[bb] Rise per residue (file [TT]rise.xvg[tt]). The helical rise per", "residue is plotted as the difference in [IT]z[it]-coordinate between C[GRK]alpha[grk]", "atoms. For an ideal helix, this is 0.15 nm[BR]", "[BB]4.[bb] Total helix length (file [TT]len-ahx.xvg[tt]). The total length", "of the", "helix in nm. This is simply the average rise (see above) times the", "number of helical residues (see below).[BR]", "[BB]5.[bb] Helix dipole, backbone only (file [TT]dip-ahx.xvg[tt]).[BR]", "[BB]6.[bb] RMS deviation from ideal helix, calculated for the C[GRK]alpha[grk]", "atoms only (file [TT]rms-ahx.xvg[tt]).[BR]", "[BB]7.[bb] Average C[GRK]alpha[grk] - C[GRK]alpha[grk] dihedral angle (file [TT]phi-ahx.xvg[tt]).[BR]", "[BB]8.[bb] Average [GRK]phi[grk] and [GRK]psi[grk] angles (file [TT]phipsi.xvg[tt]).[BR]", "[BB]9.[bb] Ellipticity at 222 nm according to Hirst and Brooks.", "[PAR]" }; static gmx_bool bCheck = FALSE, bFit = TRUE, bDBG = FALSE, bEV = FALSE; static int rStart = 0, rEnd = 0, r0 = 1; t_pargs pa [] = { { "-r0", FALSE, etINT, {&r0}, "The first residue number in the sequence" }, { "-q", FALSE, etBOOL, {&bCheck}, "Check at every step which part of the sequence is helical" }, { "-F", FALSE, etBOOL, {&bFit}, "Toggle fit to a perfect helix" }, { "-db", FALSE, etBOOL, {&bDBG}, "Print debug info" }, { "-ev", FALSE, etBOOL, {&bEV}, "Write a new 'trajectory' file for ED" }, { "-ahxstart", FALSE, etINT, {&rStart}, "First residue in helix" }, { "-ahxend", FALSE, etINT, {&rEnd}, "Last residue in helix" } }; typedef struct { FILE *fp, *fp2; gmx_bool bfp2; const char *filenm; const char *title; const char *xaxis; const char *yaxis; real val; } t_xvgrfile; t_xvgrfile xf[efhNR] = { { NULL, NULL, TRUE, "radius", "Helix radius", NULL, "r (nm)", 0.0 }, { NULL, NULL, TRUE, "twist", "Twist per residue", NULL, "Angle (deg)", 0.0 }, { NULL, NULL, TRUE, "rise", "Rise per residue", NULL, "Rise (nm)", 0.0 }, { NULL, NULL, FALSE, "len-ahx", "Length of the Helix", NULL, "Length (nm)", 0.0 }, { NULL, NULL, FALSE, "dip-ahx", "Helix Backbone Dipole", NULL, "rq (nm e)", 0.0 }, { NULL, NULL, TRUE, "rms-ahx", "RMS Deviation from Ideal Helix", NULL, "RMS (nm)", 0.0 }, { NULL, NULL, FALSE, "rmsa-ahx", "Average RMSD per Residue", "Residue", "RMS (nm)", 0.0 }, { NULL, NULL, FALSE, "cd222", "Ellipticity at 222 nm", NULL, "nm", 0.0 }, { NULL, NULL, TRUE, "pprms", "RMS Distance from \\8a\\4-helix", NULL, "deg", 0.0 }, { NULL, NULL, TRUE, "caphi", "Average Ca-Ca Dihedral", NULL, "\\8F\\4(deg)", 0.0 }, { NULL, NULL, TRUE, "phi", "Average \\8F\\4 angles", NULL, "deg", 0.0 }, { NULL, NULL, TRUE, "psi", "Average \\8Y\\4 angles", NULL, "deg", 0.0 }, { NULL, NULL, TRUE, "hb3", "Average n-n+3 hbond length", NULL, "nm", 0.0 }, { NULL, NULL, TRUE, "hb4", "Average n-n+4 hbond length", NULL, "nm", 0.0 }, { NULL, NULL, TRUE, "hb5", "Average n-n+5 hbond length", NULL, "nm", 0.0 }, { NULL, NULL, FALSE, "JCaHa", "J-Coupling Values", "Residue", "Hz", 0.0 }, { NULL, NULL, FALSE, "helicity", "Helicity per Residue", "Residue", "% of time", 0.0 } }; output_env_t oenv; char buf[54]; t_trxstatus *status; int natoms, nre, nres; t_bb *bb; int i, j, m, nall, nbb, nca, teller, nSel = 0; atom_id *bbindex, *caindex, *allindex; t_topology *top; int ePBC; rvec *x, *xref; real t; real rms; matrix box; gmx_rmpbc_t gpbc = NULL; gmx_bool bRange; t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffREAD }, { efTRX, "-f", NULL, ffREAD }, { efSTO, "-cz", "zconf", ffWRITE }, }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_BE_NICE, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } bRange = (opt2parg_bSet("-ahxstart", asize(pa), pa) && opt2parg_bSet("-ahxend", asize(pa), pa)); top = read_top(ftp2fn(efTPX, NFILE, fnm), &ePBC); natoms = read_first_x(oenv, &status, opt2fn("-f", NFILE, fnm), &t, &x, box); if (natoms != top->atoms.nr) { gmx_fatal(FARGS, "Sorry can only run when the number of atoms in the run input file (%d) is equal to the number in the trajectory (%d)", top->atoms.nr, natoms); } bb = mkbbind(ftp2fn(efNDX, NFILE, fnm), &nres, &nbb, r0, &nall, &allindex, top->atoms.atomname, top->atoms.atom, top->atoms.resinfo); snew(bbindex, natoms); snew(caindex, nres); fprintf(stderr, "nall=%d\n", nall); /* Open output files, default x-axis is time */ for (i = 0; (i < efhNR); i++) { sprintf(buf, "%s.xvg", xf[i].filenm); remove(buf); xf[i].fp = xvgropen(buf, xf[i].title, xf[i].xaxis ? xf[i].xaxis : "Time (ps)", xf[i].yaxis, oenv); if (xf[i].bfp2) { sprintf(buf, "%s.out", xf[i].filenm); remove(buf); xf[i].fp2 = gmx_ffopen(buf, "w"); } } /* Read reference frame from tpx file to compute helix length */ snew(xref, top->atoms.nr); read_tpx(ftp2fn(efTPX, NFILE, fnm), NULL, NULL, &natoms, xref, NULL, NULL, NULL); calc_hxprops(nres, bb, xref); do_start_end(nres, bb, &nbb, bbindex, &nca, caindex, bRange, rStart, rEnd); sfree(xref); if (bDBG) { fprintf(stderr, "nca=%d, nbb=%d\n", nca, nbb); pr_bb(stdout, nres, bb); } gpbc = gmx_rmpbc_init(&top->idef, ePBC, natoms); teller = 0; do { if ((teller++ % 10) == 0) { fprintf(stderr, "\rt=%.2f", t); } gmx_rmpbc(gpbc, natoms, box, x); calc_hxprops(nres, bb, x); if (bCheck) { do_start_end(nres, bb, &nbb, bbindex, &nca, caindex, FALSE, 0, 0); } if (nca >= 5) { rms = fit_ahx(nres, bb, natoms, nall, allindex, x, nca, caindex, bFit); if (teller == 1) { write_sto_conf(opt2fn("-cz", NFILE, fnm), "Helix fitted to Z-Axis", &(top->atoms), x, NULL, ePBC, box); } xf[efhRAD].val = radius(xf[efhRAD].fp2, nca, caindex, x); xf[efhTWIST].val = twist(nca, caindex, x); xf[efhRISE].val = rise(nca, caindex, x); xf[efhLEN].val = ahx_len(nca, caindex, x); xf[efhCD222].val = ellipticity(nres, bb); xf[efhDIP].val = dip(nbb, bbindex, x, top->atoms.atom); xf[efhRMS].val = rms; xf[efhCPHI].val = ca_phi(nca, caindex, x); xf[efhPPRMS].val = pprms(xf[efhPPRMS].fp2, nres, bb); for (j = 0; (j <= efhCPHI); j++) { fprintf(xf[j].fp, "%10g %10g\n", t, xf[j].val); } av_phipsi(xf[efhPHI].fp, xf[efhPSI].fp, xf[efhPHI].fp2, xf[efhPSI].fp2, t, nres, bb); av_hblen(xf[efhHB3].fp, xf[efhHB3].fp2, xf[efhHB4].fp, xf[efhHB4].fp2, xf[efhHB5].fp, xf[efhHB5].fp2, t, nres, bb); } } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); gmx_rmpbc_done(gpbc); close_trj(status); for (i = 0; (i < nres); i++) { if (bb[i].nrms > 0) { fprintf(xf[efhRMSA].fp, "%10d %10g\n", r0+i, bb[i].rmsa/bb[i].nrms); } fprintf(xf[efhAHX].fp, "%10d %10g\n", r0+i, (bb[i].nhx*100.0)/(real )teller); fprintf(xf[efhJCA].fp, "%10d %10g\n", r0+i, 140.3+(bb[i].jcaha/(double)teller)); } for (i = 0; (i < efhNR); i++) { gmx_ffclose(xf[i].fp); if (xf[i].bfp2) { gmx_ffclose(xf[i].fp2); } do_view(oenv, xf[i].filenm, "-nxy"); } return 0; }
gmx_bool read_tps_conf(const char *infile, t_topology *top, int *ePBC, rvec **x, rvec **v, matrix box, gmx_bool bMass) { t_tpxheader header; int natoms, i; gmx_bool bTop, bXNULL = FALSE; gmx_mtop_t *mtop; gmx_atomprop_t aps; bTop = fn2bTPX(infile); if (ePBC != NULL) { *ePBC = -1; } if (bTop) { read_tpxheader(infile, &header, TRUE); if (x) { snew(*x, header.natoms); } if (v) { snew(*v, header.natoms); } snew(mtop, 1); int ePBC_tmp = read_tpx(infile, NULL, box, &natoms, (x == NULL) ? NULL : *x, (v == NULL) ? NULL : *v, mtop); if (ePBC != NULL) { *ePBC = ePBC_tmp; } *top = gmx_mtop_t_to_t_topology(mtop); /* In this case we need to throw away the group data too */ done_gmx_groups_t(&mtop->groups); sfree(mtop); tpx_make_chain_identifiers(&top->atoms, &top->mols); } else { open_symtab(&top->symtab); get_stx_coordnum(infile, &natoms); init_t_atoms(&top->atoms, natoms, (fn2ftp(infile) == efPDB)); if (x == NULL) { snew(x, 1); bXNULL = TRUE; } snew(*x, natoms); if (v) { snew(*v, natoms); } read_stx_conf(infile, top, *x, (v == NULL) ? NULL : *v, ePBC, box); if (bXNULL) { sfree(*x); sfree(x); } if (bMass) { aps = gmx_atomprop_init(); for (i = 0; (i < natoms); i++) { if (!gmx_atomprop_query(aps, epropMass, *top->atoms.resinfo[top->atoms.atom[i].resind].name, *top->atoms.atomname[i], &(top->atoms.atom[i].m))) { if (debug) { fprintf(debug, "Can not find mass for atom %s %d %s, setting to 1\n", *top->atoms.resinfo[top->atoms.atom[i].resind].name, top->atoms.resinfo[top->atoms.atom[i].resind].nr, *top->atoms.atomname[i]); } } } gmx_atomprop_destroy(aps); } top->idef.ntypes = -1; } return bTop; }
int gmx_relax(int argc,char *argv[]) { const char *desc[] = { "g_noe calculates a NOE spectrum" }; int status; t_topology *top; int i,j,k,natoms,nprot,*prot_ind; int ifit; char *gn_fit; atom_id *ind_fit,*all_at; real *w_rls; rvec *xp; t_pair *pair; matrix box; int step,nre; real t,lambda; real *shifts=NULL; t_filenm fnm[] = { { efTRX, "-f", NULL, ffREAD }, { efTPX, "-s", NULL, ffREAD }, { efNDX, NULL, NULL, ffREAD }, { efDAT, "-d", "shifts", ffREAD }, { efOUT, "-o","spec", ffWRITE }, { efXVG, "-corr", "rij-corr", ffWRITE }, { efXVG, "-noe", "noesy", ffWRITE } }; #define NFILE asize(fnm) static real taum = 0.0, maxdist = 0.6; static int nlevels = 15; static int nrestart = 1; static int maxframes = 100; static bool bFFT = TRUE,bFit = TRUE, bVerbose = TRUE; t_pargs pa[] = { { "-taum", FALSE, etREAL, &taum, "Rotational correlation time for your molecule. It is obligatory to pass this option" }, { "-maxdist", FALSE, etREAL, &maxdist, "Maximum distance to be plotted" }, { "-nlevels", FALSE, etINT, &nlevels, "Number of levels for plotting" }, { "-nframes", FALSE, etINT, &maxframes, "Number of frames in your trajectory. Will stop analysis after this" }, { "-fft", FALSE, etBOOL, &bFFT, "Use FFT for correlation function" }, { "-nrestart", FALSE, etINT, &nrestart, "Number of frames between starting point for computation of ACF without FFT" }, { "-fit", FALSE, etBOOL, &bFit, "Do an optimal superposition on reference structure in tpx file" }, { "-v", FALSE, etBOOL, &bVerbose, "Tell you what I am about to do" } }; 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 (taum <= 0) gmx_fatal(FARGS,"Please give me a sensible taum!\n"); if (nlevels > 50) { nlevels = 50; fprintf(stderr,"Warning: too many levels, setting to %d\n",nlevels); } top = read_top(ftp2fn(efTPX,NFILE,fnm)); natoms = top->atoms.nr; snew(xp,natoms); read_tpx(ftp2fn(efTPX,NFILE,fnm),&step,&t,&lambda,NULL,box, &natoms,xp,NULL,NULL,NULL); /* Determine the number of protons, and their index numbers * by checking the mass */ nprot = 0; snew(prot_ind,natoms); for(i=0; (i<natoms); i++) if (top->atoms.atom[i].m < 2) { prot_ind[nprot++] = i; } fprintf(stderr,"There %d protons in your topology\n",nprot); snew(pair,(nprot*(nprot-1)/2)); for(i=k=0; (i<nprot); i++) { for(j=i+1; (j<nprot); j++,k++) { pair[k].ai = prot_ind[i]; pair[k].aj = prot_ind[j]; } } sfree(prot_ind); fprintf(stderr,"Select group for root least squares fit\n"); rd_index(ftp2fn(efNDX,NFILE,fnm),1,&ifit,&ind_fit,&gn_fit); if (ifit < 3) gmx_fatal(FARGS,"Need >= 3 points to fit!\n"); /* Make an array with weights for fitting */ snew(w_rls,natoms); for(i=0; (i<ifit); i++) w_rls[ind_fit[i]]=top->atoms.atom[ind_fit[i]].m; /* Prepare reference frame */ snew(all_at,natoms); for(j=0; (j<natoms); j++) all_at[j]=j; rm_pbc(&(top->idef),natoms,box,xp,xp); reset_x(ifit,ind_fit,natoms,all_at,xp,w_rls); sfree(all_at); spectrum(bVerbose, ftp2fn(efTRX,NFILE,fnm),ftp2fn(efDAT,NFILE,fnm), ftp2bSet(efDAT,NFILE,fnm),opt2fn("-corr",NFILE,fnm), opt2fn("-noe",NFILE,fnm), maxframes,bFFT,bFit,nrestart, k,pair,natoms,shifts, taum,maxdist,w_rls,xp,&(top->idef)); thanx(stderr); return 0; }
void read_stx_conf(const char *infile, char *title, t_atoms *atoms, rvec x[], rvec *v, int *ePBC, matrix box) { FILE *in; char buf[256]; gmx_mtop_t *mtop; t_topology top; t_trxframe fr; int i, ftp, natoms; real d; char g96_line[STRLEN+1]; if (atoms->nr == 0) { fprintf(stderr, "Warning: Number of atoms in %s is 0\n", infile); } else if (atoms->atom == NULL) { gmx_mem("Uninitialized array atom"); } if (ePBC) { *ePBC = -1; } ftp = fn2ftp(infile); switch (ftp) { case efGRO: read_whole_conf(infile, title, atoms, x, v, box); break; case efG96: fr.title = NULL; fr.natoms = atoms->nr; fr.atoms = atoms; fr.x = x; fr.v = v; fr.f = NULL; in = gmx_fio_fopen(infile, "r"); read_g96_conf(in, infile, &fr, g96_line); gmx_fio_fclose(in); copy_mat(fr.box, box); strncpy(title, fr.title, STRLEN); break; case efPDB: case efBRK: case efENT: read_pdb_conf(infile, title, atoms, x, ePBC, box, TRUE, NULL); break; case efESP: read_espresso_conf(infile, atoms, x, v, box); break; case efTPR: case efTPB: case efTPA: snew(mtop, 1); i = read_tpx(infile, NULL, box, &natoms, x, v, NULL, mtop); if (ePBC) { *ePBC = i; } strcpy(title, *(mtop->name)); /* Free possibly allocated memory */ done_atom(atoms); *atoms = gmx_mtop_global_atoms(mtop); top = gmx_mtop_t_to_t_topology(mtop); tpx_make_chain_identifiers(atoms, &top.mols); sfree(mtop); /* The strings in the symtab are still in use in the returned t_atoms * structure, so we should not free them. But there is no place to put the * symbols; the only choice is to leak the memory... * So we clear the symbol table before freeing the topology structure. */ free_symtab(&top.symtab); done_top(&top); break; default: gmx_incons("Not supported in read_stx_conf"); } }
void read_stx_conf(char *infile, char *title,t_atoms *atoms, rvec x[],rvec *v,int *ePBC,matrix box) { FILE *in; char buf[256]; gmx_mtop_t *mtop; t_topology top; t_trxframe fr; int i,ftp,natoms,i1; real d,r1,r2; if (atoms->nr == 0) fprintf(stderr,"Warning: Number of atoms in %s is 0\n",infile); else if (atoms->atom == NULL) gmx_mem("Uninitialized array atom"); if (ePBC) *ePBC = -1; ftp=fn2ftp(infile); switch (ftp) { case efGRO: read_whole_conf(infile, title, atoms, x, v, box); break; case efG96: fr.title = title; fr.natoms = atoms->nr; fr.atoms = atoms; fr.x = x; fr.v = v; fr.f = NULL; in = gmx_fio_fopen(infile,"r"); read_g96_conf(in, infile, &fr); gmx_fio_fclose(in); copy_mat(fr.box,box); break; case efPDB: case efBRK: case efENT: read_pdb_conf(infile, title, atoms, x, ePBC, box, TRUE, NULL); break; case efESP: read_espresso_conf(infile,atoms,x,v,box); break; case efTPR: case efTPB: case efTPA: snew(mtop,1); i = read_tpx(infile,&i1,&r1,&r2,NULL,box,&natoms,x,v,NULL,mtop); if (ePBC) *ePBC = i; strcpy(title,*(mtop->name)); /* Free possibly allocated memory */ done_atom(atoms); *atoms = gmx_mtop_global_atoms(mtop); top = gmx_mtop_t_to_t_topology(mtop); tpx_make_chain_identifiers(atoms,&top.mols); sfree(mtop); done_top(&top); break; default: gmx_incons("Not supported in read_stx_conf"); } }
int main(int argc,char *argv[]) { static char *desc[] = { "testlr tests the PPPM and Ewald method for the", "long range electrostatics problem." }; static t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efHAT, "-g", "ghat", ffOPTRD }, { efOUT, "-o", "rho", ffOPTWR }, { efOUT, "-op", "lr-pb", ffOPTWR }, { efOUT, "-of", "lr-four", ffOPTWR }, { efOUT, "-opt", "tot-pb", ffOPTWR }, { efOUT, "-oft", "tot-four", ffOPTWR }, { efOUT, "-fin", "lr-four", ffOPTWR }, { efEPS, "-es", "sr", ffOPTWR }, { efEPS, "-elf", "lr-four", ffOPTWR }, { efEPS, "-etf", "tot-four", ffOPTWR }, { efEPS, "-qr", "qk-real", ffOPTWR }, { efEPS, "-qi", "qk-im", ffOPTWR }, { efEPS, "-elp", "lr-pb", ffOPTWR }, { efEPS, "-etp", "tot-pb", ffOPTWR }, { efEPS, "-rho", "rho", ffOPTWR }, { efEPS, "-qq", "charge", ffOPTWR }, { efXVG, "-gt", "gk-tab", ffOPTWR }, { efXVG, "-fcorr","fcorr", ffWRITE }, { efXVG, "-pcorr","pcorr", ffWRITE }, { efXVG, "-ftotcorr","ftotcorr", ffWRITE }, { efXVG, "-ptotcorr","ptotcorr", ffWRITE }, { efLOG, "-l", "fptest", ffWRITE }, { efXVG, "-gr", "spread", ffOPTWR }, { efPDB, "-pf", "pqr-four", ffOPTWR }, { efPDB, "-phitot", "pppm-phitot", ffOPTWR } }; #define NFILE asize(fnm) FILE *log; t_topology top; t_tpxheader stath; t_inputrec ir; t_block *excl; t_forcerec *fr; t_commrec *cr; t_mdatoms *mdatoms; t_graph *graph; int i,step,nre,natoms,nmol; rvec *x,*f_sr,*f_excl,*f_four,*f_pppm,*f_pois,box_size,hbox; matrix box; real t,lambda,vsr,*charge,*phi_f,*phi_pois,*phi_s,*phi_p3m,*rho; static bool bFour=FALSE,bVerbose=FALSE,bGGhat=FALSE,bPPPM=TRUE, bPoisson=FALSE,bOld=FALSE,bOldEwald=TRUE; static int nprocs = 1; static t_pargs pa[] = { { "-np", FALSE, etINT, &nprocs, "Do it in parallel" }, { "-ewald", FALSE, etBOOL, &bFour, "Do an Ewald solution"}, { "-pppm", FALSE, etBOOL, &bPPPM, "Do a PPPM solution" }, { "-poisson",FALSE, etBOOL, &bPoisson,"Do a Poisson solution" }, { "-v", FALSE, etBOOL, &bVerbose,"Verbose on"}, { "-ghat", FALSE, etBOOL, &bGGhat, "Generate Ghat function"}, { "-old", FALSE, etBOOL, &bOld, "Use old function types"}, { "-oldewald",FALSE,etBOOL, &bOldEwald,"Use old Ewald code"} }; CopyRight(stderr,argv[0]); parse_common_args(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW, NFILE,fnm,asize(pa),pa,asize(desc),desc,0,NULL); if (nprocs > 1) { cr = init_par(&argc,argv); open_log(ftp2fn(efLOG,NFILE,fnm),cr); log = stdlog; } else { cr = init_par(&argc,argv); log = ftp2FILE(efLOG,NFILE,fnm,"w"); stdlog = log; } /* Read topology and coordinates */ read_tpxheader(ftp2fn(efTPX,NFILE,fnm),&stath,FALSE); snew(x,stath.natoms); snew(f_sr,stath.natoms); snew(f_excl,stath.natoms); snew(f_four,stath.natoms); snew(f_pppm,stath.natoms); snew(f_pois,stath.natoms); read_tpx(ftp2fn(efTPX,NFILE,fnm),&step,&t,&lambda,&ir, box,&natoms,x,NULL,NULL,&top); excl=&(top.atoms.excl); nmol=top.blocks[ebMOLS].nr; /* Allocate space for potential, charges and rho (charge density) */ snew(charge,stath.natoms); snew(phi_f,stath.natoms); snew(phi_p3m,stath.natoms); snew(phi_pois,stath.natoms); snew(phi_s,stath.natoms); snew(rho,stath.natoms); /* Set the charges */ for(i=0; (i<natoms); i++) charge[i]=top.atoms.atom[i].q; /* Make a simple box vector instead of tensor */ for(i=0; (i<DIM); i++) box_size[i]=box[i][i]; /* Set some constants */ fr = mk_forcerec(); mdatoms = atoms2md(&(top.atoms),FALSE,FALSE); set_LRconsts(log,ir.rcoulomb_switch,ir.rcoulomb,box_size,fr); init_forcerec(log,fr,&ir,&(top.blocks[ebMOLS]),cr, &(top.blocks[ebCGS]),&(top.idef),mdatoms,box,FALSE); calc_shifts(box,box_size,fr->shift_vec,FALSE); /* Periodicity stuff */ graph = mk_graph(&(top.idef),top.atoms.nr,FALSE,FALSE); shift_self(graph,fr->shift_vec,x); calc_LRcorrections(log,0,natoms,ir.rcoulomb_switch, ir.rcoulomb,charge,excl,x,f_excl,bOld); pr_f("f_excl.dat",natoms,f_excl); /* Compute the short range potential */ put_atoms_in_box(natoms,box,x); vsr=phi_sr(log,natoms,x,charge,ir.rcoulomb, ir.rcoulomb_switch,box_size,phi_s,excl,f_sr,bOld); pr_f("f_sr.dat",natoms,f_sr); /* Plot the short range potential in a matrix */ calc_ener(log,"Short Range",TRUE,nmol,natoms,phi_s,charge,excl); if (bFour) test_four(log,NFILE,fnm,&(top.atoms),&ir,x,f_four,box_size,charge,phi_f, phi_s,nmol,cr,bOld,bOldEwald); if (bPPPM) test_pppm(log,bVerbose,bGGhat,opt2fn("-g",NFILE,fnm), &(top.atoms),&ir,x,f_pppm,charge,box_size,phi_p3m,phi_s,nmol, cr,bOld,&(top.blocks[ebCGS])); if (bPoisson) test_poisson(log,bVerbose, &(top.atoms),&ir,x,f_pois,charge,box_size,phi_pois, phi_s,nmol,cr,bFour,f_four,phi_f,bOld); if (bPPPM && bFour) analyse_diff(log,"PPPM", top.atoms.nr,f_four,f_pppm,phi_f,phi_p3m,phi_s, opt2fn("-fcorr",NFILE,fnm), opt2fn("-pcorr",NFILE,fnm), opt2fn("-ftotcorr",NFILE,fnm), opt2fn("-ptotcorr",NFILE,fnm)); if (bPoisson && bFour) analyse_diff(log,"Poisson", top.atoms.nr,f_four,f_pois,phi_f,phi_pois,phi_s, opt2fn("-fcorr",NFILE,fnm), opt2fn("-pcorr",NFILE,fnm), opt2fn("-ftotcorr",NFILE,fnm), opt2fn("-ptotcorr",NFILE,fnm)); gmx_fio_fclose(log); thanx(stderr); return 0; }
int gmx_helix(int argc,char *argv[]) { const char *desc[] = { "g_helix computes all kind of helix properties. First, the peptide", "is checked to find the longest helical part. This is determined by", "Hydrogen bonds and Phi/Psi angles.", "That bit is fitted", "to an ideal helix around the Z-axis and centered around the origin.", "Then the following properties are computed:[PAR]", "[BB]1.[bb] Helix radius (file radius.xvg). This is merely the", "RMS deviation in two dimensions for all Calpha atoms.", "it is calced as sqrt((SUM i(x^2(i)+y^2(i)))/N), where N is the number", "of backbone atoms. For an ideal helix the radius is 0.23 nm[BR]", "[BB]2.[bb] Twist (file twist.xvg). The average helical angle per", "residue is calculated. For alpha helix it is 100 degrees,", "for 3-10 helices it will be smaller,", "for 5-helices it will be larger.[BR]", "[BB]3.[bb] Rise per residue (file rise.xvg). The helical rise per", "residue is plotted as the difference in Z-coordinate between Ca", "atoms. For an ideal helix this is 0.15 nm[BR]", "[BB]4.[bb] Total helix length (file len-ahx.xvg). The total length", "of the", "helix in nm. This is simply the average rise (see above) times the", "number of helical residues (see below).[BR]", "[BB]5.[bb] Number of helical residues (file n-ahx.xvg). The title says", "it all.[BR]", "[BB]6.[bb] Helix Dipole, backbone only (file dip-ahx.xvg).[BR]", "[BB]7.[bb] RMS deviation from ideal helix, calculated for the Calpha", "atoms only (file rms-ahx.xvg).[BR]", "[BB]8.[bb] Average Calpha-Calpha dihedral angle (file phi-ahx.xvg).[BR]", "[BB]9.[bb] Average Phi and Psi angles (file phipsi.xvg).[BR]", "[BB]10.[bb] Ellipticity at 222 nm according to [IT]Hirst and Brooks[it]", "[PAR]" }; static const char *ppp[efhNR+2] = { NULL, "RAD", "TWIST", "RISE", "LEN", "NHX", "DIP", "RMS", "CPHI", "RMSA", "PHI", "PSI", "HB3", "HB4", "HB5", "CD222", NULL }; static gmx_bool bCheck=FALSE,bFit=TRUE,bDBG=FALSE,bEV=FALSE; static int rStart=0,rEnd=0,r0=1; t_pargs pa [] = { { "-r0", FALSE, etINT, {&r0}, "The first residue number in the sequence" }, { "-q", FALSE, etBOOL,{&bCheck}, "Check at every step which part of the sequence is helical" }, { "-F", FALSE, etBOOL,{&bFit}, "Toggle fit to a perfect helix" }, { "-db", FALSE, etBOOL,{&bDBG}, "Print debug info" }, { "-prop", FALSE, etENUM, {ppp}, "Select property to weight eigenvectors with. WARNING experimental stuff" }, { "-ev", FALSE, etBOOL,{&bEV}, "Write a new 'trajectory' file for ED" }, { "-ahxstart", FALSE, etINT, {&rStart}, "First residue in helix" }, { "-ahxend", FALSE, etINT, {&rEnd}, "Last residue in helix" } }; typedef struct { FILE *fp,*fp2; gmx_bool bfp2; const char *filenm; const char *title; const char *xaxis; const char *yaxis; real val; } t_xvgrfile; t_xvgrfile xf[efhNR] = { { NULL, NULL, TRUE, "radius", "Helix radius", NULL, "r (nm)" , 0.0 }, { NULL, NULL, TRUE, "twist", "Twist per residue", NULL, "Angle (deg)", 0.0 }, { NULL, NULL, TRUE, "rise", "Rise per residue", NULL, "Rise (nm)", 0.0 }, { NULL, NULL, FALSE, "len-ahx", "Length of the Helix", NULL, "Length (nm)", 0.0 }, { NULL, NULL, FALSE, "dip-ahx", "Helix Backbone Dipole", NULL, "rq (nm e)", 0.0 }, { NULL, NULL, TRUE, "rms-ahx", "RMS Deviation from Ideal Helix", NULL, "RMS (nm)", 0.0 }, { NULL, NULL, FALSE, "rmsa-ahx","Average RMSD per Residue", "Residue", "RMS (nm)", 0.0 }, { NULL, NULL,FALSE, "cd222", "Ellipticity at 222 nm", NULL, "nm", 0.0 }, { NULL, NULL, TRUE, "pprms", "RMS Distance from \\8a\\4-helix", NULL, "deg" , 0.0 }, { NULL, NULL, TRUE, "caphi", "Average Ca-Ca Dihedral", NULL, "\\8F\\4(deg)", 0.0 }, { NULL, NULL, TRUE, "phi", "Average \\8F\\4 angles", NULL, "deg" , 0.0 }, { NULL, NULL, TRUE, "psi", "Average \\8Y\\4 angles", NULL, "deg" , 0.0 }, { NULL, NULL, TRUE, "hb3", "Average n-n+3 hbond length", NULL, "nm" , 0.0 }, { NULL, NULL, TRUE, "hb4", "Average n-n+4 hbond length", NULL, "nm" , 0.0 }, { NULL, NULL, TRUE, "hb5", "Average n-n+5 hbond length", NULL, "nm" , 0.0 }, { NULL, NULL,FALSE, "JCaHa", "J-Coupling Values", "Residue", "Hz" , 0.0 }, { NULL, NULL,FALSE, "helicity","Helicity per Residue", "Residue", "% of time" , 0.0 } }; output_env_t oenv; FILE *otrj; char buf[54],prop[256]; t_trxstatus *status; int natoms,nre,nres; t_bb *bb; int i,j,ai,m,nall,nbb,nca,teller,nSel=0; atom_id *bbindex,*caindex,*allindex; t_topology *top; int ePBC; rvec *x,*xref,*xav; real t; real rms,fac; matrix box; gmx_rmpbc_t gpbc=NULL; gmx_bool bRange; t_filenm fnm[] = { { efTPX, NULL, NULL, ffREAD }, { efNDX, NULL, NULL, ffREAD }, { efTRX, "-f", NULL, ffREAD }, { efG87, "-to", NULL, ffOPTWR }, { efSTO, "-cz", "zconf",ffWRITE }, { efSTO, "-co", "waver",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,&oenv); bRange=(opt2parg_bSet("-ahxstart",asize(pa),pa) && opt2parg_bSet("-ahxend",asize(pa),pa)); top=read_top(ftp2fn(efTPX,NFILE,fnm),&ePBC); natoms=read_first_x(oenv,&status,opt2fn("-f",NFILE,fnm),&t,&x,box); if (opt2bSet("-to",NFILE,fnm)) { otrj=opt2FILE("-to",NFILE,fnm,"w"); strcpy(prop,ppp[0]); fprintf(otrj,"%s Weighted Trajectory: %d atoms, NO box\n",prop,natoms); } else otrj=NULL; if (natoms != top->atoms.nr) gmx_fatal(FARGS,"Sorry can only run when the number of atoms in the run input file (%d) is equal to the number in the trajectory (%d)", top->atoms.nr,natoms); bb=mkbbind(ftp2fn(efNDX,NFILE,fnm),&nres,&nbb,r0,&nall,&allindex, top->atoms.atomname,top->atoms.atom,top->atoms.resinfo); snew(bbindex,natoms); snew(caindex,nres); fprintf(stderr,"nall=%d\n",nall); /* Open output files, default x-axis is time */ for(i=0; (i<efhNR); i++) { sprintf(buf,"%s.xvg",xf[i].filenm); remove(buf); xf[i].fp=xvgropen(buf,xf[i].title, xf[i].xaxis ? xf[i].xaxis : "Time (ps)", xf[i].yaxis,oenv); if (xf[i].bfp2) { sprintf(buf,"%s.out",xf[i].filenm); remove(buf); xf[i].fp2=ffopen(buf,"w"); } } /* Read reference frame from tpx file to compute helix length */ snew(xref,top->atoms.nr); read_tpx(ftp2fn(efTPX,NFILE,fnm), NULL,NULL,&natoms,xref,NULL,NULL,NULL); calc_hxprops(nres,bb,xref,box); do_start_end(nres,bb,xref,&nbb,bbindex,&nca,caindex,bRange,rStart,rEnd); sfree(xref); if (bDBG) { fprintf(stderr,"nca=%d, nbb=%d\n",nca,nbb); pr_bb(stdout,nres,bb); } gpbc = gmx_rmpbc_init(&top->idef,ePBC,natoms,box); snew(xav,natoms); teller=0; do { if ((teller++ % 10) == 0) fprintf(stderr,"\rt=%.2f",t); gmx_rmpbc(gpbc,natoms,box,x); calc_hxprops(nres,bb,x,box); if (bCheck) do_start_end(nres,bb,x,&nbb,bbindex,&nca,caindex,FALSE,0,0); if (nca >= 5) { rms=fit_ahx(nres,bb,natoms,nall,allindex,x,nca,caindex,box,bFit); if (teller == 1) { write_sto_conf(opt2fn("-cz",NFILE,fnm),"Helix fitted to Z-Axis", &(top->atoms),x,NULL,ePBC,box); } xf[efhRAD].val = radius(xf[efhRAD].fp2,nca,caindex,x); xf[efhTWIST].val = twist(xf[efhTWIST].fp2,nca,caindex,x); xf[efhRISE].val = rise(nca,caindex,x); xf[efhLEN].val = ahx_len(nca,caindex,x,box); xf[efhCD222].val = ellipticity(nres,bb); xf[efhDIP].val = dip(nbb,bbindex,x,top->atoms.atom); xf[efhRMS].val = rms; xf[efhCPHI].val = ca_phi(nca,caindex,x,box); xf[efhPPRMS].val = pprms(xf[efhPPRMS].fp2,nres,bb); for(j=0; (j<=efhCPHI); j++) fprintf(xf[j].fp, "%10g %10g\n",t,xf[j].val); av_phipsi(xf[efhPHI].fp,xf[efhPSI].fp,xf[efhPHI].fp2,xf[efhPSI].fp2, t,nres,bb); av_hblen(xf[efhHB3].fp,xf[efhHB3].fp2, xf[efhHB4].fp,xf[efhHB4].fp2, xf[efhHB5].fp,xf[efhHB5].fp2, t,nres,bb); if (otrj) dump_otrj(otrj,nall,allindex,x,xf[nSel].val,xav); } } while (read_next_x(oenv,status,&t,natoms,x,box)); fprintf(stderr,"\n"); gmx_rmpbc_done(gpbc); close_trj(status); if (otrj) { ffclose(otrj); fac=1.0/teller; for(i=0; (i<nall); i++) { ai=allindex[i]; for(m=0; (m<DIM); m++) xav[ai][m]*=fac; } write_sto_conf_indexed(opt2fn("-co",NFILE,fnm), "Weighted and Averaged conformation", &(top->atoms),xav,NULL,ePBC,box,nall,allindex); } for(i=0; (i<nres); i++) { if (bb[i].nrms > 0) { fprintf(xf[efhRMSA].fp,"%10d %10g\n",r0+i,bb[i].rmsa/bb[i].nrms); } fprintf(xf[efhAHX].fp,"%10d %10g\n",r0+i,(bb[i].nhx*100.0)/(real )teller); fprintf(xf[efhJCA].fp,"%10d %10g\n", r0+i,140.3+(bb[i].jcaha/(double)teller)); } for(i=0; (i<efhNR); i++) { ffclose(xf[i].fp); if (xf[i].bfp2) ffclose(xf[i].fp2); do_view(oenv,xf[i].filenm,"-nxy"); } thanx(stderr); return 0; }