int find_gb_bondlength(t_params *plist,int ai,int aj, real *length) { int i,j,a1,a2; int found=0; int status; for(i=0;i<F_NRE && !found;i++) { if(IS_CHEMBOND(i)) { for(j=0;j<plist[i].nr; j++) { a1=plist[i].param[j].a[0]; a2=plist[i].param[j].a[1]; if( (a1==ai && a2==aj) || (a1==aj && a2==ai)) { /* Equilibrium bond distance */ *length=plist[i].param[j].c[0]; found=1; } } } } status = !found; return status; }
void gmx_tng_add_mtop(tng_trajectory_t tng, const gmx_mtop_t *mtop) { int i, j; const t_ilist *ilist; tng_bond_t tngBond; if (!mtop) { /* No topology information available to add. */ return; } for (int molIt = 0; molIt < mtop->nmolblock; molIt++) { tng_molecule_t tngMol = NULL; const gmx_moltype_t *molType = &mtop->moltype[mtop->molblock[molIt].type]; /* Add a molecule to the TNG trajectory with the same name as the * current molecule. */ addTngMoleculeFromTopology(tng, *(molType->name), &molType->atoms, mtop->molblock[molIt].nmol, &tngMol); /* Bonds have to be deduced from interactions (constraints etc). Different * interactions have different sets of parameters. */ /* Constraints are specified using two atoms */ for (i = 0; i < F_NRE; i++) { if (IS_CHEMBOND(i)) { ilist = &molType->ilist[i]; if (ilist) { j = 1; while (j < ilist->nr) { tng_molecule_bond_add(tng, tngMol, ilist->iatoms[j], ilist->iatoms[j+1], &tngBond); j += 3; } } } } /* Settle is described using three atoms */ ilist = &molType->ilist[F_SETTLE]; if (ilist) { j = 1; while (j < ilist->nr) { tng_molecule_bond_add(tng, tngMol, ilist->iatoms[j], ilist->iatoms[j+1], &tngBond); tng_molecule_bond_add(tng, tngMol, ilist->iatoms[j], ilist->iatoms[j+2], &tngBond); j += 4; } } } }
static void add_bpl(t_manager *man,t_idef *idef,bool bB[]) { int ftype; for(ftype=0; ftype<F_NRE; ftype++) if (IS_CHEMBOND(ftype) || ftype==F_SETTLE) add_bonds(man,idef->functype,&idef->il[ftype],bB); }
static void add_bonds(t_manager *man, t_functype func[], t_ilist *b, bool bB[]) { bool *bH = man->bHydro; t_iatom *ia; t_iatom type, ai, aj, ak; int i, delta, ftype; #ifdef DEBUG std::fprintf(stderr, "Going to make bonds from an ilist with %d entries\n", b->nr); #endif ia = b->iatoms; for (i = 0; (i < b->nr); ) { type = ia[0]; ai = ia[1]; ftype = func[type]; delta = interaction_function[ftype].nratoms; if (ftype == F_SETTLE) { aj = ia[2]; ak = ia[3]; bB[ai] = bB[aj] = bB[ak] = true; add_object(man, eOHBond, ai, aj); add_object(man, eOHBond, ai, ak); } else if (IS_CHEMBOND(ftype)) { aj = ia[2]; #ifdef DEBUG std::fprintf(stderr, "Adding bond from %d to %d\n", ai, aj); #endif bB[ai] = bB[aj] = true; if (!(bH[ai] == bH[aj])) { add_object(man, eOHBond, ai, aj); } else if (!bH[ai] && !bH[aj]) { add_object(man, eOBond, ai, aj); } } #ifdef DEBUG std::fprintf(stderr, "Type: %5d, delta: %5d\n", type, delta); #endif ia += delta+1; i += delta+1; } }
void gen_nnb(t_nextnb *nnb, t_params plist[]) { sortable *s; int i, nrbonds, nrf; nrbonds = 0; for (i = 0; (i < F_NRE); i++) { if (IS_CHEMBOND(i)) { /* we need every bond twice (bidirectional) */ nrbonds += 2*plist[i].nr; } } snew(s, nrbonds); nrf = 0; for (i = 0; (i < F_NRE); i++) { if (IS_CHEMBOND(i)) { add_b(&plist[i], &nrf, s); } } /* now sort the bonds */ prints("gen_excl before qsort", nrbonds, s); if (nrbonds > 1) { qsort((void *) s, nrbonds, (size_t)sizeof(sortable), bond_sort); prints("gen_excl after qsort", nrbonds, s); } do_gen(nrbonds, s, nnb); sfree(s); }
gmx_conect gmx_conect_generate(t_topology *top) { int f,i; gmx_conect gc; /* Fill the conect records */ gc = gmx_conect_init(); for(f=0; (f<F_NRE); f++) { if (IS_CHEMBOND(f)) for(i=0; (i<top->idef.il[f].nr); i+=interaction_function[f].nratoms+1) { gmx_conect_add(gc,top->idef.il[f].iatoms[i+1], top->idef.il[f].iatoms[i+2]); } } return gc; }
int gmx_rms(int argc, char *argv[]) { const char *desc[] = { "[THISMODULE] compares two structures by computing the root mean square", "deviation (RMSD), the size-independent [GRK]rho[grk] similarity parameter", "([TT]rho[tt]) or the scaled [GRK]rho[grk] ([TT]rhosc[tt]), ", "see Maiorov & Crippen, Proteins [BB]22[bb], 273 (1995).", "This is selected by [TT]-what[tt].[PAR]" "Each structure from a trajectory ([TT]-f[tt]) is compared to a", "reference structure. The reference structure", "is taken from the structure file ([TT]-s[tt]).[PAR]", "With option [TT]-mir[tt] also a comparison with the mirror image of", "the reference structure is calculated.", "This is useful as a reference for 'significant' values, see", "Maiorov & Crippen, Proteins [BB]22[bb], 273 (1995).[PAR]", "Option [TT]-prev[tt] produces the comparison with a previous frame", "the specified number of frames ago.[PAR]", "Option [TT]-m[tt] produces a matrix in [TT].xpm[tt] format of", "comparison values of each structure in the trajectory with respect to", "each other structure. This file can be visualized with for instance", "[TT]xv[tt] and can be converted to postscript with [gmx-xpm2ps].[PAR]", "Option [TT]-fit[tt] controls the least-squares fitting of", "the structures on top of each other: complete fit (rotation and", "translation), translation only, or no fitting at all.[PAR]", "Option [TT]-mw[tt] controls whether mass weighting is done or not.", "If you select the option (default) and ", "supply a valid [TT].tpr[tt] file masses will be taken from there, ", "otherwise the masses will be deduced from the [TT]atommass.dat[tt] file in", "[TT]GMXLIB[tt]. This is fine for proteins, but not", "necessarily for other molecules. A default mass of 12.011 amu (carbon)", "is assigned to unknown atoms. You can check whether this happend by", "turning on the [TT]-debug[tt] flag and inspecting the log file.[PAR]", "With [TT]-f2[tt], the 'other structures' are taken from a second", "trajectory, this generates a comparison matrix of one trajectory", "versus the other.[PAR]", "Option [TT]-bin[tt] does a binary dump of the comparison matrix.[PAR]", "Option [TT]-bm[tt] produces a matrix of average bond angle deviations", "analogously to the [TT]-m[tt] option. Only bonds between atoms in the", "comparison group are considered." }; static gmx_bool bPBC = TRUE, bFitAll = TRUE, bSplit = FALSE; static gmx_bool bDeltaLog = FALSE; static int prev = 0, freq = 1, freq2 = 1, nlevels = 80, avl = 0; static real rmsd_user_max = -1, rmsd_user_min = -1, bond_user_max = -1, bond_user_min = -1, delta_maxy = 0.0; /* strings and things for selecting difference method */ enum { ewSel, ewRMSD, ewRho, ewRhoSc, ewNR }; int ewhat; const char *what[ewNR + 1] = { NULL, "rmsd", "rho", "rhosc", NULL }; const char *whatname[ewNR] = { NULL, "RMSD", "Rho", "Rho sc" }; const char *whatlabel[ewNR] = { NULL, "RMSD (nm)", "Rho", "Rho sc" }; const char *whatxvgname[ewNR] = { NULL, "RMSD", "\\8r\\4", "\\8r\\4\\ssc\\N" }; const char *whatxvglabel[ewNR] = { NULL, "RMSD (nm)", "\\8r\\4", "\\8r\\4\\ssc\\N" }; /* strings and things for fitting methods */ enum { efSel, efFit, efReset, efNone, efNR }; int efit; const char *fit[efNR + 1] = { NULL, "rot+trans", "translation", "none", NULL }; const char *fitgraphlabel[efNR + 1] = { NULL, "lsq fit", "translational fit", "no fit" }; static int nrms = 1; static gmx_bool bMassWeighted = TRUE; t_pargs pa[] = { { "-what", FALSE, etENUM, { what }, "Structural difference measure" }, { "-pbc", FALSE, etBOOL, { &bPBC }, "PBC check" }, { "-fit", FALSE, etENUM, { fit }, "Fit to reference structure" }, { "-prev", FALSE, etINT, { &prev }, "Compare with previous frame" }, { "-split", FALSE, etBOOL, { &bSplit }, "Split graph where time is zero" }, { "-fitall", FALSE, etBOOL, { &bFitAll }, "HIDDENFit all pairs of structures in matrix" }, { "-skip", FALSE, etINT, { &freq }, "Only write every nr-th frame to matrix" }, { "-skip2", FALSE, etINT, { &freq2 }, "Only write every nr-th frame to matrix" }, { "-max", FALSE, etREAL, { &rmsd_user_max }, "Maximum level in comparison matrix" }, { "-min", FALSE, etREAL, { &rmsd_user_min }, "Minimum level in comparison matrix" }, { "-bmax", FALSE, etREAL, { &bond_user_max }, "Maximum level in bond angle matrix" }, { "-bmin", FALSE, etREAL, { &bond_user_min }, "Minimum level in bond angle matrix" }, { "-mw", FALSE, etBOOL, { &bMassWeighted }, "Use mass weighting for superposition" }, { "-nlevels", FALSE, etINT, { &nlevels }, "Number of levels in the matrices" }, { "-ng", FALSE, etINT, { &nrms }, "Number of groups to compute RMS between" }, { "-dlog", FALSE, etBOOL, { &bDeltaLog }, "HIDDENUse a log x-axis in the delta t matrix" }, { "-dmax", FALSE, etREAL, { &delta_maxy }, "HIDDENMaximum level in delta matrix" }, { "-aver", FALSE, etINT, { &avl }, "HIDDENAverage over this distance in the RMSD matrix" } }; int natoms_trx, natoms_trx2, natoms; int i, j, k, m, teller, teller2, tel_mat, tel_mat2; #define NFRAME 5000 int maxframe = NFRAME, maxframe2 = NFRAME; real t, *w_rls, *w_rms, *w_rls_m = NULL, *w_rms_m = NULL; gmx_bool bNorm, bAv, bFreq2, bFile2, bMat, bBond, bDelta, bMirror, bMass; gmx_bool bFit, bReset; t_topology top; int ePBC; t_iatom *iatom = NULL; matrix box; rvec *x, *xp, *xm = NULL, **mat_x = NULL, **mat_x2, *mat_x2_j = NULL, vec1, vec2; t_trxstatus *status; char buf[256], buf2[256]; int ncons = 0; FILE *fp; real rlstot = 0, **rls, **rlsm = NULL, *time, *time2, *rlsnorm = NULL, **rmsd_mat = NULL, **bond_mat = NULL, *axis, *axis2, *del_xaxis, *del_yaxis, rmsd_max, rmsd_min, rmsd_avg, bond_max, bond_min, ang; real **rmsdav_mat = NULL, av_tot, weight, weight_tot; real **delta = NULL, delta_max, delta_scalex = 0, delta_scaley = 0, *delta_tot; int delta_xsize = 0, del_lev = 100, mx, my, abs_my; gmx_bool bA1, bA2, bPrev, bTop, *bInMat = NULL; int ifit, *irms, ibond = 0, *ind_bond1 = NULL, *ind_bond2 = NULL, n_ind_m = 0; atom_id *ind_fit, **ind_rms, *ind_m = NULL, *rev_ind_m = NULL, *ind_rms_m = NULL; char *gn_fit, **gn_rms; t_rgb rlo, rhi; output_env_t oenv; gmx_rmpbc_t gpbc = NULL; t_filenm fnm[] = { { efTPS, NULL, NULL, ffREAD }, { efTRX, "-f", NULL, ffREAD }, { efTRX, "-f2", NULL, ffOPTRD }, { efNDX, NULL, NULL, ffOPTRD }, { efXVG, NULL, "rmsd", ffWRITE }, { efXVG, "-mir", "rmsdmir", ffOPTWR }, { efXVG, "-a", "avgrp", ffOPTWR }, { efXVG, "-dist", "rmsd-dist", ffOPTWR }, { efXPM, "-m", "rmsd", ffOPTWR }, { efDAT, "-bin", "rmsd", ffOPTWR }, { efXPM, "-bm", "bond", ffOPTWR } }; #define NFILE asize(fnm) if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW | PCA_BE_NICE, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, NULL, &oenv)) { return 0; } /* parse enumerated options: */ ewhat = nenum(what); if (ewhat == ewRho || ewhat == ewRhoSc) { please_cite(stdout, "Maiorov95"); } efit = nenum(fit); bFit = efit == efFit; bReset = efit == efReset; if (bFit) { bReset = TRUE; /* for fit, reset *must* be set */ } else { bFitAll = FALSE; } /* mark active cmdline options */ bMirror = opt2bSet("-mir", NFILE, fnm); /* calc RMSD vs mirror of ref. */ bFile2 = opt2bSet("-f2", NFILE, fnm); bMat = opt2bSet("-m", NFILE, fnm); bBond = opt2bSet("-bm", NFILE, fnm); bDelta = (delta_maxy > 0); /* calculate rmsd vs delta t matrix from * * your RMSD matrix (hidden option */ bNorm = opt2bSet("-a", NFILE, fnm); bFreq2 = opt2parg_bSet("-skip2", asize(pa), pa); if (freq <= 0) { fprintf(stderr, "The number of frames to skip is <= 0. " "Writing out all frames.\n\n"); freq = 1; } if (!bFreq2) { freq2 = freq; } else if (bFile2 && freq2 <= 0) { fprintf(stderr, "The number of frames to skip in second trajectory is <= 0.\n" " Writing out all frames.\n\n"); freq2 = 1; } bPrev = (prev > 0); if (bPrev) { prev = abs(prev); if (freq != 1) { fprintf(stderr, "WARNING: option -skip also applies to -prev\n"); } } if (bFile2 && !bMat && !bBond) { fprintf( stderr, "WARNING: second trajectory (-f2) useless when not calculating matrix (-m/-bm),\n" " will not read from %s\n", opt2fn("-f2", NFILE, fnm)); bFile2 = FALSE; } if (bDelta) { bMat = TRUE; if (bFile2) { fprintf(stderr, "WARNING: second trajectory (-f2) useless when making delta matrix,\n" " will not read from %s\n", opt2fn("-f2", NFILE, fnm)); bFile2 = FALSE; } } bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), buf, &top, &ePBC, &xp, NULL, box, TRUE); snew(w_rls, top.atoms.nr); snew(w_rms, top.atoms.nr); if (!bTop && bBond) { fprintf(stderr, "WARNING: Need a run input file for bond angle matrix,\n" " will not calculate bond angle matrix.\n"); bBond = FALSE; } if (bReset) { fprintf(stderr, "Select group for %s fit\n", bFit ? "least squares" : "translational"); get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &ifit, &ind_fit, &gn_fit); } else { ifit = 0; } if (bReset) { if (bFit && ifit < 3) { gmx_fatal(FARGS, "Need >= 3 points to fit!\n" ); } bMass = FALSE; for (i = 0; i < ifit; i++) { if (bMassWeighted) { w_rls[ind_fit[i]] = top.atoms.atom[ind_fit[i]].m; } else { w_rls[ind_fit[i]] = 1; } bMass = bMass || (top.atoms.atom[ind_fit[i]].m != 0); } if (!bMass) { fprintf(stderr, "All masses in the fit group are 0, using masses of 1\n"); for (i = 0; i < ifit; i++) { w_rls[ind_fit[i]] = 1; } } } if (bMat || bBond) { nrms = 1; } snew(gn_rms, nrms); snew(ind_rms, nrms); snew(irms, nrms); fprintf(stderr, "Select group%s for %s calculation\n", (nrms > 1) ? "s" : "", whatname[ewhat]); get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), nrms, irms, ind_rms, gn_rms); if (bNorm) { snew(rlsnorm, irms[0]); } snew(rls, nrms); for (j = 0; j < nrms; j++) { snew(rls[j], maxframe); } if (bMirror) { snew(rlsm, nrms); for (j = 0; j < nrms; j++) { snew(rlsm[j], maxframe); } } snew(time, maxframe); for (j = 0; j < nrms; j++) { bMass = FALSE; for (i = 0; i < irms[j]; i++) { if (bMassWeighted) { w_rms[ind_rms[j][i]] = top.atoms.atom[ind_rms[j][i]].m; } else { w_rms[ind_rms[j][i]] = 1.0; } bMass = bMass || (top.atoms.atom[ind_rms[j][i]].m != 0); } if (!bMass) { fprintf(stderr, "All masses in group %d are 0, using masses of 1\n", j); for (i = 0; i < irms[j]; i++) { w_rms[ind_rms[j][i]] = 1; } } } /* Prepare reference frame */ if (bPBC) { gpbc = gmx_rmpbc_init(&top.idef, ePBC, top.atoms.nr); gmx_rmpbc(gpbc, top.atoms.nr, box, xp); } if (bReset) { reset_x(ifit, ind_fit, top.atoms.nr, NULL, xp, w_rls); } if (bMirror) { /* generate reference structure mirror image: */ snew(xm, top.atoms.nr); for (i = 0; i < top.atoms.nr; i++) { copy_rvec(xp[i], xm[i]); xm[i][XX] = -xm[i][XX]; } } if (ewhat == ewRhoSc) { norm_princ(&top.atoms, ifit, ind_fit, top.atoms.nr, xp); } /* read first frame */ natoms_trx = read_first_x(oenv, &status, opt2fn("-f", NFILE, fnm), &t, &x, box); if (natoms_trx != top.atoms.nr) { fprintf(stderr, "\nWARNING: topology has %d atoms, whereas trajectory has %d\n", top.atoms.nr, natoms_trx); } natoms = min(top.atoms.nr, natoms_trx); if (bMat || bBond || bPrev) { snew(mat_x, NFRAME); if (bPrev) { /* With -prev we use all atoms for simplicity */ n_ind_m = natoms; } else { /* Check which atoms we need (fit/rms) */ snew(bInMat, natoms); for (i = 0; i < ifit; i++) { bInMat[ind_fit[i]] = TRUE; } n_ind_m = ifit; for (i = 0; i < irms[0]; i++) { if (!bInMat[ind_rms[0][i]]) { bInMat[ind_rms[0][i]] = TRUE; n_ind_m++; } } } /* Make an index of needed atoms */ snew(ind_m, n_ind_m); snew(rev_ind_m, natoms); j = 0; for (i = 0; i < natoms; i++) { if (bPrev || bInMat[i]) { ind_m[j] = i; rev_ind_m[i] = j; j++; } } snew(w_rls_m, n_ind_m); snew(ind_rms_m, irms[0]); snew(w_rms_m, n_ind_m); for (i = 0; i < ifit; i++) { w_rls_m[rev_ind_m[ind_fit[i]]] = w_rls[ind_fit[i]]; } for (i = 0; i < irms[0]; i++) { ind_rms_m[i] = rev_ind_m[ind_rms[0][i]]; w_rms_m[ind_rms_m[i]] = w_rms[ind_rms[0][i]]; } sfree(bInMat); } if (bBond) { ncons = 0; for (k = 0; k < F_NRE; k++) { if (IS_CHEMBOND(k)) { iatom = top.idef.il[k].iatoms; ncons += top.idef.il[k].nr/3; } } fprintf(stderr, "Found %d bonds in topology\n", ncons); snew(ind_bond1, ncons); snew(ind_bond2, ncons); ibond = 0; for (k = 0; k < F_NRE; k++) { if (IS_CHEMBOND(k)) { iatom = top.idef.il[k].iatoms; ncons = top.idef.il[k].nr/3; for (i = 0; i < ncons; i++) { bA1 = FALSE; bA2 = FALSE; for (j = 0; j < irms[0]; j++) { if (iatom[3*i+1] == ind_rms[0][j]) { bA1 = TRUE; } if (iatom[3*i+2] == ind_rms[0][j]) { bA2 = TRUE; } } if (bA1 && bA2) { ind_bond1[ibond] = rev_ind_m[iatom[3*i+1]]; ind_bond2[ibond] = rev_ind_m[iatom[3*i+2]]; ibond++; } } } } fprintf(stderr, "Using %d bonds for bond angle matrix\n", ibond); if (ibond == 0) { gmx_fatal(FARGS, "0 bonds found"); } } /* start looping over frames: */ tel_mat = 0; teller = 0; do { if (bPBC) { gmx_rmpbc(gpbc, natoms, box, x); } if (bReset) { reset_x(ifit, ind_fit, natoms, NULL, x, w_rls); } if (ewhat == ewRhoSc) { norm_princ(&top.atoms, ifit, ind_fit, natoms, x); } if (bFit) { /*do the least squares fit to original structure*/ do_fit(natoms, w_rls, xp, x); } if (teller % freq == 0) { /* keep frame for matrix calculation */ if (bMat || bBond || bPrev) { if (tel_mat >= NFRAME) { srenew(mat_x, tel_mat+1); } snew(mat_x[tel_mat], n_ind_m); for (i = 0; i < n_ind_m; i++) { copy_rvec(x[ind_m[i]], mat_x[tel_mat][i]); } } tel_mat++; } /*calculate energy of root_least_squares*/ if (bPrev) { j = tel_mat-prev-1; if (j < 0) { j = 0; } for (i = 0; i < n_ind_m; i++) { copy_rvec(mat_x[j][i], xp[ind_m[i]]); } if (bReset) { reset_x(ifit, ind_fit, natoms, NULL, xp, w_rls); } if (bFit) { do_fit(natoms, w_rls, x, xp); } } for (j = 0; (j < nrms); j++) { rls[j][teller] = calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xp); } if (bNorm) { for (j = 0; (j < irms[0]); j++) { rlsnorm[j] += calc_similar_ind(ewhat != ewRMSD, 1, &(ind_rms[0][j]), w_rms, x, xp); } } if (bMirror) { if (bFit) { /*do the least squares fit to mirror of original structure*/ do_fit(natoms, w_rls, xm, x); } for (j = 0; j < nrms; j++) { rlsm[j][teller] = calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xm); } } time[teller] = output_env_conv_time(oenv, t); teller++; if (teller >= maxframe) { maxframe += NFRAME; srenew(time, maxframe); for (j = 0; (j < nrms); j++) { srenew(rls[j], maxframe); } if (bMirror) { for (j = 0; (j < nrms); j++) { srenew(rlsm[j], maxframe); } } } } while (read_next_x(oenv, status, &t, x, box)); close_trj(status); if (bFile2) { snew(time2, maxframe2); fprintf(stderr, "\nWill read second trajectory file\n"); snew(mat_x2, NFRAME); natoms_trx2 = read_first_x(oenv, &status, opt2fn("-f2", NFILE, fnm), &t, &x, box); if (natoms_trx2 != natoms_trx) { gmx_fatal(FARGS, "Second trajectory (%d atoms) does not match the first one" " (%d atoms)", natoms_trx2, natoms_trx); } tel_mat2 = 0; teller2 = 0; do { if (bPBC) { gmx_rmpbc(gpbc, natoms, box, x); } if (bReset) { reset_x(ifit, ind_fit, natoms, NULL, x, w_rls); } if (ewhat == ewRhoSc) { norm_princ(&top.atoms, ifit, ind_fit, natoms, x); } if (bFit) { /*do the least squares fit to original structure*/ do_fit(natoms, w_rls, xp, x); } if (teller2 % freq2 == 0) { /* keep frame for matrix calculation */ if (bMat) { if (tel_mat2 >= NFRAME) { srenew(mat_x2, tel_mat2+1); } snew(mat_x2[tel_mat2], n_ind_m); for (i = 0; i < n_ind_m; i++) { copy_rvec(x[ind_m[i]], mat_x2[tel_mat2][i]); } } tel_mat2++; } time2[teller2] = output_env_conv_time(oenv, t); teller2++; if (teller2 >= maxframe2) { maxframe2 += NFRAME; srenew(time2, maxframe2); } } while (read_next_x(oenv, status, &t, x, box)); close_trj(status); } else { mat_x2 = mat_x; time2 = time; tel_mat2 = tel_mat; freq2 = freq; } gmx_rmpbc_done(gpbc); if (bMat || bBond) { /* calculate RMS matrix */ fprintf(stderr, "\n"); if (bMat) { fprintf(stderr, "Building %s matrix, %dx%d elements\n", whatname[ewhat], tel_mat, tel_mat2); snew(rmsd_mat, tel_mat); } if (bBond) { fprintf(stderr, "Building bond angle matrix, %dx%d elements\n", tel_mat, tel_mat2); snew(bond_mat, tel_mat); } snew(axis, tel_mat); snew(axis2, tel_mat2); rmsd_max = 0; if (bFile2) { rmsd_min = 1e10; } else { rmsd_min = 0; } rmsd_avg = 0; bond_max = 0; bond_min = 1e10; for (j = 0; j < tel_mat2; j++) { axis2[j] = time2[freq2*j]; } if (bDelta) { if (bDeltaLog) { delta_scalex = 8.0/log(2.0); delta_xsize = (int)(log(tel_mat/2)*delta_scalex+0.5)+1; } else { delta_xsize = tel_mat/2; } delta_scaley = 1.0/delta_maxy; snew(delta, delta_xsize); for (j = 0; j < delta_xsize; j++) { snew(delta[j], del_lev+1); } if (avl > 0) { snew(rmsdav_mat, tel_mat); for (j = 0; j < tel_mat; j++) { snew(rmsdav_mat[j], tel_mat); } } } if (bFitAll) { snew(mat_x2_j, natoms); } for (i = 0; i < tel_mat; i++) { axis[i] = time[freq*i]; fprintf(stderr, "\r element %5d; time %5.2f ", i, axis[i]); if (bMat) { snew(rmsd_mat[i], tel_mat2); } if (bBond) { snew(bond_mat[i], tel_mat2); } for (j = 0; j < tel_mat2; j++) { if (bFitAll) { for (k = 0; k < n_ind_m; k++) { copy_rvec(mat_x2[j][k], mat_x2_j[k]); } do_fit(n_ind_m, w_rls_m, mat_x[i], mat_x2_j); } else { mat_x2_j = mat_x2[j]; } if (bMat) { if (bFile2 || (i < j)) { rmsd_mat[i][j] = calc_similar_ind(ewhat != ewRMSD, irms[0], ind_rms_m, w_rms_m, mat_x[i], mat_x2_j); if (rmsd_mat[i][j] > rmsd_max) { rmsd_max = rmsd_mat[i][j]; } if (rmsd_mat[i][j] < rmsd_min) { rmsd_min = rmsd_mat[i][j]; } rmsd_avg += rmsd_mat[i][j]; } else { rmsd_mat[i][j] = rmsd_mat[j][i]; } } if (bBond) { if (bFile2 || (i <= j)) { ang = 0.0; for (m = 0; m < ibond; m++) { rvec_sub(mat_x[i][ind_bond1[m]], mat_x[i][ind_bond2[m]], vec1); rvec_sub(mat_x2_j[ind_bond1[m]], mat_x2_j[ind_bond2[m]], vec2); ang += acos(cos_angle(vec1, vec2)); } bond_mat[i][j] = ang*180.0/(M_PI*ibond); if (bond_mat[i][j] > bond_max) { bond_max = bond_mat[i][j]; } if (bond_mat[i][j] < bond_min) { bond_min = bond_mat[i][j]; } } else { bond_mat[i][j] = bond_mat[j][i]; } } } } if (bFile2) { rmsd_avg /= tel_mat*tel_mat2; } else { rmsd_avg /= tel_mat*(tel_mat - 1)/2; } if (bMat && (avl > 0)) { rmsd_max = 0.0; rmsd_min = 0.0; rmsd_avg = 0.0; for (j = 0; j < tel_mat-1; j++) { for (i = j+1; i < tel_mat; i++) { av_tot = 0; weight_tot = 0; for (my = -avl; my <= avl; my++) { if ((j+my >= 0) && (j+my < tel_mat)) { abs_my = abs(my); for (mx = -avl; mx <= avl; mx++) { if ((i+mx >= 0) && (i+mx < tel_mat)) { weight = (real)(avl+1-max(abs(mx), abs_my)); av_tot += weight*rmsd_mat[i+mx][j+my]; weight_tot += weight; } } } } rmsdav_mat[i][j] = av_tot/weight_tot; rmsdav_mat[j][i] = rmsdav_mat[i][j]; if (rmsdav_mat[i][j] > rmsd_max) { rmsd_max = rmsdav_mat[i][j]; } } } rmsd_mat = rmsdav_mat; } if (bMat) { fprintf(stderr, "\n%s: Min %f, Max %f, Avg %f\n", whatname[ewhat], rmsd_min, rmsd_max, rmsd_avg); rlo.r = 1; rlo.g = 1; rlo.b = 1; rhi.r = 0; rhi.g = 0; rhi.b = 0; if (rmsd_user_max != -1) { rmsd_max = rmsd_user_max; } if (rmsd_user_min != -1) { rmsd_min = rmsd_user_min; } if ((rmsd_user_max != -1) || (rmsd_user_min != -1)) { fprintf(stderr, "Min and Max value set to resp. %f and %f\n", rmsd_min, rmsd_max); } sprintf(buf, "%s %s matrix", gn_rms[0], whatname[ewhat]); write_xpm(opt2FILE("-m", NFILE, fnm, "w"), 0, buf, whatlabel[ewhat], output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2, axis, axis2, rmsd_mat, rmsd_min, rmsd_max, rlo, rhi, &nlevels); /* Print the distribution of RMSD values */ if (opt2bSet("-dist", NFILE, fnm)) { low_rmsd_dist(opt2fn("-dist", NFILE, fnm), rmsd_max, tel_mat, rmsd_mat, oenv); } if (bDelta) { snew(delta_tot, delta_xsize); for (j = 0; j < tel_mat-1; j++) { for (i = j+1; i < tel_mat; i++) { mx = i-j; if (mx < tel_mat/2) { if (bDeltaLog) { mx = (int)(log(mx)*delta_scalex+0.5); } my = (int)(rmsd_mat[i][j]*delta_scaley*del_lev+0.5); delta_tot[mx] += 1.0; if ((rmsd_mat[i][j] >= 0) && (rmsd_mat[i][j] <= delta_maxy)) { delta[mx][my] += 1.0; } } } } delta_max = 0; for (i = 0; i < delta_xsize; i++) { if (delta_tot[i] > 0.0) { delta_tot[i] = 1.0/delta_tot[i]; for (j = 0; j <= del_lev; j++) { delta[i][j] *= delta_tot[i]; if (delta[i][j] > delta_max) { delta_max = delta[i][j]; } } } } fprintf(stderr, "Maximum in delta matrix: %f\n", delta_max); snew(del_xaxis, delta_xsize); snew(del_yaxis, del_lev+1); for (i = 0; i < delta_xsize; i++) { del_xaxis[i] = axis[i]-axis[0]; } for (i = 0; i < del_lev+1; i++) { del_yaxis[i] = delta_maxy*i/del_lev; } sprintf(buf, "%s %s vs. delta t", gn_rms[0], whatname[ewhat]); fp = gmx_ffopen("delta.xpm", "w"); write_xpm(fp, 0, buf, "density", output_env_get_time_label(oenv), whatlabel[ewhat], delta_xsize, del_lev+1, del_xaxis, del_yaxis, delta, 0.0, delta_max, rlo, rhi, &nlevels); gmx_ffclose(fp); } if (opt2bSet("-bin", NFILE, fnm)) { /* NB: File must be binary if we use fwrite */ fp = ftp2FILE(efDAT, NFILE, fnm, "wb"); for (i = 0; i < tel_mat; i++) { if (fwrite(rmsd_mat[i], sizeof(**rmsd_mat), tel_mat2, fp) != tel_mat2) { gmx_fatal(FARGS, "Error writing to output file"); } } gmx_ffclose(fp); } } if (bBond) { fprintf(stderr, "\nMin. angle: %f, Max. angle: %f\n", bond_min, bond_max); if (bond_user_max != -1) { bond_max = bond_user_max; } if (bond_user_min != -1) { bond_min = bond_user_min; } if ((bond_user_max != -1) || (bond_user_min != -1)) { fprintf(stderr, "Bond angle Min and Max set to:\n" "Min. angle: %f, Max. angle: %f\n", bond_min, bond_max); } rlo.r = 1; rlo.g = 1; rlo.b = 1; rhi.r = 0; rhi.g = 0; rhi.b = 0; sprintf(buf, "%s av. bond angle deviation", gn_rms[0]); write_xpm(opt2FILE("-bm", NFILE, fnm, "w"), 0, buf, "degrees", output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2, axis, axis2, bond_mat, bond_min, bond_max, rlo, rhi, &nlevels); } } bAv = opt2bSet("-a", NFILE, fnm); /* Write the RMSD's to file */ if (!bPrev) { sprintf(buf, "%s", whatxvgname[ewhat]); } else { sprintf(buf, "%s with frame %g %s ago", whatxvgname[ewhat], time[prev*freq]-time[0], output_env_get_time_label(oenv)); } fp = xvgropen(opt2fn("-o", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv), whatxvglabel[ewhat], oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"%s%s after %s%s%s\"\n", (nrms == 1) ? "" : "of ", gn_rms[0], fitgraphlabel[efit], bFit ? " to " : "", bFit ? gn_fit : ""); } if (nrms != 1) { xvgr_legend(fp, nrms, (const char**)gn_rms, oenv); } for (i = 0; (i < teller); i++) { if (bSplit && i > 0 && abs(time[bPrev ? freq*i : i]/output_env_get_time_factor(oenv)) < 1e-5) { fprintf(fp, "&\n"); } fprintf(fp, "%12.7f", time[bPrev ? freq*i : i]); for (j = 0; (j < nrms); j++) { fprintf(fp, " %12.7f", rls[j][i]); if (bAv) { rlstot += rls[j][i]; } } fprintf(fp, "\n"); } gmx_ffclose(fp); if (bMirror) { /* Write the mirror RMSD's to file */ sprintf(buf, "%s with Mirror", whatxvgname[ewhat]); sprintf(buf2, "Mirror %s", whatxvglabel[ewhat]); fp = xvgropen(opt2fn("-mir", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv), buf2, oenv); if (nrms == 1) { if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"of %s after lsq fit to mirror of %s\"\n", gn_rms[0], gn_fit); } } else { if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"after lsq fit to mirror %s\"\n", gn_fit); } xvgr_legend(fp, nrms, (const char**)gn_rms, oenv); } for (i = 0; (i < teller); i++) { if (bSplit && i > 0 && abs(time[i]) < 1e-5) { fprintf(fp, "&\n"); } fprintf(fp, "%12.7f", time[i]); for (j = 0; (j < nrms); j++) { fprintf(fp, " %12.7f", rlsm[j][i]); } fprintf(fp, "\n"); } gmx_ffclose(fp); } if (bAv) { sprintf(buf, "Average %s", whatxvgname[ewhat]); sprintf(buf2, "Average %s", whatxvglabel[ewhat]); fp = xvgropen(opt2fn("-a", NFILE, fnm), buf, "Residue", buf2, oenv); for (j = 0; (j < nrms); j++) { fprintf(fp, "%10d %10g\n", j, rlstot/teller); } gmx_ffclose(fp); } if (bNorm) { fp = xvgropen("aver.xvg", gn_rms[0], "Residue", whatxvglabel[ewhat], oenv); for (j = 0; (j < irms[0]); j++) { fprintf(fp, "%10d %10g\n", j, rlsnorm[j]/teller); } gmx_ffclose(fp); } do_view(oenv, opt2fn_null("-a", NFILE, fnm), "-graphtype bar"); do_view(oenv, opt2fn("-o", NFILE, fnm), NULL); do_view(oenv, opt2fn_null("-mir", NFILE, fnm), NULL); do_view(oenv, opt2fn_null("-m", NFILE, fnm), NULL); do_view(oenv, opt2fn_null("-bm", NFILE, fnm), NULL); do_view(oenv, opt2fn_null("-dist", NFILE, fnm), NULL); return 0; }
/* Create a TNG molecule representing the selection groups * to write */ static void add_selection_groups(tng_trajectory_t tng, const gmx_mtop_t *mtop) { const gmx_moltype_t *molType; const t_atoms *atoms; const t_atom *at; const t_resinfo *resInfo; const t_ilist *ilist; int nAtoms = 0, i = 0, j, molIt, atomIt, nameIndex; int atom_offset = 0; tng_molecule_t mol, iterMol; tng_chain_t chain; tng_residue_t res; tng_atom_t atom; tng_bond_t tngBond; gmx_int64_t nMols; char *groupName; /* The name of the TNG molecule containing the selection group is the * same as the name of the selection group. */ nameIndex = *mtop->groups.grps[egcCompressedX].nm_ind; groupName = *mtop->groups.grpname[nameIndex]; tng_molecule_alloc(tng, &mol); tng_molecule_name_set(tng, mol, groupName); tng_molecule_chain_add(tng, mol, "", &chain); for (molIt = 0; molIt < mtop->nmoltype; molIt++) { molType = &mtop->moltype[mtop->molblock[molIt].type]; atoms = &molType->atoms; for (j = 0; j < mtop->molblock[molIt].nmol; j++) { bool bAtomsAdded = FALSE; for (atomIt = 0; atomIt < atoms->nr; atomIt++, i++) { char *res_name; int res_id; if (ggrpnr(&mtop->groups, egcCompressedX, i) != 0) { continue; } at = &atoms->atom[atomIt]; if (atoms->nres > 0) { resInfo = &atoms->resinfo[at->resind]; /* FIXME: When TNG supports both residue index and residue * number the latter should be used. */ res_name = *resInfo->name; res_id = at->resind + 1; } else { res_name = (char *)""; res_id = 0; } if (tng_chain_residue_find(tng, chain, res_name, res_id, &res) != TNG_SUCCESS) { /* Since there is ONE chain for selection groups do not keep the * original residue IDs - otherwise there might be conflicts. */ tng_chain_residue_add(tng, chain, res_name, &res); } tng_residue_atom_w_id_add(tng, res, *(atoms->atomname[atomIt]), *(atoms->atomtype[atomIt]), atom_offset + atomIt, &atom); nAtoms++; bAtomsAdded = TRUE; } /* Add bonds. */ if (bAtomsAdded) { for (int k = 0; k < F_NRE; k++) { if (IS_CHEMBOND(k)) { ilist = &molType->ilist[k]; if (ilist) { int l = 1; while (l < ilist->nr) { int atom1, atom2; atom1 = ilist->iatoms[l] + atom_offset; atom2 = ilist->iatoms[l+1] + atom_offset; if (ggrpnr(&mtop->groups, egcCompressedX, atom1) == 0 && ggrpnr(&mtop->groups, egcCompressedX, atom2) == 0) { tng_molecule_bond_add(tng, mol, ilist->iatoms[l], ilist->iatoms[l+1], &tngBond); } l += 3; } } } } /* Settle is described using three atoms */ ilist = &molType->ilist[F_SETTLE]; if (ilist) { int l = 1; while (l < ilist->nr) { int atom1, atom2, atom3; atom1 = ilist->iatoms[l] + atom_offset; atom2 = ilist->iatoms[l+1] + atom_offset; atom3 = ilist->iatoms[l+2] + atom_offset; if (ggrpnr(&mtop->groups, egcCompressedX, atom1) == 0) { if (ggrpnr(&mtop->groups, egcCompressedX, atom2) == 0) { tng_molecule_bond_add(tng, mol, atom1, atom2, &tngBond); } if (ggrpnr(&mtop->groups, egcCompressedX, atom3) == 0) { tng_molecule_bond_add(tng, mol, atom1, atom3, &tngBond); } } l += 4; } } } atom_offset += atoms->nr; } } if (nAtoms != i) { tng_molecule_existing_add(tng, &mol); tng_molecule_cnt_set(tng, mol, 1); tng_num_molecule_types_get(tng, &nMols); for (gmx_int64_t k = 0; k < nMols; k++) { tng_molecule_of_index_get(tng, k, &iterMol); if (iterMol == mol) { continue; } tng_molecule_cnt_set(tng, iterMol, 0); } } else { tng_molecule_free(tng, &mol); } }
static void generate_qmexcl_moltype(gmx_moltype_t *molt,unsigned char *grpnr, t_inputrec *ir) { /* This routine expects molt->ilist to be of size F_NRE and ordered. */ /* generates the exclusions between the individual QM atoms, as * these interactions should be handled by the QM subroutines and * not by the gromacs routines */ int i,j,l,k=0,jmax,qm_max=0,qm_nr=0,nratoms=0,link_nr=0,link_max=0; atom_id *qm_arr=NULL,*link_arr=NULL,a1,a2,a3,a4,ftype=0; t_blocka qmexcl; t_block2 qmexcl2; gmx_bool *bQMMM,*blink,bexcl; /* First we search and select the QM atoms in an qm_arr array that * we use to create the exclusions. * * we take the possibility into account that a user has defined more * than one QM group: * * for that we also need to do this an ugly work-about just in case * the QM group contains the entire system... */ fprintf(stderr,"excluding classical QM-QM interactions...\n"); jmax = ir->opts.ngQM; /* we first search for all the QM atoms and put them in an array */ for(j=0;j<jmax;j++){ for(i=0;i<molt->atoms.nr;i++){ if(qm_nr>=qm_max){ qm_max += 100; srenew(qm_arr,qm_max); } if ((grpnr ? grpnr[i] : 0) == j){ qm_arr[qm_nr++] = i; } } } /* bQMMM[..] is an array containin TRUE/FALSE for atoms that are * QM/not QM. We first set all elements to false. Afterwards we use * the qm_arr to change the elements corresponding to the QM atoms * to TRUE. */ snew(bQMMM,molt->atoms.nr); for (i=0;i<molt->atoms.nr;i++) bQMMM[i]=FALSE; for (i=0;i<qm_nr;i++) bQMMM[qm_arr[i]]=TRUE; /* We remove all bonded interactions (i.e. bonds, * angles, dihedrals, 1-4's), involving the QM atoms. The way they * are removed is as follows: if the interaction invloves 2 atoms, * it is removed if both atoms are QMatoms. If it involves 3 atoms, * it is removed if at least two of the atoms are QM atoms, if the * interaction involves 4 atoms, it is removed if there are at least * 2 QM atoms. Since this routine is called once before any forces * are computed, the top->idef.il[N].iatom[] array (see idef.h) can * be rewritten at this poitn without any problem. 25-9-2002 */ /* first check weter we already have CONNBONDS: */ if (molt->ilist[F_CONNBONDS].nr != 0){ fprintf(stderr,"nr. of CONNBONDS present already: %d\n", molt->ilist[F_CONNBONDS].nr/3); ftype = molt->ilist[F_CONNBONDS].iatoms[0]; k = molt->ilist[F_CONNBONDS].nr; } /* now we delete all bonded interactions, except the ones describing * a chemical bond. These are converted to CONNBONDS */ for (i=0;i<F_LJ;i++){ if(i==F_CONNBONDS) continue; nratoms = interaction_function[i].nratoms; j = 0; while (j<molt->ilist[i].nr){ bexcl = FALSE; switch (nratoms){ case 2: a1 = molt->ilist[i].iatoms[j+1]; a2 = molt->ilist[i].iatoms[j+2]; bexcl = (bQMMM[a1] && bQMMM[a2]); /* a bonded beteen two QM atoms will be copied to the * CONNBONDS list, for reasons mentioned above */ if(bexcl && i<F_ANGLES){ srenew(molt->ilist[F_CONNBONDS].iatoms,k+3); molt->ilist[F_CONNBONDS].nr += 3; molt->ilist[F_CONNBONDS].iatoms[k++] = ftype; molt->ilist[F_CONNBONDS].iatoms[k++] = a1; molt->ilist[F_CONNBONDS].iatoms[k++] = a2; } break; case 3: a1 = molt->ilist[i].iatoms[j+1]; a2 = molt->ilist[i].iatoms[j+2]; a3 = molt->ilist[i].iatoms[j+3]; bexcl = ((bQMMM[a1] && bQMMM[a2]) || (bQMMM[a1] && bQMMM[a3]) || (bQMMM[a2] && bQMMM[a3])); break; case 4: a1 = molt->ilist[i].iatoms[j+1]; a2 = molt->ilist[i].iatoms[j+2]; a3 = molt->ilist[i].iatoms[j+3]; a4 = molt->ilist[i].iatoms[j+4]; bexcl = ((bQMMM[a1] && bQMMM[a2] && bQMMM[a3]) || (bQMMM[a1] && bQMMM[a2] && bQMMM[a4]) || (bQMMM[a1] && bQMMM[a3] && bQMMM[a4]) || (bQMMM[a2] && bQMMM[a3] && bQMMM[a4])); break; default: gmx_fatal(FARGS,"no such bonded interactions with %d atoms\n",nratoms); } if (bexcl){ /* since the interaction involves QM atoms, these should be * removed from the MM ilist */ molt->ilist[i].nr -= (nratoms+1); for (l=j;l<molt->ilist[i].nr;l++) molt->ilist[i].iatoms[l] = molt->ilist[i].iatoms[l+(nratoms+1)]; } else { j += nratoms+1; /* the +1 is for the functype */ } } } /* Now, we search for atoms bonded to a QM atom because we also want * to exclude their nonbonded interactions with the QM atoms. The * reason for this is that this interaction is accounted for in the * linkatoms interaction with the QMatoms and would be counted * twice. */ for(i=0;i<F_NRE;i++){ if(IS_CHEMBOND(i)){ j=0; while(j<molt->ilist[i].nr){ a1 = molt->ilist[i].iatoms[j+1]; a2 = molt->ilist[i].iatoms[j+2]; if((bQMMM[a1] && !bQMMM[a2])||(!bQMMM[a1] && bQMMM[a2])){ if(link_nr>=link_max){ link_max += 10; srenew(link_arr,link_max); } if(bQMMM[a1]){ link_arr[link_nr++] = a2; } else { link_arr[link_nr++] = a1; } } j+=3; } } } snew(blink,molt->atoms.nr); for (i=0;i<molt->atoms.nr;i++) blink[i]=FALSE; for (i=0;i<link_nr;i++) blink[link_arr[i]]=TRUE; /* creating the exclusion block for the QM atoms. Each QM atom has * as excluded elements all the other QMatoms (and itself). */ qmexcl.nr = molt->atoms.nr; qmexcl.nra = qm_nr*(qm_nr+link_nr)+link_nr*qm_nr; snew(qmexcl.index,qmexcl.nr+1); snew(qmexcl.a,qmexcl.nra); j=0; for(i=0;i<qmexcl.nr;i++){ qmexcl.index[i]=j; if(bQMMM[i]){ for(k=0;k<qm_nr;k++){ qmexcl.a[k+j] = qm_arr[k]; } for(k=0;k<link_nr;k++){ qmexcl.a[qm_nr+k+j] = link_arr[k]; } j+=(qm_nr+link_nr); } if(blink[i]){ for(k=0;k<qm_nr;k++){ qmexcl.a[k+j] = qm_arr[k]; } j+=qm_nr; } } qmexcl.index[qmexcl.nr]=j; /* and merging with the exclusions already present in sys. */ init_block2(&qmexcl2,molt->atoms.nr); b_to_b2(&qmexcl, &qmexcl2); merge_excl(&(molt->excls),&qmexcl2); done_block2(&qmexcl2); /* Finally, we also need to get rid of the pair interactions of the * classical atom bonded to the boundary QM atoms with the QMatoms, * as this interaction is already accounted for by the QM, so also * here we run the risk of double counting! We proceed in a similar * way as we did above for the other bonded interactions: */ for (i=F_LJ14;i<F_COUL14;i++){ nratoms = interaction_function[i].nratoms; j = 0; while (j<molt->ilist[i].nr){ bexcl = FALSE; a1 = molt->ilist[i].iatoms[j+1]; a2 = molt->ilist[i].iatoms[j+2]; bexcl = ((bQMMM[a1] && bQMMM[a2])|| (blink[a1] && bQMMM[a2])|| (bQMMM[a1] && blink[a2])); if (bexcl){ /* since the interaction involves QM atoms, these should be * removed from the MM ilist */ molt->ilist[i].nr -= (nratoms+1); for (k=j;k<molt->ilist[i].nr;k++) molt->ilist[i].iatoms[k] = molt->ilist[i].iatoms[k+(nratoms+1)]; } else { j += nratoms+1; /* the +1 is for the functype */ } } } free(qm_arr); free(bQMMM); free(link_arr); free(blink); } /* generate_qmexcl */
static void clean_vsite_bonds(t_params *plist, t_pindex pindex[], int cftype, int vsite_type[]) { int ftype,i,j,parnr,k,l,m,n,nvsite,nOut,kept_i,vsnral,vsitetype; int nconverted,nremoved; atom_id atom,oatom,constr,at1,at2; atom_id vsiteatoms[MAXATOMLIST]; gmx_bool bKeep,bRemove,bUsed,bPresent,bThisFD,bThisOUT,bAllFD,bFirstTwo; t_params *ps; if (cftype == F_CONNBONDS) return; ps = &(plist[cftype]); vsnral=0; kept_i=0; nconverted=0; nremoved=0; nOut=0; for(i=0; (i<ps->nr); i++) { /* for all bonds in the plist */ bKeep=FALSE; bRemove=FALSE; bAllFD=TRUE; /* check if all virtual sites are constructed from the same atoms */ nvsite=0; if(debug) fprintf(debug,"constr %u %u:",ps->param[i].AI+1,ps->param[i].AJ+1); for(k=0; (k<2) && !bKeep && !bRemove; k++) { /* for all atoms in the bond */ atom = ps->param[i].a[k]; if (vsite_type[atom]!=NOTSET) { if(debug) { fprintf(debug," d%d[%d: %d %d %d]",k,atom+1, plist[pindex[atom].ftype].param[pindex[atom].parnr].AJ+1, plist[pindex[atom].ftype].param[pindex[atom].parnr].AK+1, plist[pindex[atom].ftype].param[pindex[atom].parnr].AL+1); } nvsite++; bThisFD = ( (pindex[atom].ftype == F_VSITE3FD ) || (pindex[atom].ftype == F_VSITE3FAD) || (pindex[atom].ftype == F_VSITE4FD ) || (pindex[atom].ftype == F_VSITE4FDN ) ); bThisOUT= ( (pindex[atom].ftype == F_VSITE3OUT) && (interaction_function[cftype].flags & IF_CONSTRAINT) ); bAllFD = bAllFD && bThisFD; if (bThisFD || bThisOUT) { if(debug)fprintf(debug," %s",bThisOUT?"out":"fd"); oatom = ps->param[i].a[1-k]; /* the other atom */ if ( vsite_type[oatom]==NOTSET && oatom==plist[pindex[atom].ftype].param[pindex[atom].parnr].AJ ){ /* if the other atom isn't a vsite, and it is AI */ bRemove=TRUE; if (bThisOUT) nOut++; if(debug)fprintf(debug," D-AI"); } } if (!bRemove) { if (nvsite==1) { /* if this is the first vsite we encounter then store construction atoms */ vsnral=NRAL(pindex[atom].ftype)-1; for(m=0; (m<vsnral); m++) vsiteatoms[m]= plist[pindex[atom].ftype].param[pindex[atom].parnr].a[m+1]; } else { /* if it is not the first then check if this vsite is constructed from the same atoms */ if (vsnral == NRAL(pindex[atom].ftype)-1 ) for(m=0; (m<vsnral) && !bKeep; m++) { bPresent=FALSE; constr= plist[pindex[atom].ftype].param[pindex[atom].parnr].a[m+1]; for(n=0; (n<vsnral) && !bPresent; n++) if (constr == vsiteatoms[n]) bPresent=TRUE; if (!bPresent) { bKeep=TRUE; if(debug)fprintf(debug," !present"); } } else { bKeep=TRUE; if(debug)fprintf(debug," !same#at"); } } } } } if (bRemove) bKeep=FALSE; else { /* if we have no virtual sites in this bond, keep it */ if (nvsite==0) { if (debug)fprintf(debug," no vsite"); bKeep=TRUE; } /* check if all non-vsite atoms are used in construction: */ bFirstTwo=TRUE; for(k=0; (k<2) && !bKeep; k++) { /* for all atoms in the bond */ atom = ps->param[i].a[k]; if (vsite_type[atom]==NOTSET) { bUsed=FALSE; for(m=0; (m<vsnral) && !bUsed; m++) if (atom == vsiteatoms[m]) { bUsed=TRUE; bFirstTwo = bFirstTwo && m<2; } if (!bUsed) { bKeep=TRUE; if(debug)fprintf(debug," !used"); } } } if ( ! ( bAllFD && bFirstTwo ) ) /* check if all constructing atoms are constrained together */ for (m=0; m<vsnral && !bKeep; m++) { /* all constr. atoms */ at1 = vsiteatoms[m]; at2 = vsiteatoms[(m+1) % vsnral]; bPresent=FALSE; for (ftype=0; ftype<F_NRE; ftype++) if ( interaction_function[ftype].flags & IF_CONSTRAINT ) for (j=0; (j<plist[ftype].nr) && !bPresent; j++) /* all constraints until one matches */ bPresent = ( ( (plist[ftype].param[j].AI == at1) && (plist[ftype].param[j].AJ == at2) ) || ( (plist[ftype].param[j].AI == at2) && (plist[ftype].param[j].AJ == at1) ) ); if (!bPresent) { bKeep=TRUE; if(debug)fprintf(debug," !bonded"); } } } if ( bKeep ) { if(debug)fprintf(debug," keeping"); /* now copy the bond to the new array */ memcpy(&(ps->param[kept_i]), &(ps->param[i]),(size_t)sizeof(ps->param[0])); kept_i++; } else if (IS_CHEMBOND(cftype)) { srenew(plist[F_CONNBONDS].param,plist[F_CONNBONDS].nr+1); memcpy(&(plist[F_CONNBONDS].param[plist[F_CONNBONDS].nr]), &(ps->param[i]),(size_t)sizeof(plist[F_CONNBONDS].param[0])); plist[F_CONNBONDS].nr++; nconverted++; } else nremoved++; if(debug)fprintf(debug,"\n"); } if (nremoved) fprintf(stderr,"Removed %4d %15ss with virtual sites, %5d left\n", nremoved, interaction_function[cftype].longname, kept_i); if (nconverted) fprintf(stderr,"Converted %4d %15ss with virtual sites to connections, %5d left\n", nconverted, interaction_function[cftype].longname, kept_i); if (nOut) fprintf(stderr,"Warning: removed %d %ss with vsite with %s construction\n" " This vsite construction does not guarantee constant " "bond-length\n" " If the constructions were generated by pdb2gmx ignore " "this warning\n", nOut, interaction_function[cftype].longname, interaction_function[F_VSITE3OUT].longname ); ps->nr=kept_i; }