// ----------------------------------------------------------------------------- // COPY STATE BACK TO CPU FROM OPENMM // ----------------------------------------------------------------------------- static void myGetOpenMMState(MyOpenMMData* omm, bool wantEnergy, double& timeInPs, double& energyInKcal, MyAtomInfo atoms[]) { int infoMask = 0; infoMask = OpenMM::State::Positions; if (wantEnergy) { infoMask += OpenMM::State::Velocities; // for kinetic energy (cheap) infoMask += OpenMM::State::Energy; // for pot. energy (expensive) } // Forces are also available (and cheap). const OpenMM::State state = omm->context->getState(infoMask); timeInPs = state.getTime(); // OpenMM time is in ps already // Copy OpenMM positions into atoms array and change units from nm to Angstroms. const std::vector<Vec3>& positionsInNm = state.getPositions(); for (int i=0; i < (int)positionsInNm.size(); ++i) for (int j=0; j < 3; ++j) atoms[i].posInAng[j] = positionsInNm[i][j] * OpenMM::AngstromsPerNm; // If energy has been requested, obtain it and convert from kJ to kcal. energyInKcal = 0; if (wantEnergy) energyInKcal = (state.getPotentialEnergy() + state.getKineticEnergy()) * OpenMM::KcalPerKJ; }
// ----------------------------------------------------------------------------- // COPY STATE BACK TO CPU FROM OPENMM // ----------------------------------------------------------------------------- static void myGetOpenMMState(MyOpenMMData* omm, double& timeInPs, std::vector<double>& atomPositionsInAng) { const OpenMM::State state = omm->context->getState(OpenMM::State::Positions, true); timeInPs = state.getTime(); // OpenMM time is in ps already // Copy OpenMM positions into output array and change units from nm to Angstroms. const std::vector<Vec3>& positionsInNm = state.getPositions(); atomPositionsInAng.resize(3*positionsInNm.size()); for (int i=0; i < (int)positionsInNm.size(); ++i) for (int j=0; j < 3; ++j) atomPositionsInAng[3*i+j] = positionsInNm[i][j] * OpenMM::AngstromsPerNm; }
double getQscore(const OpenMM::State& state, json &molinfo) { const std::vector<OpenMM::Vec3>& posInNm = state.getPositions(); int contact = 0; for (int i=0; i<molinfo["contact"].size(); ++i) { int p1 = rs2pi[molinfo["contact"][i]["resSeq"][0]]; int p2 = rs2pi[molinfo["contact"][i]["resSeq"][1]]; double r_native = molinfo["contact"][i]["length"]; double r, r2; r2 = pow(posInNm[p1][0]-posInNm[p2][0], 2); r2 += pow(posInNm[p1][1]-posInNm[p2][1], 2); r2 += pow(posInNm[p1][2]-posInNm[p2][2], 2); r = sqrt(r2) / OpenMM::NmPerAngstrom; if (r < r_native * QscoreThreshold ) contact++; } return ((double)contact) / molinfo["contact"].size(); }
void writePDBFrame(int frameNum, const OpenMM::State& state, json &molinfo, std::ofstream &opdb) { // Reference atomic positions in the OpenMM State. const std::vector<OpenMM::Vec3>& posInNm = state.getPositions(); opdb << "MODEL " << frameNum << "\n"; for (int a = 0; a < (int)posInNm.size(); ++a) { opdb << "ATOM " << std::setw(5) << a+1 << " C C A"; opdb << std::setw(4) << (int)molinfo["resSeq"][a]; opdb << " "; // atom number opdb << std::fixed << std::setw(8) << std::setprecision(3) << posInNm[a][0]*10; opdb << std::fixed << std::setw(8) << std::setprecision(3) << posInNm[a][1]*10; opdb << std::fixed << std::setw(8) << std::setprecision(3) << posInNm[a][2]*10; opdb << " 1.00 0.00\n"; } opdb << "ENDMDL\n"; // end of frame }
void OpenMMIntegrator::run( int numTimesteps ) { preStepModify(); bool execute = true; /*#ifdef HAVE_OPENMM_LTMD if( mLTMDParameters.ShouldProtoMolDiagonalize && mLTMDParameters.ShouldForceRediagOnMinFail ){ if( app->eigenInfo.OpenMMMinimize ){ OpenMM::LTMD::Integrator *ltmd = dynamic_cast<OpenMM::LTMD::Integrator*>( integrator ); bool minimizePassed = ltmd->minimize( 50, 2 ); if( minimizePassed || app->eigenInfo.RediagonalizationCount >= 5 ){ if( app->eigenInfo.RediagonalizationCount >= 5 ){ std::cout << "Maximum Rediagonalizations Reached" << std::endl; } execute = true; app->eigenInfo.OpenMMMinimize = false; app->eigenInfo.RediagonalizationCount = 0; std::cout << "Exiting Rediagonalizations" << std::endl; }else{ execute = false; app->eigenInfo.reDiagonalize = true; app->eigenInfo.RediagonalizationCount++; } } } #endif */ integrator->step( numTimesteps ); // Retrive data const OpenMM::State state = context->getState( OpenMM::State::Positions | OpenMM::State::Velocities | OpenMM::State::Forces | OpenMM::State::Energy ); const std::vector<OpenMM::Vec3> positions( state.getPositions() ); const std::vector<OpenMM::Vec3> velocities( state.getVelocities() ); const std::vector<OpenMM::Vec3> forces( state.getForces() ); const unsigned int sz = app->positions.size(); for( unsigned int i = 0; i < sz; ++i ) { for( int j = 0; j < 3; j++ ) { app->positions[i].c[j] = positions[i][j] * Constant::NM_ANGSTROM; //nm to A app->velocities[i].c[j] = velocities[i][j] * Constant::NM_ANGSTROM * Constant::TIMEFACTOR * Constant::FS_PS; //nm/ps to A/fs? ( *myForces )[i].c[j] = forces[i][j] * Constant::INV_NM_ANGSTROM * Constant::KJ_KCAL; //KJ/nm to Kcal/A } } app->energies.clear(); //clear old energies app->energies[ScalarStructure::COULOMB] = app->energies[ScalarStructure::LENNARDJONES] = app->energies[ScalarStructure::BOND] = app->energies[ScalarStructure::ANGLE] = app->energies[ScalarStructure::DIHEDRAL] = app->energies[ScalarStructure::IMPROPER] = 0.0; //save total potential energy app->energies[ScalarStructure::OTHER] = state.getPotentialEnergy() * Constant::KJ_KCAL; //fix time as no forces calculated app->topology->time += numTimesteps * getTimestep(); postStepModify(); }