// Action_Unwrap::Setup() Action::RetType Action_Unwrap::Setup(ActionSetup& setup) { // Ensure same number of atoms in current parm and ref parm if ( RefParm_!=0 ) { if ( setup.Top().Natom() != RefParm_->Natom() ) { mprinterr("Error: unwrap: # atoms in reference parm %s is not\n", RefParm_->c_str()); mprinterr("Error: equal to # atoms in parm %s\n", setup.Top().c_str()); return Action::ERR; } } // Check box type if (setup.CoordInfo().TrajBox().Type()==Box::NOBOX) { mprintf("Error: unwrap: Parm %s does not contain box information.\n", setup.Top().c_str()); return Action::ERR; } orthogonal_ = false; if (setup.CoordInfo().TrajBox().Type()==Box::ORTHO) orthogonal_ = true; // Setup atom pairs to be unwrapped. imageList_ = Image::CreatePairList(setup.Top(), imageMode_, maskExpression_); if (imageList_.empty()) { mprintf("Warning: Mask selects no atoms for topology '%s'.\n", setup.Top().c_str()); return Action::SKIP; } mprintf("\tNumber of %ss to be unwrapped is %zu\n", Image::ModeString(imageMode_), imageList_.size()/2); // Use current parm as reference if not already set if (RefParm_ == 0) RefParm_ = setup.TopAddress(); return Action::OK; }
/** Determine what atoms each mask pertains to for the current parm file. */ Action::RetType Action_LIE::Setup(ActionSetup& setup) { if (setup.Top().SetupIntegerMask( Mask1_ )) return Action::ERR; if (setup.Top().SetupIntegerMask( Mask2_ )) return Action::ERR; mprintf("\tLIE: %i Ligand Atoms, %i Surrounding Atoms\n", Mask1_.Nselected(), Mask2_.Nselected()); if (setup.CoordInfo().TrajBox().Type() == Box::NOBOX) { mprinterr("Error: LIE: Must have explicit solvent system with box info\n"); return Action::ERR; } if (Mask1_.None() || Mask2_.None()) { mprintf("Warning: LIE: One or both masks have no atoms.\n"); return Action::SKIP; } if (SetupParms(setup.Top())) return Action::ERR; // Back up the parm CurrentParm_ = setup.TopAddress(); return Action::OK; }
/** Set angle up for this parmtop. Get masks etc. */ Action::RetType Action_Esander::Setup(ActionSetup& setup) { if (currentParm_ != 0 && currentParm_->Pindex() != setup.Top().Pindex()) { mprintf("Warning: Current topology is %i:%s but reference is %i:%s. Skipping.\n", setup.Top().Pindex(), setup.Top().c_str(), currentParm_->Pindex(), currentParm_->c_str()); return Action::SKIP; } // Check for LJ terms if (!setup.Top().Nonbond().HasNonbond()) { mprinterr("Error: Topology '%s' does not have non-bonded parameters.\n", setup.Top().c_str()); return Action::ERR; } // If reference specified, init now. Otherwise using first frame. if (currentParm_ != 0 ) { if ( InitForRef() ) return Action::ERR; } else currentParm_ = setup.TopAddress(); // If saving of forces is requested, make sure CoordinateInfo has force. if (save_forces_) { cInfo_ = setup.CoordInfo(); cInfo_.SetForce( true ); newFrame_.SetupFrameV( setup.Top().Atoms(), cInfo_ ); setup.SetCoordInfo( &cInfo_ ); ret_ = Action::MODIFY_COORDS; return Action::MODIFY_TOPOLOGY; } ret_ = Action::OK; return Action::OK; }
/** Set up solute and solvent masks. If no solvent mask was specified use * solvent information in the current topology. */ Action::RetType Action_Watershell::Setup(ActionSetup& setup) { // Set up solute mask if (setup.Top().SetupIntegerMask( soluteMask_ )) return Action::ERR; if ( soluteMask_.None() ) { mprintf("Warning: No atoms in solute mask [%s].\n",soluteMask_.MaskString()); return Action::SKIP; } // Set up solvent mask if (!solventmaskexpr_.empty()) { if (setup.Top().SetupIntegerMask( solventMask_ )) return Action::ERR; } else { solventMask_.ResetMask(); for (Topology::mol_iterator mol = setup.Top().MolStart(); mol != setup.Top().MolEnd(); ++mol) { if ( mol->IsSolvent() ) solventMask_.AddAtomRange( mol->BeginAtom(), mol->EndAtom() ); } } if ( solventMask_.None() ) { if (!solventmaskexpr_.empty()) mprintf("Warning: No solvent atoms selected by mask [%s]\n", solventmaskexpr_.c_str()); else mprintf("Warning: No solvent atoms in topology %s\n",setup.Top().c_str()); return Action::SKIP; } SetupImaging( setup.CoordInfo().TrajBox().Type() ); // Create space for residues # ifdef _OPENMP // Only re-allocate for larger # of residues if ( setup.Top().Nres() > NactiveResidues_ ) { if (activeResidues_thread_ != 0) { // Deallocate each thread for (int i = 0; i < NactiveResidues_; ++i) delete[] activeResidues_thread_[i]; } else { // Initial thread allocation needed activeResidues_thread_ = new int*[ numthreads_ ]; } // Allocate each thread for (int i = 0; i < numthreads_; ++i) { activeResidues_thread_[i] = new int[ setup.Top().Nres() ]; std::fill( activeResidues_thread_[i], activeResidues_thread_[i] + setup.Top().Nres(), 0 ); } } NactiveResidues_ = setup.Top().Nres(); # else activeResidues_.resize( setup.Top().Nres(), 0 ); # endif // Store current Parm CurrentParm_ = setup.TopAddress(); return Action::OK; }
// Action_Outtraj::Setup() Action::RetType Action_Outtraj::Setup(ActionSetup& setup) { if (associatedParm_->Pindex() != setup.Top().Pindex()) return Action::SKIP; if (!isSetup_) { // TODO: Trajout IsOpen? if (outtraj_.SetupTrajWrite(setup.TopAddress(), setup.CoordInfo(), setup.Nframes())) return Action::ERR; outtraj_.PrintInfo(0); isSetup_ = true; } return Action::OK; }
// Action_CheckStructure::Setup() Action::RetType Action_CheckStructure::Setup(ActionSetup& setup) { CurrentParm_ = setup.TopAddress(); if (SeparateSetup( setup.Top(), setup.CoordInfo().TrajBox().Type(),bondcheck_ )) return Action::ERR; // Print imaging info for this parm if (bondcheck_) mprintf("\tChecking %u bonds.\n", bondList_.size()); if (image_.ImagingEnabled()) mprintf("\tImaging on.\n"); else mprintf("\timaging off.\n"); return Action::OK; }
// Action_Outtraj::Setup() Action::RetType Action_Outtraj::Setup(ActionSetup& setup) { if (!isActive_ || associatedParm_->Pindex() != setup.Top().Pindex()) { mprintf("\tOutput trajectory not active for topology '%s'\n", setup.Top().c_str()); return Action::SKIP; } if (!isSetup_) { // TODO: Trajout IsOpen? if (outtraj_.SetupTrajWrite(setup.TopAddress(), setup.CoordInfo(), setup.Nframes())) return Action::ERR; mprintf(" "); //TODO this is a kludge; PrintInfo should be a string. outtraj_.PrintInfo(0); mprintf("\tHas %s\n", outtraj_.Traj().CoordInfo().InfoString().c_str()); isSetup_ = true; } return Action::OK; }
// Action_NativeContacts::Setup() Action::RetType Action_NativeContacts::Setup(ActionSetup& setup) { // Setup potential contact lists for this topology if (SetupContactLists( setup.Top(), Frame())) return Action::SKIP; mprintf("\t%zu potential contact sites for '%s'\n", Mask1_.Nselected(), Mask1_.MaskString()); if (Mask2_.MaskStringSet()) mprintf("\t%zu potential contact sites for '%s'\n", Mask2_.Nselected(), Mask2_.MaskString()); // Set up imaging info for this parm image_.SetupImaging( setup.CoordInfo().TrajBox().Type() ); if (image_.ImagingEnabled()) mprintf("\tImaging enabled.\n"); else mprintf("\tImaging disabled.\n"); CurrentParm_ = setup.TopAddress(); return Action::OK; }
/** Set up mask, allocate memory for exclusion list. */ Action::RetType Action_Pairwise::Setup(ActionSetup& setup) { // Set up mask if ( setup.Top().SetupIntegerMask( Mask0_ ) ) return Action::ERR; if (Mask0_.None()) { mprintf("Warning: Mask has no atoms.\n"); return Action::SKIP; } // Set up exclusion list and determine total # interactions. int N_interactions = SetupNonbondParm(Mask0_, setup.Top()); if (N_interactions == -1) return Action::ERR; // Allocate matrix memory int previous_size = (int)vdwMat_->Size(); if (previous_size == 0) { vdwMat_->AllocateTriangle( setup.Top().Natom() ); eleMat_->AllocateTriangle( setup.Top().Natom() ); } else { if (previous_size != N_interactions) { mprinterr("Error: Attempting to reallocate matrix with different size.\n" "Error: Original size= %i, new size= %i\n" "Error: This can occur when different #s of atoms are selected in\n" "Error: different topology files.\n", previous_size, N_interactions); return Action::ERR; } } // If comparing to a reference frame for atom-by-atom comparison make sure // the number of interactions is the same in reference and parm. if (nb_calcType_==COMPARE_REF) { if (N_interactions != N_ref_interactions_) { mprinterr("Error: # reference interactions (%i) != # interactions for this parm (%i)\n", N_ref_interactions_, N_interactions); return Action::ERR; } } // Set up cumulative energy arrays atom_eelec_.clear(); atom_eelec_.resize(setup.Top().Natom(), 0.0); atom_evdw_.clear(); atom_evdw_.resize(setup.Top().Natom(), 0.0); // Print pairwise info for this parm Mask0_.MaskInfo(); CurrentParm_ = setup.TopAddress(); return Action::OK; }
/** Set angle up for this parmtop. Get masks etc. */ Action::RetType Action_Energy::Setup(ActionSetup& setup) { if (setup.Top().SetupCharMask(Mask1_)) return Action::ERR; if (Mask1_.None()) { mprintf("Warning: Mask '%s' selects no atoms.\n", Mask1_.MaskString()); return Action::SKIP; } Mask1_.MaskInfo(); Imask_ = AtomMask(Mask1_.ConvertToIntMask(), Mask1_.Natom()); // Check for LJ terms for (calc_it calc = Ecalcs_.begin(); calc != Ecalcs_.end(); ++calc) if ((*calc == N14 || *calc == NBD) && !setup.Top().Nonbond().HasNonbond()) { mprinterr("Error: Nonbonded energy calc requested but topology '%s'\n" "Error: does not have non-bonded parameters.\n", setup.Top().c_str()); return Action::ERR; } currentParm_ = setup.TopAddress(); return Action::OK; }
// Action_Vector::Setup() Action::RetType Action_Vector::Setup(ActionSetup& setup) { if (needBoxInfo_) { // Check for box info if (setup.CoordInfo().TrajBox().Type() == Box::NOBOX) { mprinterr("Error: vector box: No box information.\n", setup.Top().c_str()); return Action::ERR; } } if (mask_.MaskStringSet()) { // Setup mask 1 if (setup.Top().SetupIntegerMask(mask_)) return Action::ERR; mask_.MaskInfo(); if (mask_.None()) { mprinterr("Error: First vector mask is empty.\n"); return Action::ERR; } } // Allocate space for CORRPLANE. if (mode_ == CORRPLANE) { if (vcorr_!=0) delete[] vcorr_; vcorr_ = new double[ 3 * mask_.Nselected() ]; } // Setup mask 2 if (mask2_.MaskStringSet()) { if (setup.Top().SetupIntegerMask(mask2_)) return Action::ERR; mask2_.MaskInfo(); if (mask2_.None()) { mprinterr("Error: Second vector mask is empty.\n"); return Action::ERR; } } CurrentParm_ = setup.TopAddress(); return Action::OK; }
/** Called every time the trajectory changes. Set up FrameMask for the new * parmtop and allocate space for selected atoms from the Frame. */ Action::RetType Action_Rmsd::Setup(ActionSetup& setup) { // Target setup if ( setup.Top().SetupIntegerMask( tgtMask_ ) ) return Action::ERR; mprintf("\tTarget mask:"); tgtMask_.BriefMaskInfo(); mprintf("\n"); if ( tgtMask_.None() ) { mprintf("Warning: No atoms in mask '%s'.\n", tgtMask_.MaskString()); return Action::SKIP; } // Allocate space for selected atoms in the frame. This will also put the // correct masses in based on the mask. tgtFrame_.SetupFrameFromMask(tgtMask_, setup.Top().Atoms()); // Reference setup if (REF_.SetupRef(setup.Top(), tgtMask_.Nselected(), "rmsd")) return Action::SKIP; // Per residue rmsd setup if (perres_) { // If RefParm is still NULL probably 'first', set now. if (RefParm_ == 0) RefParm_ = setup.TopAddress(); int err = perResSetup(setup.Top(), *RefParm_); if (err == 1) return Action::SKIP; else if (err == 2) return Action::ERR; } // Warn if PBC and rotating if (rotate_ && setup.CoordInfo().TrajBox().Type() != Box::NOBOX) { mprintf("Warning: Coordinates are being rotated and box coordinates are present.\n" "Warning: Unit cell vectors are NOT rotated; imaging will not be possible\n" "Warning: after the RMS-fit is performed.\n"); } return Action::OK; }
Action::RetType Action_Contacts::Setup(ActionSetup& setup) { //if (first_) // RefParm_ = currentParm; // Set up atom mask if (setup.Top().SetupIntegerMask(Mask_)) return Action::ERR; // Determine which residues are active based on the mask activeResidues_.clear(); for (AtomMask::const_iterator atom = Mask_.begin(); atom != Mask_.end(); ++atom) { int resnum = setup.Top()[*atom].ResNum(); activeResidues_.insert( resnum ); } // byresidue header - only on first time through if (residueContacts_.empty() && byResidue_) { outfile_->Printf("#time"); outfile2_->Printf("#time"); for (std::set<int>::iterator res = activeResidues_.begin(); res != activeResidues_.end(); ++res) { outfile_->Printf("\tresidue %i", *res); outfile2_->Printf("\tresidue %i", *res); } outfile_->Printf("\tTotal\n"); outfile2_->Printf("\tTotal\n"); } // Reserve space for residue contact counts residueContacts_.reserve( setup.Top().Nres() ); residueNative_.reserve( setup.Top().Nres() ); CurrentParm_ = setup.TopAddress(); return Action::OK; }
/** Determine what atoms each mask pertains to for the current parm file. */ Action::RetType Action_NMRrst::Setup(ActionSetup& setup) { if (!viewrst_.empty() && rsttop_ == 0) rsttop_ = setup.TopAddress(); // --------------------------------------------- // Set up NOEs from file. for (noeDataArray::iterator noe = NOEs_.begin(); noe != NOEs_.end(); ++noe) { if (setup.Top().SetupIntegerMask( noe->dMask1_ )) return Action::ERR; if (setup.Top().SetupIntegerMask( noe->dMask2_ )) return Action::ERR; if (noe->dMask1_.None() || noe->dMask2_.None()) { mprintf("Warning: One or both masks for NOE '%s' have no atoms (%i and %i).\n", noe->dist_->legend(), noe->dMask1_.Nselected(), noe->dMask2_.Nselected()); noe->active_ = false; } else noe->active_ = true; } // --------------------------------------------- // Set up potential NOE sites. if (findNOEs_) { if (setup.Top().SetupCharMask( Mask_ )) return Action::ERR; Mask_.MaskInfo(); if (Mask_.None()) return Action::SKIP; SiteArray potentialSites; // .clear(); AtomMap resMap; resMap.SetDebug( debug_ ); std::vector<bool> selected; Range soluteRes = setup.Top().SoluteResidues(); for (Range::const_iterator res = soluteRes.begin(); res != soluteRes.end(); ++res) { int res_first_atom = setup.Top().Res(*res).FirstAtom(); selected.assign( setup.Top().Res(*res).NumAtoms(), false ); // Find symmetric atom groups. AtomMap::AtomIndexArray symmGroups; if (resMap.SymmetricAtoms(setup.Top(), symmGroups, *res)) return Action::ERR; // DEBUG if (debug_ > 0) { mprintf("DEBUG: Residue %i: symmetric atom groups:\n", *res + 1); for (AtomMap::AtomIndexArray::const_iterator grp = symmGroups.begin(); grp != symmGroups.end(); ++grp) { mprintf("\t\t"); for (AtomMap::Iarray::const_iterator at = grp->begin(); at != grp->end(); ++at) mprintf(" %s", setup.Top().TruncAtomNameNum( *at ).c_str()); mprintf("\n"); } } // Each symmetric hydrogen atom group is a site. for (AtomMap::AtomIndexArray::const_iterator grp = symmGroups.begin(); grp != symmGroups.end(); ++grp) { // NOTE: If first atom is H all should be H. if ( setup.Top()[ grp->front() ].Element() == Atom::HYDROGEN ) { Iarray symmAtomGroup; for (Iarray::const_iterator at = grp->begin(); at != grp->end(); ++at) if (Mask_.AtomInCharMask( *at )) symmAtomGroup.push_back( *at ); if (!symmAtomGroup.empty()) { potentialSites.push_back( Site(*res, symmAtomGroup) ); // Mark symmetric atoms as selected. for (AtomMap::Iarray::const_iterator at = grp->begin(); at != grp->end(); ++at) selected[ *at - res_first_atom ] = true; } } } // All other non-selected hydrogens bonded to same heavy atom are sites. for (int ratom = res_first_atom; ratom != setup.Top().Res(*res).LastAtom(); ++ratom) { if ( setup.Top()[ratom].Element() != Atom::HYDROGEN ) { Iarray heavyAtomGroup; for (Atom::bond_iterator ba = setup.Top()[ratom].bondbegin(); ba != setup.Top()[ratom].bondend(); ++ba) if ( Mask_.AtomInCharMask(*ba) && *ba >= res_first_atom && *ba < setup.Top().Res(*res).LastAtom() ) { if ( !selected[ *ba - res_first_atom ] && setup.Top()[ *ba ].Element() == Atom::HYDROGEN ) heavyAtomGroup.push_back( *ba ); } if (!heavyAtomGroup.empty()) potentialSites.push_back( Site(*res, heavyAtomGroup) ); } } } mprintf("\t%zu potential NOE sites:\n", potentialSites.size()); for (SiteArray::const_iterator site = potentialSites.begin(); site != potentialSites.end(); ++site) { mprintf(" %u\tRes %i:", site - potentialSites.begin(), site->ResNum()+1); for (unsigned int idx = 0; idx != site->Nindices(); ++idx) mprintf(" %s", setup.Top().TruncAtomNameNum( site->Idx(idx) ).c_str()); mprintf("\n"); } if (noeArray_.empty()) { size_t siteArraySize = 0; // Set up all potential NOE pairs. Keep track of size. for (SiteArray::const_iterator site1 = potentialSites.begin(); site1 != potentialSites.end(); ++site1) { for (SiteArray::const_iterator site2 = site1 + 1; site2 != potentialSites.end(); ++site2) { if (site1->ResNum() != site2->ResNum()) { std::string legend = site1->SiteLegend(setup.Top()) + "--" + site2->SiteLegend(setup.Top()); DataSet* ds = 0; if (series_) { ds = masterDSL_->AddSet(DataSet::FLOAT, MetaData(setname_, "foundNOE", noeArray_.size())); if (ds == 0) return Action::ERR; // Construct a data set name. ds->SetLegend(legend); } noeArray_.push_back( NOEtype(*site1, *site2, ds, legend) ); siteArraySize += (2 * sizeof(int) * site1->Nindices()) + (2 * sizeof(int) * site2->Nindices()); } } } numNoePairs_ = noeArray_.size(); size_t siteSize = sizeof(int) + (2 * sizeof(Iarray)) + sizeof(Site); size_t noeSize = (2 * siteSize) + sizeof(DataSet*) + sizeof(double) + sizeof(NOEtype); if (series_) noeSize += sizeof(std::vector<float>); size_t noeArraySize = (noeSize * numNoePairs_) + siteArraySize; if (series_) noeArraySize += (setup.Nframes() * numNoePairs_ * sizeof(float)); mprintf("\t%zu potential NOE pairs. Estimated memory usage is %s\n", numNoePairs_, ByteString(noeArraySize, BYTE_DECIMAL).c_str()); } else if (numNoePairs_ != potentialSites.size()) { mprinterr("Warning: Found NOE matrix has already been set up for %zu potential\n" "Warning: NOEs, but %zu NOEs currently found.\n", numNoePairs_, potentialSites.size()); return Action::SKIP; } } // --------------------------------------------- // Set up NOEs specified on the command line if (!Pairs_.empty()) { if (!specifiedNOEs_.empty()) { mprintf("Warning: Specifying NOEs currently only works with first topology used.\n"); return Action::SKIP; } for (MaskPairArray::iterator mp = Pairs_.begin(); mp != Pairs_.end(); mp++) { if (setup.Top().SetupIntegerMask( mp->first )) return Action::ERR; int res1 = CheckSameResidue(setup.Top(), mp->first); if (res1 < 0) continue; if (setup.Top().SetupIntegerMask( mp->second )) return Action::ERR; int res2 = CheckSameResidue(setup.Top(), mp->second); if (res2 < 0) continue; Site site1( res1, mp->first.Selected() ); Site site2( res2, mp->second.Selected() ); std::string legend = site1.SiteLegend(setup.Top()) + "--" + site2.SiteLegend(setup.Top()); DataSet* ds = 0; if (series_) { ds = masterDSL_->AddSet(DataSet::FLOAT, MetaData(setname_, "specNOE", specifiedNOEs_.size())); if (ds == 0) return Action::ERR; ds->SetLegend(legend); } specifiedNOEs_.push_back( NOEtype(site1, site2, ds, legend) ); } } // Set up imaging info for this parm Image_.SetupImaging( setup.CoordInfo().TrajBox().Type() ); if (Image_.ImagingEnabled()) mprintf("\tImaged.\n"); else mprintf("\tImaging off.\n"); return Action::OK; }
/** Determine from selected mask atoms which dihedrals will be rotated. */ Action::RetType Action_DihedralScan::Setup(ActionSetup& setup) { DihedralScanType dst; // If range is empty (i.e. no resrange arg given) look through all // solute residues. Range actualRange; if (resRange_.Empty()) actualRange = setup.Top().SoluteResidues(); else actualRange = resRange_; // Search for dihedrals if (dihSearch_.FindDihedrals(setup.Top(), actualRange)) return Action::ERR; // For each found dihedral, set up mask of atoms that will move upon // rotation. Also set up mask of atoms in this residue that will not // move, including atom2. if (debug_>0) mprintf("DEBUG: Dihedrals:\n"); for (DihedralSearch::mask_it dih = dihSearch_.begin(); dih != dihSearch_.end(); ++dih) { dst.checkAtoms.clear(); // Set mask of atoms that will move during dihedral rotation. dst.Rmask = DihedralSearch::MovingAtoms(setup.Top(), dih->A1(), dih->A2()); // If randomly rotating angles, check for atoms that are in the same // residue as A1 but will not move. They need to be checked for clashes // since further rotations will not help them. if (mode_ == RANDOM && check_for_clashes_) { CharMask cMask( dst.Rmask.ConvertToCharMask(), dst.Rmask.Nselected() ); int a1res = setup.Top()[dih->A1()].ResNum(); for (int maskatom = setup.Top().Res(a1res).FirstAtom(); maskatom < setup.Top().Res(a1res).LastAtom(); ++maskatom) if (!cMask.AtomInCharMask(maskatom)) dst.checkAtoms.push_back( maskatom ); dst.checkAtoms.push_back(dih->A1()); // TODO: Does this need to be added first? // Since only the second atom and atoms it is bonded to move during // rotation, base the check on the residue of the second atom. dst.resnum = a1res; } dst.atom0 = dih->A0(); // FIXME: This duplicates info dst.atom1 = dih->A1(); dst.atom2 = dih->A2(); dst.atom3 = dih->A3(); BB_dihedrals_.push_back(dst); // DEBUG: List dihedral info. if (debug_ > 0) { mprintf("\t%s-%s-%s-%s\n", setup.Top().TruncResAtomName(dih->A0()).c_str(), setup.Top().TruncResAtomName(dih->A1()).c_str(), setup.Top().TruncResAtomName(dih->A2()).c_str(), setup.Top().TruncResAtomName(dih->A3()).c_str() ); if (debug_ > 1 && mode_ == RANDOM && check_for_clashes_) { mprintf("\t\tCheckAtoms="); for (std::vector<int>::const_iterator ca = dst.checkAtoms.begin(); ca != dst.checkAtoms.end(); ++ca) mprintf(" %i", *ca + 1); mprintf("\n"); } if (debug_ > 2) { mprintf("\t\t"); dst.Rmask.PrintMaskAtoms("Rmask:"); } } } // Set up CheckStructure for this parm (false = nobondcheck) if (checkStructure_.SeparateSetup(setup.Top(), setup.CoordInfo().TrajBox().Type(), false) != Action::OK) return Action::ERR; // Set the overall max number of rotations to try max_rotations_ = (int) BB_dihedrals_.size(); max_rotations_ *= max_factor_; // Set up simple structure check. First step is coarse; check distances // between a certain atom in each residue (first, COM, CA, some other atom?) // to see if residues are in each others neighborhood. Second step is to // check the atoms in each close residue. if (check_for_clashes_) { ResidueCheckType rct; int res = 0; for (Topology::res_iterator residue = setup.Top().ResStart(); residue != setup.Top().ResEnd(); ++residue) { rct.resnum = res++; rct.start = residue->FirstAtom(); rct.stop = residue->LastAtom(); rct.checkatom = rct.start; ResCheck_.push_back(rct); } } if (!outfilename_.empty() && CurrentParm_ == 0) // FIXME: Correct frames for # of rotations outtraj_.SetupTrajWrite(setup.TopAddress(), setup.CoordInfo(), setup.Nframes()); CurrentParm_ = setup.TopAddress(); return Action::OK; }
/** Set up solute and solvent masks. If no solvent mask was specified use * solvent information in the current topology. */ Action::RetType Action_Watershell::Setup(ActionSetup& setup) { // Set up solute mask if (setup.Top().SetupIntegerMask( soluteMask_ )) return Action::ERR; soluteMask_.MaskInfo(); if ( soluteMask_.None() ) { mprintf("Warning: No atoms in solute mask [%s].\n",soluteMask_.MaskString()); return Action::SKIP; } if (solventMask_.MaskStringSet()) { // Set up solvent mask if (setup.Top().SetupIntegerMask( solventMask_ )) return Action::ERR; solventMask_.MaskInfo(); } else { // Use all solvent atoms. solventMask_.ResetMask(); // Set number of atoms; needed for CharMask conversion. solventMask_.SetNatoms( setup.Top().Natom() ); for (Topology::mol_iterator mol = setup.Top().MolStart(); mol != setup.Top().MolEnd(); ++mol) if ( mol->IsSolvent() ) solventMask_.AddAtomRange( mol->BeginAtom(), mol->EndAtom() ); mprintf("\tSelecting all solvent atoms (%i total)\n", solventMask_.Nselected()); } if ( solventMask_.None() ) { if ( solventMask_.MaskStringSet() ) mprintf("Warning: No solvent atoms selected by mask [%s]\n", solventMask_.MaskString()); else mprintf("Warning: No solvent atoms in topology %s\n", setup.Top().c_str()); return Action::SKIP; } #ifdef CUDA // Since we are using the 'closest' kernels under the hood, all solvent mols // must have the same size. int first_solvent_mol = setup.Top()[ solventMask_[0] ].MolNum(); NAtoms_ = setup.Top().Mol( first_solvent_mol ).NumAtoms(); for (AtomMask::const_iterator atm = solventMask_.begin(); atm != solventMask_.end(); ++atm) { int mol = setup.Top()[*atm].MolNum(); if (NAtoms_ != setup.Top().Mol( mol ).NumAtoms()) { mprinterr("Error: CUDA version of 'watershell' requires all solvent mols be same size.\n"); return Action::ERR; } } // Determine how many solvent molecules are selected NsolventMolecules_ = 0; CharMask cMask( solventMask_.ConvertToCharMask(), solventMask_.Nselected() ); for (Topology::mol_iterator mol = setup.Top().MolStart(); mol != setup.Top().MolEnd(); ++mol) if ( cMask.AtomsInCharMask( mol->BeginAtom(), mol->EndAtom() ) ) NsolventMolecules_++; // Sanity check if ( (NsolventMolecules_ * NAtoms_) != solventMask_.Nselected() ) { mprinterr("Error: CUDA version of 'watershell' requires all atoms in solvent mols be selected.\n"); return Action::ERR; } // Allocate space for selected solvent atom coords and distances V_atom_coords_.resize( NsolventMolecules_ * NAtoms_ * 3, 0.0 ); V_distances_.resize( NsolventMolecules_ ); #else /* CUDA */ // Allocate space to record status of each solvent molecule. // NOTE: Doing this by residue instead of by molecule does waste some memory, // but it means watershell can be used even if no molecule info present. # ifdef _OPENMP // Each thread needs space to record residue status to avoid clashes for (std::vector<Iarray>::iterator it = shellStatus_thread_.begin(); it != shellStatus_thread_.end(); ++it) it->assign( setup.Top().Nres(), 0 ); # else shellStatus_.assign( setup.Top().Nres(), 0 ); # endif #endif /* CUDA */ // Set up imaging image_.SetupImaging( setup.CoordInfo().TrajBox().Type() ); if (image_.ImagingEnabled()) mprintf("\tImaging is on.\n"); else mprintf("\tImaging is off.\n"); // Allocate temp space for selected solute atom coords. soluteCoords_.resize( soluteMask_.Nselected() * 3 ); // Store current topology CurrentParm_ = setup.TopAddress(); return Action::OK; }
/** Set up a j-coupling calculation for dihedrals defined by atoms within * the mask. */ Action::RetType Action_Jcoupling::Setup(ActionSetup& setup) { std::string resName; karplusConstantList* currentResList=0; int MaxResidues; jcouplingInfo JC; if ( setup.Top().SetupCharMask(Mask1_) ) return Action::ERR; if (Mask1_.None()) { mprintf("Warning: Mask specifies no atoms.\n"); return Action::SKIP; } // If JcouplingInfo has already been set up, print a warning and reset for // new parm. if (!JcouplingInfo_.empty()) { mprintf("Warning: Jcoupling has been set up for another parm.\n" "Warning: Resetting jcoupling info for new parm %s\n",setup.Top().c_str()); //JcouplingInfo_.clear(); } // For each residue, set up 1 jcoupling calc for each parameter defined in // KarplusConstants for this residue. Only set up the Jcoupling calc if all // atoms involved are present in the mask. Range resRange = setup.Top().SoluteResidues(); for (Range::const_iterator residue = resRange.begin(); residue != resRange.end(); ++residue) { // Skip residue if no atoms within residue are selected. if (!Mask1_.AtomsInCharMask(setup.Top().Res(*residue).FirstAtom(), setup.Top().Res(*residue).LastAtom())) continue; resName.assign(setup.Top().Res(*residue).c_str()); karplusConstantMap::iterator reslist = KarplusConstants_.find(resName); // If list does not exist for residue, skip it. if (reslist == KarplusConstants_.end() ) { mprintf("Warning: Karplus parameters not found for residue [%i:%s]\n", *residue+1, resName.c_str()); continue; } currentResList = (*reslist).second; // For each parameter set in the list find the corresponding atoms. for (karplusConstantList::iterator kc = currentResList->begin(); kc != currentResList->end(); ++kc) { // Init jcoupling info. Constants will point inside KarplusConstants. JC.residue = *residue; JC.atom[0] = -1; JC.atom[1] = -1; JC.atom[2] = -1; JC.atom[3] = -1; JC.C = kc->C; JC.type = kc->type; // For each atom in the dihedral specified in this Karplus constant, find // corresponding atoms in parm. bool allAtomsFound = true; for (int idx=0; idx < 4; idx++) { JC.atom[idx] = setup.Top().FindAtomInResidue(*residue + kc->offset[idx], kc->atomName[idx] ); if (JC.atom[idx] == -1) { mprintf("Warning: Atom '%s' at position %i not found for residue %i\n", *(kc->atomName[idx]), idx, *residue+kc->offset[idx]+1); allAtomsFound = false; } } if (allAtomsFound) { // Check that all the atoms involved in this Jcouple dihedral are // in the atom mask. If so, add jcoupling info to the list. if (Mask1_.AtomInCharMask(JC.atom[0]) && Mask1_.AtomInCharMask(JC.atom[1]) && Mask1_.AtomInCharMask(JC.atom[2]) && Mask1_.AtomInCharMask(JC.atom[3])) { // TODO: Look for previously set up matching data set if (setname_.empty()) setname_ = masterDSL_->GenerateDefaultName("JC"); JC.data_ = masterDSL_->AddSet( DataSet::FLOAT, MetaData(setname_, setcount_++) ); if ( JC.data_ != 0 ) { JC.data_->SetLegend( setup.Top().TruncResNameNum(JC.residue) + "_" + setup.Top()[JC.atom[0]].Name().Truncated() + "-" + setup.Top()[JC.atom[1]].Name().Truncated() + "-" + setup.Top()[JC.atom[2]].Name().Truncated() + "-" + setup.Top()[JC.atom[3]].Name().Truncated() ); if (outfile_ != 0) outfile_->AddDataSet( JC.data_ ); JcouplingInfo_.push_back(JC); } else { mprinterr("Internal Error: Could not set up Jcoupling data set for res %i\n", JC.residue+1); } } } } // END loop over karplus parameters for this residue } // END loop over all residues // Print info for this parm mprintf(" J-COUPLING: [%s] Will calculate J-coupling for %zu dihedrals.\n", Mask1_.MaskString(), JcouplingInfo_.size()); if (JcouplingInfo_.empty()) { mprintf("Warning: No dihedrals found for J-coupling calculation!\n" "Warning: Check that all atoms of dihedrals are included in mask [%s]\n" "Warning: and/or that dihedrals are defined in Karplus parameter file.\n", Mask1_.MaskString()); return Action::SKIP; } // DEBUG if (debug_>0) { MaxResidues=1; for (std::vector<jcouplingInfo>::iterator jc = JcouplingInfo_.begin(); jc != JcouplingInfo_.end(); ++jc) { mprintf("%8i [%i:%4s]",MaxResidues,jc->residue, setup.Top().Res(jc->residue).c_str()); mprintf(" %6i:%-4s",jc->atom[0],setup.Top()[jc->atom[0]].c_str()); mprintf(" %6i:%-4s",jc->atom[1],setup.Top()[jc->atom[1]].c_str()); mprintf(" %6i:%-4s",jc->atom[2],setup.Top()[jc->atom[2]].c_str()); mprintf(" %6i:%-4s",jc->atom[3],setup.Top()[jc->atom[3]].c_str()); mprintf(" %6.2lf%6.2lf%6.2lf%6.2lf %i\n",jc->C[0],jc->C[1],jc->C[2],jc->C[3], jc->type); MaxResidues++; } } CurrentParm_ = setup.TopAddress(); return Action::OK; }
/** Determine what atoms each mask pertains to for the current parm file. * Also determine whether imaging should be performed. */ Action::RetType Action_Radial::Setup(ActionSetup& setup) { if ( setup.Top().SetupIntegerMask( Mask1_ ) ) return Action::ERR; if (Mask1_.None()) { mprintf("Warning: First mask has no atoms.\n"); return Action::SKIP; } if (setup.Top().SetupIntegerMask( Mask2_ ) ) return Action::ERR; if (Mask2_.None()) { mprintf("Warning: Second mask has no atoms.\n"); return Action::SKIP; } image_.SetupImaging( setup.CoordInfo().TrajBox().Type() ); // If not computing center for mask 1 or 2, make the outer loop for distance // calculation correspond to the mask with the most atoms. if (rmode_ == NORMAL || rmode_ == NO_INTRAMOL) { if (Mask1_.Nselected() > Mask2_.Nselected()) { OuterMask_ = Mask1_; InnerMask_ = Mask2_; } else { OuterMask_ = Mask2_; InnerMask_ = Mask1_; } } else if (rmode_ == CENTER1) { OuterMask_ = Mask1_; InnerMask_ = Mask2_; } else if (rmode_ == CENTER2) { OuterMask_ = Mask2_; InnerMask_ = Mask1_; } // If ignoring intra-molecular distances, need to count how many we // are ignoring. if (rmode_ == NO_INTRAMOL) { int ndist = 0; for (AtomMask::const_iterator atom1 = OuterMask_.begin(); atom1 != OuterMask_.end(); ++atom1) for (AtomMask::const_iterator atom2 = InnerMask_.begin(); atom2 != InnerMask_.end(); ++atom2) if ( setup.Top()[*atom1].MolNum() == setup.Top()[*atom2].MolNum() ) ++ndist; if (currentParm_ != 0 && ndist != intramol_distances_) mprintf("Warning: # of intramolecular distances (%i) has changed from the last" " topology (%i).\nWarning: Normalization will not be correct.\n", ndist, intramol_distances_); intramol_distances_ = ndist; currentParm_ = setup.TopAddress(); mprintf("\tIgnoring %i intra-molecular distances.\n", intramol_distances_); } // Check volume information if (useVolume_ && setup.CoordInfo().TrajBox().Type()==Box::NOBOX) { mprintf("Warning: 'volume' specified but no box information for %s, skipping.\n", setup.Top().c_str()); return Action::SKIP; } // Print mask and imaging info for this parm mprintf(" RADIAL: %i atoms in Mask1, %i atoms in Mask2, ", Mask1_.Nselected(), Mask2_.Nselected()); if (image_.ImagingEnabled()) mprintf("Imaging on.\n"); else mprintf("Imaging off.\n"); return Action::OK; }
// Action_ClusterDihedral::Setup() Action::RetType Action_ClusterDihedral::Setup(ActionSetup& setup) { // Currently setup can only be performed based on first prmtop if (dcparm_!=0) { mprintf("Warning: clusterdihedral is only setup based on the first prmtop\n"); mprintf("Warning: read in. Skipping setup for this prmtop.\n"); return Action::OK; } // Set up backbone dihedral angles if none were read if (DCmasks_.empty()) { // Setup mask if ( setup.Top().SetupIntegerMask( mask_ ) ) return Action::ERR; if ( mask_.None()) { mprinterr("Error clusterdihedral: No atoms selected by mask [%s]\n", mask_.MaskString()); return Action::ERR; } // NOTE: This code relies on selection having contiguous residues! int C1 = -1; int N2 = -1; int CA = -1; int C2 = -1; for (AtomMask::const_iterator atom = mask_.begin(); atom != mask_.end(); ++atom) { if ( C2 > -1 ) { // If we have already found the last C in phi dihedral, this N is // the last atom in psi dihedral - store both. if ( setup.Top()[*atom].Name() == "N " ) { DCmasks_.push_back( DCmask(C1, N2, CA, C2, phibins_, minimum_) ); // PHI DCmasks_.push_back( DCmask(N2, CA, C2, *atom, psibins_, minimum_) ); // PSI if (debug_ > 0) mprintf("DIHEDRAL PAIR FOUND: C1= %i, N2= %i, CA= %i, C2= %i, N3= %li\n", C1, N2, CA, C2, *atom); // Since the carbonyl C/amide N probably starts a new dihedral, // reset to those. C1 = C2; N2 = *atom; C2 = -1; CA = -1; } } else if ( C1 > -1 ) { // If we've already found the first carbonyl, look for other atoms // in the dihedral pair. if ( setup.Top()[*atom].Name() == "N " ) N2 = *atom; if ( setup.Top()[*atom].Name() == "CA " ) CA = *atom; if ( setup.Top()[*atom].Name() == "C " ) C2 = *atom; } else if ( setup.Top()[*atom].Name() == "C " ) C1 = *atom; // 1st carbon } // End loop over selected atoms mprintf("\tFound %zu dihedral angles.\n", DCmasks_.size()); } if (DCmasks_.empty()) { mprinterr("Error: clusterdihedral: No dihedral angles defined.\n"); return Action::ERR; } // Allocate space to hold Bin IDs each frame Bins_.resize( DCmasks_.size() ); dcparm_ = setup.TopAddress(); // DEBUG - Print bin ranges if (debug_ > 0) { for (std::vector<DCmask>::const_iterator dih = DCmasks_.begin(); dih != DCmasks_.end(); ++dih) { mprintf("\tDihedral %s-%s-%s-%s[", setup.Top()[dih->A1()].c_str(), setup.Top()[dih->A2()].c_str(), setup.Top()[dih->A3()].c_str(), setup.Top()[dih->A4()].c_str()); for (int phibin = 0; phibin < dih->Bins(); ++phibin) { double PHI = ((double)phibin * dih->Step()) + dih->Min(); mprintf("%6.2f] %3i [", PHI, phibin); } mprintf("%6.2f]\n",((double)dih->Bins() * dih->Step()) + dih->Min()); } } return Action::OK; }