/* * Zero forces on all local atoms and optionally on ghosts. */ void AtomStorage::zeroForces(bool zeroGhosts) { int factor = 2; // Zero forces for all local atoms if (nAtom() > atomCapacity_/factor) { atoms_.zeroForces(); // Optimization to allow sequential access } else { AtomIterator atomIter; begin(atomIter); for( ; atomIter.notEnd(); ++atomIter){ atomIter->force().zero(); } } // If using reverse communication, zero ghost atoms if (zeroGhosts && nGhost()) { if (nGhost() > ghostCapacity_/factor) { ghosts_.zeroForces(); // Optimization to allow sequential access } else { GhostIterator ghostIter; begin(ghostIter); for( ; ghostIter.notEnd(); ++ghostIter){ ghostIter->force().zero(); } } } }
/* * Compute, store and return total number of atoms on all processors. */ void AtomStorage::computeNAtomTotal(MPI::Intracomm& communicator) { // If nAtomTotal is already set, do nothing and return. // if (nAtomTotal_.isSet()) return; int nAtomLocal = nAtom(); int nAtomTotal = 0; communicator.Reduce(&nAtomLocal, &nAtomTotal, 1, MPI::INT, MPI::SUM, 0); if (communicator.Get_rank() !=0) { nAtomTotal = 0; } nAtomTotal_.set(nAtomTotal); }
/* * Transform all atomic coordinates from generalized to Cartesian. */ void AtomStorage::transformGenToCart(const Boundary& boundary) { if (isCartesian()) { UTIL_THROW("Error: Coordinates are Cartesian on entry"); } Vector r; if (nAtom()) { AtomIterator atomIter; for (begin(atomIter); atomIter.notEnd(); ++atomIter) { r = atomIter->position(); boundary.transformGenToCart(r, atomIter->position()); } } if (nGhost()) { GhostIterator ghostIter; for (begin(ghostIter); ghostIter.notEnd(); ++ghostIter) { r = ghostIter->position(); boundary.transformGenToCart(r, ghostIter->position()); } } isCartesian_ = true; }
/* * Check validity of this AtomStorage. * * Returns true if all is ok, or throws an Exception. */ bool AtomStorage::isValid() const { if (nAtom() + atomReservoir_.size() != atomCapacity_) { UTIL_THROW("nAtom + reservoir size != local capacity"); } if (nGhost() + ghostReservoir_.size() != ghostCapacity_) { UTIL_THROW("nGhost + reservoir size != ghost capacity"); } if (nGhost() != map_.nGhost()) { UTIL_THROW("Inconsistent values of nGhost"); } // Test validity of AtomMap. map_.isValid(); // Iterate over, count and find local atoms on this processor. ConstAtomIterator localIter; Atom* ptr; int j = 0; for (begin(localIter); localIter.notEnd(); ++localIter) { ++j; if (localIter->isGhost()) { UTIL_THROW("Atom in atomSet is marked isGhost"); } ptr = map_.find(localIter->id()); if (ptr == 0) { UTIL_THROW("Unable to find local atom returned by iterator"); } if (ptr != localIter.get()) { UTIL_THROW("Inconsistent find(localIter->id()"); } } if (j != nAtom()) { UTIL_THROW("Number counted by localIterator != nAtom()"); } // Iterate over, count and find ghost atoms ConstGhostIterator ghostIter; j = 0; for (begin(ghostIter); ghostIter.notEnd(); ++ghostIter) { ++j; if (!ghostIter->isGhost()) { UTIL_THROW("Atom in ghostSet is not marked isGhost"); } ptr = map_.find(ghostIter->id()); if (ptr == 0) { UTIL_THROW("find(ghostIter->id()) == 0"); } // We do NOT test if ptr == ghostIter.get(), because it is possible // to have multiple atoms with the same id on one processor. One to // one correspondence of ids and pointers is guaranteed only for // local atoms. } #if 0 if (j != nGhost()) { UTIL_THROW("Number counted by ghostIterator != nGhost()"); } #endif return true; }
Processor::Result PeptideCapProcessor::operator() (Chain& chain) { TranslationProcessor tlp; TransformationProcessor tfp; Matrix4x4 m; FragmentDB fragment_db(""); ReconstructFragmentProcessor reconstruct(fragment_db); Residue* ace_residue = NULL; Residue* nme_residue = NULL; // check if a ACE cap was already added bool add_cap = (chain.getResidue(0)->getName() != "ACE"); if (add_cap) { // create ACE-Cap ace_residue = new Residue("ACE"); ace_residue->setProperty(Residue::PROPERTY__AMINO_ACID); ace_residue->apply(reconstruct); ace_residue->apply(fragment_db.normalize_names); ace_residue->apply(fragment_db.build_bonds); AtomIterator ace_atom = ace_residue->beginAtom(); //get all atoms needed to compute the transformation of the cap Atom* cAtom = NULL; Atom* ch3Atom = NULL; Atom* oAtom = NULL; Atom* h1Atom = NULL; Vector3 h2Atom(0.0,0.0,0.0); Vector3 h3Atom(0.0,0.0,0.0); Vector3 nAtom(0.0,0.0,0.0); while(+ace_atom) { if (ace_atom->getName() == "C") cAtom = &*ace_atom; else if (ace_atom->getName() == "CH3") ch3Atom = &*ace_atom; else if (ace_atom->getName() == "O") oAtom = &*ace_atom; ++ace_atom; } std::vector<Atom*> to_remove; AtomIterator n_atom = chain.getResidue(0)->beginAtom(); while (+n_atom) { if (n_atom->getName() == "1H") { h1Atom = &*n_atom; n_atom->setName("H"); if (chain.getResidue(0)->getName() == "PRO") to_remove.push_back(&*n_atom); } else if (n_atom->getName() == "N") { nAtom = n_atom->getPosition(); n_atom->apply(fragment_db.add_hydrogens); } ++n_atom; } //compute position of OXT... map N of the last residue to it later tlp.setTranslation(ch3Atom->getPosition()*-1.0); ace_residue->apply(tlp); m.setRotation( Angle(180.0 * Constants::PI / 180.0), cAtom->getPosition()); // map oxt and N of the last residue to the origin tlp.setTranslation(m*oAtom->getPosition()*-1.0); ace_residue->apply(tlp); tlp.setTranslation(nAtom*-1.0); chain.apply(tlp); n_atom = chain.getResidue(0)->beginAtom(); while (+n_atom) { if (n_atom->getName() == "2H") { h2Atom = n_atom->getPosition(); to_remove.push_back(&*n_atom); } else if (n_atom->getName() == "3H") { h3Atom = n_atom->getPosition(); to_remove.push_back(&*n_atom); } ++n_atom; } //rotate CH3 atom to 2H position Angle angle = cAtom->getPosition().getAngle(h2Atom+h3Atom); Vector3 rot_axis = (cAtom->getPosition()%(h2Atom+h3Atom)).normalize(); m.setRotation(angle,rot_axis); tfp.setTransformation(m); ace_residue->apply(tfp); //insert ACE-Cap into chain chain.insertBefore(*ace_residue,*chain.getResidue(0)); //Add Bond between ACE-Cap and Helix n_atom = chain.getResidue(1)->beginAtom(); while (+n_atom) { if (n_atom->getName() == "N") { Bond* new_bond = cAtom->createBond(*n_atom); new_bond->setOrder(Bond::ORDER__SINGLE); break; } ++n_atom; } //back translation tlp.setTranslation(nAtom); chain.apply(tlp); //remove old hydrogens for (Position a = 0; a < to_remove.size(); ++a) { delete to_remove[a]; } //torsional optimzation of ACE optimizeCapPosition(chain, true); } //################################################################## add_cap = (chain.getResidue(chain.countResidues()-1)->getName() != "NME"); if (add_cap) { //create NME-Cap nme_residue = new Residue("NME"); nme_residue->setProperty(Residue::PROPERTY__AMINO_ACID); nme_residue->apply(reconstruct); nme_residue->apply(fragment_db.normalize_names); nme_residue->apply(fragment_db.build_bonds); Residue* last_residue = chain.getResidue(chain.countResidues()-1); //#################################################### Atom* nAtom = NULL; Atom* ch3Atom = NULL; Atom* hAtom = NULL; AtomIterator nme_atom = nme_residue->beginAtom(); while (+nme_atom) { if (nme_atom->getName() == "N") nAtom = &*nme_atom; else if (nme_atom->getName() == "CH3") ch3Atom = &*nme_atom; else if (nme_atom->getName() == "H") hAtom = &*nme_atom; ++nme_atom; } Vector3 anchor(( (hAtom->getPosition()-nAtom->getPosition()).normalize() + (ch3Atom->getPosition()-nAtom->getPosition()).normalize()).normalize()*-1.335); tlp.setTranslation((anchor + nAtom->getPosition())*-1.0); nme_residue->apply(tlp); Atom* oxt = NULL; Atom* cAtom = NULL; AtomIterator c_atom = last_residue->beginAtom(); while (+c_atom) { if (c_atom->getName() == "OXT") oxt = &*c_atom; else if (c_atom->getName() == "C") { anchor = c_atom->getPosition(); cAtom = &*c_atom; } ++c_atom; } tlp.setTranslation(anchor*-1.0); chain.apply(tlp); //transform cap to the old OXT position Angle angle = nAtom->getPosition().getAngle(oxt->getPosition()); Vector3 rot_axis = (nAtom->getPosition()%(oxt->getPosition())).normalize(); m.setRotation(angle,rot_axis); tfp.setTransformation(m); nme_residue->apply(tfp); //insert NME-Cap into chain chain.insertAfter(*nme_residue, *last_residue); //Add Bond between NME-Cap and Helix Bond* new_bond = cAtom->createBond(*nAtom); new_bond->setOrder(Bond::ORDER__SINGLE); tlp.setTranslation(anchor); chain.apply(tlp); delete oxt; //torsional optimzation of NME optimizeCapPosition(chain, false); } return Processor::CONTINUE; }