/** Like the strip action, closest will modify the current parm keeping info * for atoms in mask plus the closestWaters solvent molecules. Set up the * vector of MolDist objects, one for every solvent molecule in the original * parm file. Atom masks for each solvent molecule will be set up. */ Action_Closest::RetType Action_Closest::Setup(Topology const& topIn, CoordinateInfo const& cInfoIn) { // If there are no solvent molecules this action is not valid. if (topIn.Nsolvent()==0) { mprintf("Warning: Parm %s does not contain solvent.\n",topIn.c_str()); return Action_Closest::SKIP; } // If # solvent to keep >= solvent in this parm the action is not valid. if (closestWaters_ >= topIn.Nsolvent()) { mprintf("Warning: # solvent to keep (%i) >= # solvent molecules in '%s' (%i)\n", closestWaters_, topIn.c_str(), topIn.Nsolvent()); return Action_Closest::SKIP; } image_.SetupImaging( cInfoIn.TrajBox().Type() ); if (image_.ImagingEnabled()) mprintf("\tDistances will be imaged.\n"); else mprintf("\tImaging off.\n"); // LOOP OVER MOLECULES // 1: Check that all solvent molecules contain same # atoms. Solvent // molecules must be identical for the command to work properly; // the prmtop strip occurs only once so the solvent params become fixed. // 2: Set up a mask for all solvent molecules. SolventMols_.clear(); // NOTE: May not be necessary to init 'solvent' MolDist solvent; solvent.D = 0.0; solvent.mol = 0; SolventMols_.resize(topIn.Nsolvent(), solvent); std::vector<MolDist>::iterator mdist = SolventMols_.begin(); // 3: Set up the soluteMask for all non-solvent molecules. int molnum = 1; int nclosest = 0; int NsolventAtoms = -1; for (Topology::mol_iterator Mol = topIn.MolStart(); Mol != topIn.MolEnd(); ++Mol) { if ( Mol->IsSolvent() ) { // Solvent, check for same # of atoms. if (NsolventAtoms == -1) NsolventAtoms = Mol->NumAtoms(); else if ( NsolventAtoms != Mol->NumAtoms() ) { mprinterr("Error: Solvent molecules in '%s' are not of uniform size.\n" "Error: First solvent mol = %i atoms, solvent mol %i = %i atoms.\n", topIn.c_str(), NsolventAtoms, molnum, (*Mol).NumAtoms()); return Action_Closest::ERR; } // mol here is the output molecule number which is why it starts from 1. mdist->mol = molnum; // Solvent molecule mask mdist->mask.AddAtomRange( Mol->BeginAtom(), Mol->EndAtom() ); // Atoms in the solvent molecule to actually calculate distances to. if (firstAtom_) { mdist->solventAtoms.assign(1, Mol->BeginAtom() ); } else { mdist->solventAtoms.clear(); mdist->solventAtoms.reserve( Mol->NumAtoms() ); for (int svatom = Mol->BeginAtom(); svatom < Mol->EndAtom(); svatom++) mdist->solventAtoms.push_back( svatom ); } if (debug_ > 0) { mprintf("DEBUG:\tSet up mol %i:", mdist->mol); // DEBUG mdist->mask.PrintMaskAtoms("solvent"); // DEBUG mprintf("\n"); // DEBUG } ++mdist; } ++molnum; } // Setup distance atom mask // NOTE: Should ensure that no solvent atoms are selected! if ( topIn.SetupIntegerMask(distanceMask_) ) return Action_Closest::ERR; if (distanceMask_.None()) { mprintf("Warning: Distance mask '%s' contains no atoms.\n", distanceMask_.MaskString()); return Action_Closest::SKIP; } distanceMask_.MaskInfo(); // Check the total number of solvent atoms to be kept. NsolventAtoms *= closestWaters_; mprintf("\tKeeping %i solvent atoms.\n",NsolventAtoms); if (NsolventAtoms < 1) { mprintf("Warning: # of solvent atoms to be kept is < 1.\n"); return Action_Closest::SKIP; } NsolventMolecules_ = (int)SolventMols_.size(); return Action_Closest::OK; }
// Action_RandomizeIons::Setup() Action::RetType Action_RandomizeIons::Setup(ActionSetup& setup) { n_solvent_ = setup.Top().Nsolvent(); if (n_solvent_ < 1) { mprinterr("Error: This command only works if solvent information has been specified.\n"); return Action::ERR; } // Set up ion mask if (setup.Top().SetupIntegerMask( ions_ )) return Action::ERR; if ( ions_.None() ) { mprintf("Warning: Ion mask '%s' has no atoms.\n", ions_.MaskString()); return Action::SKIP; } mprintf("\tIon mask is '%s' (%i atoms)\n", ions_.MaskString(), ions_.Nselected()); // Set up the around mask if necessary if (around_.MaskStringSet()) { if (setup.Top().SetupIntegerMask( around_ )) return Action::ERR; if ( around_.None() ) { mprintf("Warning: Around mask '%s' has no atoms.\n", around_.MaskString()); } else { mprintf("\tAround mask is '%s' (%i atoms)\n", around_.MaskString(), around_.Nselected()); } } // Check that each ion is only a single atom residue. // NOTE: Should this be a molecule check instead? If so can then get rid of ResSize for (AtomMask::const_iterator ion = ions_.begin(); ion != ions_.end(); ++ion) { int res = setup.Top()[*ion].ResNum(); if (debug_ > 0) mprintf("\tAtom %i is in residue %i which is %i atoms\n", *ion+1, res+1, setup.Top().Res( res ).NumAtoms() ); if ( setup.Top().Res( res ).NumAtoms() > 1 ) { mprintf("Warning: randomizeions: Ion atom %i belongs to residue %i which\n", *ion + 1, res + 1); mprintf("Warning: contains more than 1 atom (%i)!\n", setup.Top().Res( res ).NumAtoms()); } } // Check the solvent information to make sure that each solvent listed has the // same number of atoms in each molecule; otherwise a uniform trajectory is not // possible and therefore this command will be ignored. // Also save the start and end atom of each solvent molecule. int NsolventAtoms = -1; solventStart_.clear(); solventEnd_.clear(); solventStart_.reserve( n_solvent_ ); solventEnd_.reserve( n_solvent_ ); for (Topology::mol_iterator Mol = setup.Top().MolStart(); Mol != setup.Top().MolEnd(); ++Mol) { if ( Mol->IsSolvent() ) { if (NsolventAtoms == -1) NsolventAtoms = Mol->NumAtoms(); else if ( NsolventAtoms != Mol->NumAtoms() ) { mprinterr("Error: Solvent molecules in %s are not of uniform size.\n", setup.Top().c_str()); mprinterr("Error: First solvent mol = %i atoms, this solvent mol = %i atoms.\n", NsolventAtoms, Mol->NumAtoms()); return Action::ERR; } solventStart_.push_back( Mol->BeginAtom() ); solventEnd_.push_back( Mol->EndAtom() ); } } image_.SetupImaging( setup.CoordInfo().TrajBox().Type() ); // Allocate solvent molecule mask solvent_.resize( n_solvent_ ); return Action::OK; }