// Action_DihedralScan::DoAction() Action::RetType Action_DihedralScan::DoAction(int frameNum, ActionFrame& frm) { switch (mode_) { case RANDOM: RandomizeAngles(frm.ModifyFrm()); break; case INTERVAL: IntervalAngles(frm.ModifyFrm()); break; } // Check the resulting structure int n_problems = checkStructure_.CheckOverlap( frameNum+1, frm.Frm(), *CurrentParm_ ); //mprintf("%i\tResulting structure has %i problems.\n",frameNum,n_problems); number_of_problems_->Add(frameNum, &n_problems); return Action::OK; }
// Action_Rmsd::DoAction() Action::RetType Action_Rmsd::DoAction(int frameNum, ActionFrame& frm) { // Perform any needed reference actions REF_.ActionRef( frm.Frm(), fit_, useMass_ ); // Calculate RMSD double rmsdval; Action::RetType err; // Set selected frame atoms. Masses have already been set. tgtFrame_.SetCoordinates(frm.Frm(), tgtMask_); if (!fit_) { rmsdval = tgtFrame_.RMSD_NoFit(REF_.SelectedRef(), useMass_); err = Action::OK; } else { rmsdval = tgtFrame_.RMSD_CenteredRef(REF_.SelectedRef(), rot_, tgtTrans_, useMass_); if (rmatrices_ != 0) rmatrices_->Add(frameNum, rot_.Dptr()); if (rotate_) frm.ModifyFrm().Trans_Rot_Trans(tgtTrans_, rot_, REF_.RefTrans()); else { tgtTrans_ += REF_.RefTrans(); frm.ModifyFrm().Translate(tgtTrans_); } err = Action::MODIFY_COORDS; } rmsd_->Add(frameNum, &rmsdval); // ---=== Per Residue RMSD ===--- // Set reference and selected frame for each residue using the previously // set-up masks in refResMask and tgtResMask. Use SetFrame instead // of SetCoordinates since each residue can be a different size. if (perres_) { for (perResArray::const_iterator PerRes = ResidueRMS_.begin(); PerRes != ResidueRMS_.end(); ++PerRes) { if ( PerRes->isActive_ ) { ResRefFrame_.SetFrame(REF_.RefFrame(), PerRes->refResMask_); ResTgtFrame_.SetFrame(frm.Frm(), PerRes->tgtResMask_); if (perrescenter_) { ResTgtFrame_.CenterOnOrigin( useMass_ ); ResRefFrame_.CenterOnOrigin( useMass_ ); } double R = ResTgtFrame_.RMSD_NoFit(ResRefFrame_, useMass_); PerRes->data_->Add(frameNum, &R); } } } if (REF_.Previous()) REF_.SetRefStructure( frm.Frm(), fit_, useMass_ ); return err; }
// Action_Principal::DoAction() Action::RetType Action_Principal::DoAction(int frameNum, ActionFrame& frm) { Matrix_3x3 Inertia; Vec3 Eval; frm.Frm().CalculateInertia( mask_, Inertia ); // NOTE: Diagonalize_Sort_Chirality places sorted eigenvectors in rows. Inertia.Diagonalize_Sort_Chirality( Eval, debug_ ); if (outfile_ != 0) { int fn = frameNum+1; outfile_->Printf("%i EIGENVALUES: %f %f %f\n%i EIGENVECTOR 0: %f %f %f\n%i EIGENVECTOR 1: %f %f %f\n%i EIGENVECTOR 2: %f %f %f\n", fn, Eval[0], Eval[1], Eval[2], fn, Inertia[0], Inertia[1], Inertia[2], fn, Inertia[3], Inertia[4], Inertia[5], fn, Inertia[6], Inertia[7], Inertia[8]); //Eval.Print("PRINCIPAL EIGENVALUES"); //Inertia.Print("PRINCIPAL EIGENVECTORS (Rows)"); } if (vecData_ != 0) { vecData_->AddMat3x3( Inertia ); valData_->AddVxyz( Eval ); } // Rotate - since Evec is already transposed (eigenvectors // are returned in rows) just do plain rotation to affect an // inverse rotation. if (doRotation_) { frm.ModifyFrm().Rotate( Inertia ); return Action::MODIFY_COORDS; } return Action::OK; }
// Action_Unwrap::DoAction() Action::RetType Action_Unwrap::DoAction(int frameNum, ActionFrame& frm) { Matrix_3x3 ucell, recip; // Set reference structure if not already set if (RefFrame_.empty()) { RefFrame_ = frm.Frm(); return Action::OK; } if (orthogonal_) Image::UnwrapOrtho( frm.ModifyFrm(), RefFrame_, imageList_, center_, true ); else { frm.Frm().BoxCrd().ToRecip( ucell, recip ); Image::UnwrapNonortho( frm.ModifyFrm(), RefFrame_, imageList_, ucell, recip, center_, true ); } return Action::MODIFY_COORDS; }
/** Center coordinates in frame according to specified mode. */ Action::RetType Action_Center::DoAction(int frameNum, ActionFrame& frm) { Vec3 center; if (useMass_) center = frm.Frm().VCenterOfMass(Mask_); else center = frm.Frm().VGeometricCenter(Mask_); //mprinterr(" FRAME CENTER: %lf %lf %lf\n",center[0],center[1],center[2]); //DEBUG switch (centerMode_) { case ORIGIN: // Shift to coordinate origin (0,0,0) center.Neg(); break; case BOXCTR: // Shift to box center center = frm.Frm().BoxCrd().Center() - center; break; case POINT: // Shift to specified point case REF: // Shift to reference point center = refCenter_ - center; break; } frm.ModifyFrm().Translate(center); return Action::MODIFY_COORDS; }
// Action_Esander::DoAction() Action::RetType Action_Esander::DoAction(int frameNum, ActionFrame& frm) { if (refFrame_.empty()) { refFrame_ = frm.Frm(); if ( InitForRef() ) return Action::ERR; } if (save_forces_) { newFrame_.SetCoordAndBox( frm.Frm() ); SANDER_.CalcEnergyForces( newFrame_ ); frm.SetFrame( &newFrame_ ); } else // FIXME: Passing in ModifyFrm() to give CalcEnergy access to non-const pointers SANDER_.CalcEnergy( frm.ModifyFrm() ); for (int ie = 0; ie != (int)Energy_Sander::N_ENERGYTYPES; ie++) { if (Esets_[ie] != 0) Esets_[ie]->Add(frameNum, SANDER_.Eptr((Energy_Sander::Etype)ie)); } return ret_; }
/** Modify the current frame based on the atom map. */ Action::RetType Action_AtomMap::DoAction(int frameNum, ActionFrame& frm) { if (maponly_) return Action::OK; // Perform RMS fit on mapped atoms only if (rmsfit_) { // Set target frame up according to atom map. rmsTgtFrame_.ModifyByMap(frm.Frm(), AMap_); Matrix_3x3 Rot; Vec3 Trans, refTrans; double R = rmsTgtFrame_.RMSD(rmsRefFrame_, Rot, Trans, refTrans, false); frm.ModifyFrm().Trans_Rot_Trans(Trans, Rot, refTrans); if (rmsdata_!=0) rmsdata_->Add(frameNum, &R); return Action::OK; } // Modify the current frame // TODO: Fix this since its probably busted for unmapped atoms newFrame_->SetCoordinatesByMap(frm.Frm(), AMap_); frm.SetFrame( newFrame_ ); return Action::MODIFY_COORDS; }
// Action_SymmetricRmsd::DoAction() Action::RetType Action_SymmetricRmsd::DoAction(int frameNum, ActionFrame& frm) { // Perform any needed reference actions REF_.ActionRef( frm.Frm(), SRMSD_.Fit(), SRMSD_.UseMass() ); // Calculate symmetric RMSD selectedTgt_.SetCoordinates( frm.Frm(), tgtMask_ ); double rmsdval = SRMSD_.SymmRMSD_CenteredRef( selectedTgt_, REF_.SelectedRef() ); rmsd_->Add(frameNum, &rmsdval); if (remap_) { // Now re-map the target frame for (int atom = 0; atom < (int)targetMap_.size(); atom++) targetMap_[atom] = atom; SymmetricRmsdCalc::Iarray const& AMap = SRMSD_.AMap(); for (unsigned int ref = 0; ref < AMap.size(); ++ref) targetMap_[ tgtMask_[ref] ] = tgtMask_[AMap[ref]]; remapFrame_.SetCoordinatesByMap( frm.Frm(), targetMap_ ); frm.SetFrame( &remapFrame_ ); } if ( SRMSD_.Fit() ) frm.ModifyFrm().Trans_Rot_Trans( SRMSD_.TgtTrans(), SRMSD_.RotMatrix(), REF_.RefTrans() ); return action_return_; }
// Action_RandomizeIons::DoAction() Action::RetType Action_RandomizeIons::DoAction(int frameNum, ActionFrame& frm) { Matrix_3x3 ucell, recip; if (image_.ImageType() == NONORTHO) frm.Frm().BoxCrd().ToRecip(ucell, recip); // Loop over all solvent molecules and mark those that are too close to the solute int n_active_solvent = 0; for (int idx = 0; idx != n_solvent_; idx++) { solvent_[idx] = true; if (around_.MaskStringSet()) { const double* solventXYZ = frm.Frm().XYZ( solventStart_[idx] ); // Is solvent molecule too close to any atom in the around mask? for (AtomMask::const_iterator atom = around_.begin(); atom != around_.end(); ++atom) { double dist = DIST2( solventXYZ, frm.Frm().XYZ(*atom), image_.ImageType(), frm.Frm().BoxCrd(), ucell, recip); if (dist < min_) { solvent_[idx] = false; //mprintf("RANDOMIZEIONS: water %i only %.2f ang from around @%i\n", // smolnum, sqrt(dist), *atom+1); break; } } } if (solvent_[idx]) ++n_active_solvent; } if (n_active_solvent < ions_.Nselected()) { mprinterr("Error: Fewer active solvent molecules (%i) than ions (%i)\n", n_active_solvent, ions_.Nselected()); return Action::ERR; } // DEBUG - print solvent molecule mask if (debug_ > 2) { mprintf("RANDOMIZEIONS: The following waters are ACTIVE so far:\n"); int smoltot = 0; for (int idx = 0; idx != n_solvent_; idx++) { if (solvent_[idx]) { mprintf(" %5i ", solventStart_[idx]+1 ); ++smoltot; if (smoltot%10 == 0) mprintf("\n"); } } mprintf("RANDOMIZEIONS: A total of %i waters (out of %zu) are active\n", smoltot, solvent_.size()); } // Outer loop over all ions for (AtomMask::const_iterator ion1 = ions_.begin(); ion1 != ions_.end(); ++ion1) { //mprintf("RANDOMIZEIONS: Processing ion atom %i\n", *ion1+1); // Is a potential solvent molecule close to any of the ions (except this one)? for (int idx = 0; idx != n_solvent_; idx++) { if (solvent_[idx]) { const double* solventXYZ = frm.Frm().XYZ( solventStart_[idx] ); // This solvent is active; check distance to all other ions for (AtomMask::const_iterator ion2 = ions_.begin(); ion2 != ions_.end(); ++ion2) { if (*ion1 != *ion2) { double dist = DIST2( solventXYZ, frm.Frm().XYZ(*ion2), image_.ImageType(), frm.Frm().BoxCrd(), ucell, recip); if (dist < overlap_) { // This solvent mol is too close to another ion. solvent_[idx] = false; //mprintf("RANDOMIZEIONS: water %i only %.2f ang from ion @%i\n", // smolnum, sqrt(dist), *ion2+1); break; } } } // END inner loop over ions } } // END loop over solvent molecules // The solvent_ array should now be true for all solvent molecules eligible // to swap with ion. int loop = 1; int swapMol = 0; while (loop > 0 && loop < 10000) { // Run the random number generator so that the same number is not produced // when the seed was set manually. swapMol = (int)(RN_.rn_gen() * (double)n_solvent_); if ( solvent_[swapMol] ) loop = -1; else ++loop; } // If a suitable solvent molecule was found, swap it. if (loop > 0) { mprintf("Warning: Tried to swap ion @%i with %i random waters\n",*ion1+1,loop); mprintf("Warning: and couldn't meet criteria; skipping.\n"); } else { if (debug_ > 2) mprintf("RANDOMIZEIONS: Swapping solvent mol %i for ion @%i\n", swapMol+1, *ion1+1); const double* ionXYZ = frm.Frm().XYZ( *ion1 ); int sbegin = solventStart_[ swapMol ]; const double* watXYZ = frm.Frm().XYZ( sbegin ); Vec3 trans( ionXYZ[0] - watXYZ[0], ionXYZ[1] - watXYZ[1], ionXYZ[2] - watXYZ[2]); frm.ModifyFrm().Translate( trans, sbegin, solventEnd_[ swapMol ] ); trans.Neg(); frm.ModifyFrm().Translate( trans, *ion1 ); } } // END outer loop over all ions return Action::MODIFY_COORDS; }
// Action_AutoImage::DoAction() Action::RetType Action_AutoImage::DoAction(int frameNum, ActionFrame& frm) { Matrix_3x3 ucell, recip; Vec3 fcom; Vec3 bp, bm, offset(0.0); Vec3 Trans, framecenter, imagedcenter, anchorcenter; if (!ortho_) frm.Frm().BoxCrd().ToRecip(ucell, recip); // Center w.r.t. anchor if (useMass_) fcom = frm.Frm().VCenterOfMass( anchorMask_ ); else fcom = frm.Frm().VGeometricCenter( anchorMask_ ); if (origin_) { fcom.Neg(); // Shift to coordinate origin (0,0,0) anchorcenter.Zero(); } else { if (ortho_ || truncoct_) // Center is box xyz over 2 anchorcenter = frm.Frm().BoxCrd().Center(); else // Center in frac coords is (0.5,0.5,0.5) anchorcenter = ucell.TransposeMult(Vec3(0.5)); fcom = anchorcenter - fcom; } frm.ModifyFrm().Translate(fcom); // Setup imaging, and image everything in currentFrame // according to mobileList. if (ortho_) { if (Image::SetupOrtho(frm.Frm().BoxCrd(), bp, bm, origin_)) { mprintf("Warning: Frame %i imaging failed, box lengths are zero.\n",frameNum+1); // TODO: Return OK for now so next frame is tried; eventually indicate SKIP? return Action::OK; // FIXME return MODIFY_COORDS instead? } Image::Ortho(frm.ModifyFrm(), bp, bm, offset, usecom_, useMass_, mobileList_); } else { if (truncoct_) fcom = Image::SetupTruncoct( frm.Frm(), 0, useMass_, origin_ ); Image::Nonortho(frm.ModifyFrm(), origin_, fcom, offset, ucell, recip, truncoct_, usecom_, useMass_, mobileList_); } // For each molecule defined by atom pairs in fixedList, determine if the // imaged position is closer to anchor center than the current position. // Always use molecule center when imaging fixedList. for (pairList::const_iterator atom1 = fixedList_.begin(); atom1 != fixedList_.end(); ++atom1) { int firstAtom = *atom1; ++atom1; int lastAtom = *atom1; if (useMass_) framecenter = frm.Frm().VCenterOfMass(firstAtom, lastAtom); else framecenter = frm.Frm().VGeometricCenter(firstAtom, lastAtom); // NOTE: imaging routines will modify input coords. //imagedcenter[0] = framecenter[0]; //imagedcenter[1] = framecenter[1]; //imagedcenter[2] = framecenter[2]; if (ortho_) Trans = Image::Ortho(framecenter, bp, bm, frm.Frm().BoxCrd()); else Trans = Image::Nonortho(framecenter, truncoct_, origin_, ucell, recip, fcom, -1.0); // If molecule was imaged, determine whether imaged position is closer to anchor. if (Trans[0] != 0 || Trans[1] != 0 || Trans[2] != 0) { imagedcenter = framecenter; imagedcenter += Trans; double framedist2 = DIST2_NoImage( anchorcenter, framecenter ); double imageddist2 = DIST2_NoImage( anchorcenter, imagedcenter ); //mprintf("DBG: [%5i] Fixed @%i-%i frame dist2=%lf, imaged dist2=%lf\n", frameNum, // firstAtom+1, lastAtom+1, // framedist2, imageddist2); if (imageddist2 < framedist2) { // Imaging these atoms moved them closer to anchor. Update coords in currentFrame. frm.ModifyFrm().Translate(Trans, firstAtom, lastAtom); //for (int idx = firstAtom*3; idx < lastAtom*3; ++idx) // (*currentFrame)[idx] = fixedFrame[idx]; } } } return Action::MODIFY_COORDS; }