void Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, TrajectoryAnalysisModuleData *pdata) { AnalysisDataHandle dh = pdata->dataHandle(angles_); const SelectionList &sel1 = pdata->parallelSelections(sel1_); const SelectionList &sel2 = pdata->parallelSelections(sel2_); checkSelections(sel1, sel2); dh.startFrame(frnr, fr.time); for (size_t g = 0; g < sel1_.size(); ++g) { rvec v1, v2; rvec c1, c2; switch (g2type_[0]) { case 'z': clear_rvec(v2); v2[ZZ] = 1.0; clear_rvec(c2); break; case 's': copy_rvec(sel2_[g].position(0).x(), c2); break; } for (int i = 0, j = 0, n = 0; i < sel1[g].posCount(); i += natoms1_, j += natoms2_, ++n) { rvec x[4]; real angle; copy_pos(sel1, natoms1_, g, i, x); switch (g1type_[0]) { case 'a': if (pbc) { pbc_dx(pbc, x[0], x[1], v1); pbc_dx(pbc, x[2], x[1], v2); } else { rvec_sub(x[0], x[1], v1); rvec_sub(x[2], x[1], v2); } angle = gmx_angle(v1, v2); break; case 'd': { rvec dx[3]; if (pbc) { pbc_dx(pbc, x[0], x[1], dx[0]); pbc_dx(pbc, x[2], x[1], dx[1]); pbc_dx(pbc, x[2], x[3], dx[2]); } else { rvec_sub(x[0], x[1], dx[0]); rvec_sub(x[2], x[1], dx[1]); rvec_sub(x[2], x[3], dx[2]); } cprod(dx[0], dx[1], v1); cprod(dx[1], dx[2], v2); angle = gmx_angle(v1, v2); real ipr = iprod(dx[0], v2); if (ipr < 0) { angle = -angle; } break; } case 'v': case 'p': calc_vec(natoms1_, x, pbc, v1, c1); switch (g2type_[0]) { case 'v': case 'p': copy_pos(sel2, natoms2_, 0, j, x); calc_vec(natoms2_, x, pbc, v2, c2); break; case 't': // FIXME: This is not parallelizable. if (frnr == 0) { copy_rvec(v1, vt0_[g][n]); } copy_rvec(vt0_[g][n], v2); break; case 'z': c1[XX] = c1[YY] = 0.0; break; case 's': if (pbc) { pbc_dx(pbc, c1, c2, v2); } else { rvec_sub(c1, c2, v2); } break; default: GMX_THROW(InternalError("invalid -g2 value")); } angle = gmx_angle(v1, v2); break; default: GMX_THROW(InternalError("invalid -g1 value")); } /* TODO: Should we also calculate distances like g_sgangle? * Could be better to leave that for a separate tool. real dist = 0.0; if (bDumpDist_) { if (pbc) { rvec dx; pbc_dx(pbc, c2, c1, dx); dist = norm(dx); } else { dist = sqrt(distance2(c1, c2)); } } */ dh.setPoint(n, angle * RAD2DEG); } } dh.finishFrame(); }
void Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, TrajectoryAnalysisModuleData *pdata) { AnalysisDataHandle *dh = pdata->dataHandle("angle"); std::vector<Selection *> sel1 = pdata->parallelSelections(_sel1); std::vector<Selection *> sel2 = pdata->parallelSelections(_sel2); checkSelections(sel1, sel2); rvec v1, v2; rvec c1, c2; switch (_g2type[0]) { case 'z': clear_rvec(v2); v2[ZZ] = 1.0; clear_rvec(c2); break; case 's': copy_rvec(_sel2[0]->x(0), c2); break; } dh->startFrame(frnr, fr.time); int incr1 = _bSplit1 ? 1 : _natoms1; int incr2 = _bSplit2 ? 1 : _natoms2; int ngrps = _bMulti ? _sel1.size() : 1; for (int g = 0; g < ngrps; ++g) { real ave = 0.0; int n = 0; int i, j; for (i = j = 0; i < sel1[g]->posCount(); i += incr1) { rvec x[4]; real angle; copy_pos(sel1, _bSplit1, _natoms1, g, i, x); switch (_g1type[0]) { case 'a': if (pbc) { pbc_dx(pbc, x[0], x[1], v1); pbc_dx(pbc, x[2], x[1], v2); } else { rvec_sub(x[0], x[1], v1); rvec_sub(x[2], x[1], v2); } angle = gmx_angle(v1, v2); break; case 'd': { rvec dx[3]; if (pbc) { pbc_dx(pbc, x[0], x[1], dx[0]); pbc_dx(pbc, x[2], x[1], dx[1]); pbc_dx(pbc, x[2], x[3], dx[2]); } else { rvec_sub(x[0], x[1], dx[0]); rvec_sub(x[2], x[1], dx[1]); rvec_sub(x[2], x[3], dx[2]); } cprod(dx[0], dx[1], v1); cprod(dx[1], dx[2], v2); angle = gmx_angle(v1, v2); real ipr = iprod(dx[0], v2); if (ipr < 0) { angle = -angle; } break; } case 'v': case 'p': calc_vec(_natoms1, x, pbc, v1, c1); switch (_g2type[0]) { case 'v': case 'p': copy_pos(sel2, _bSplit2, _natoms2, 0, j, x); calc_vec(_natoms2, x, pbc, v2, c2); j += incr2; break; case 't': // FIXME: This is not parallelizable. if (frnr == 0) { copy_rvec(v1, _vt0[n]); } copy_rvec(_vt0[n], v2); break; case 'z': c1[XX] = c1[YY] = 0.0; break; case 's': if (pbc) { pbc_dx(pbc, c1, c2, v2); } else { rvec_sub(c1, c2, v2); } break; default: GMX_THROW(InternalError("invalid -g2 value")); } angle = gmx_angle(v1, v2); break; default: GMX_THROW(InternalError("invalid -g1 value")); } angle *= RAD2DEG; real dist = 0.0; if (_bDumpDist) { if (pbc) { rvec dx; pbc_dx(pbc, c2, c1, dx); dist = norm(dx); } else { dist = sqrt(distance2(c1, c2)); } } if (_bAll) { dh->addPoint(n + 1, angle); } ave += angle; ++n; } if (n > 0) { ave /= n; } dh->addPoint(g, ave); } dh->finishFrame(); }