Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Fragmentation/Exporters/SaturatedFragment.cpp

    r5aaa43 r5d5550  
    6363    HydrogenPool &_hydrogens,
    6464    const enum HydrogenTreatment _treatment,
    65     const enum HydrogenSaturation _saturation) :
     65    const enum HydrogenSaturation _saturation,
     66    const GlobalSaturationPositions_t &_globalsaturationpositions) :
    6667  container(_container),
    6768  set(_set),
     
    7778  container.insert(set);
    7879
    79   // prepare saturation hydrogens
    80   saturate();
     80  // prepare saturation hydrogens, either using global information
     81  // or if not given, local information (created in the function)
     82  if (_globalsaturationpositions.empty())
     83    saturate();
     84  else
     85    saturate(_globalsaturationpositions);
    8186}
    8287
     
    99104}
    100105
    101 void SaturatedFragment::saturate()
    102 {
    103   // gather all atoms in a vector
    104   std::vector<atom *> atoms;
    105   for (KeySet::const_iterator iter = FullMolecule.begin();
    106       iter != FullMolecule.end();
     106typedef std::vector<atom *> atoms_t;
     107
     108atoms_t gatherAllAtoms(const KeySet &_FullMolecule)
     109{
     110  atoms_t atoms;
     111  for (KeySet::const_iterator iter = _FullMolecule.begin();
     112      iter != _FullMolecule.end();
    107113      ++iter) {
    108114    atom * const Walker = World::getInstance().getAtom(AtomById(*iter));
    109115    ASSERT( Walker != NULL,
    110         "SaturatedFragment::OutputConfig() - id "
     116        "gatherAllAtoms() - id "
    111117        +toString(*iter)+" is unknown to World.");
    112118    atoms.push_back(Walker);
    113119  }
    114120
    115 //  bool LonelyFlag = false;
    116   for (std::vector<atom *>::const_iterator iter = atoms.begin();
    117       iter != atoms.end();
     121  return atoms;
     122}
     123
     124typedef std::map<atom *, BondList > CutBonds_t;
     125
     126CutBonds_t gatherCutBonds(
     127    const atoms_t &_atoms,
     128    const KeySet &_set,
     129    const enum HydrogenTreatment _treatment)
     130{
     131  //  bool LonelyFlag = false;
     132  CutBonds_t CutBonds;
     133  for (atoms_t::const_iterator iter = _atoms.begin();
     134      iter != _atoms.end();
    118135      ++iter) {
    119136    atom * const Walker = *iter;
     
    125142        ++BondRunner) {
    126143      atom * const OtherWalker = (*BondRunner)->GetOtherAtom(Walker);
    127       // if in set
    128       if (set.find(OtherWalker->getId()) != set.end()) {
     144      // if other atom is in key set or is a specially treated hydrogen
     145      if (_set.find(OtherWalker->getId()) != _set.end()) {
    129146        LOG(4, "DEBUG: Walker " << *Walker << " is bound to " << *OtherWalker << ".");
    130 //        if (OtherWalker->getId() > Walker->getId()) { // add bond (Nr check is for adding only one of both variants: ab, ba)
    131 ////          std::stringstream output;
    132 ////            output << "ACCEPT: Adding Bond: "
    133 //          output << Leaf->AddBond((*iter), OtherWalker, (*BondRunner)->getDegree());
    134 ////            LOG(3, output.str());
    135 //          //NumBonds[(*iter)->getNr()]++;
    136 //        } else {
    137 ////            LOG(3, "REJECY: Not adding bond, labels in wrong order.");
    138 //        }
    139 //        LonelyFlag = false;
     147      } else if ((_treatment == ExcludeHydrogen)
     148          && (OtherWalker->getElementNo() == (atomicNumber_t)1)) {
     149        LOG(4, "DEBUG: Walker " << *Walker << " is bound to specially treated hydrogen " <<
     150            *OtherWalker << ".");
    140151      } else {
    141152        LOG(4, "DEBUG: Walker " << *Walker << " is bound to "
    142153            << *OtherWalker << ", who is not in this fragment molecule.");
    143         if (saturation == DoSaturate) {
    144 //          LOG(3, "ACCEPT: Adding Hydrogen to " << (*iter)->Name << " and a bond in between.");
    145           if (!AddHydrogenReplacementAtom(
    146               (*BondRunner),
    147               Walker,
    148               OtherWalker,
    149               World::getInstance().getConfig()->IsAngstroem == 1))
    150             exit(1);
     154          if (CutBonds.count(Walker) == 0)
     155            CutBonds.insert( std::make_pair(Walker, BondList() ));
     156          CutBonds[Walker].push_back(*BondRunner);
     157      }
     158    }
     159  }
     160
     161  return CutBonds;
     162}
     163
     164typedef std::vector<atomId_t> atomids_t;
     165
     166atomids_t gatherPresentExcludedHydrogens(
     167    const atoms_t &_atoms,
     168    const KeySet &_set,
     169    const enum HydrogenTreatment _treatment)
     170{
     171  //  bool LonelyFlag = false;
     172  atomids_t ExcludedHydrogens;
     173  for (atoms_t::const_iterator iter = _atoms.begin();
     174      iter != _atoms.end();
     175      ++iter) {
     176    atom * const Walker = *iter;
     177
     178    // go through all bonds
     179    const BondList& ListOfBonds = Walker->getListOfBonds();
     180    for (BondList::const_iterator BondRunner = ListOfBonds.begin();
     181        BondRunner != ListOfBonds.end();
     182        ++BondRunner) {
     183      atom * const OtherWalker = (*BondRunner)->GetOtherAtom(Walker);
     184      // if other atom is in key set or is a specially treated hydrogen
     185      if (_set.find(OtherWalker->getId()) != _set.end()) {
     186        LOG(6, "DEBUG: OtherWalker " << *OtherWalker << " is in set already.");
     187      } else if ((_treatment == ExcludeHydrogen)
     188          && (OtherWalker->getElementNo() == (atomicNumber_t)1)) {
     189        LOG(5, "DEBUG: Adding excluded hydrogen OtherWalker " << *OtherWalker << ".");
     190        ExcludedHydrogens.push_back(OtherWalker->getId());
     191      } else {
     192        LOG(6, "DEBUG: OtherWalker " << *Walker << " is not in this fragment molecule and no hydrogen.");
     193      }
     194    }
     195  }
     196
     197  return ExcludedHydrogens;
     198}
     199
     200void SaturatedFragment::saturate()
     201{
     202  // so far, we just have a set of keys. Hence, convert to atom refs
     203  // and gather all atoms in a vector
     204  std::vector<atom *> atoms = gatherAllAtoms(FullMolecule);
     205
     206  // go through each atom of the fragment and gather all cut bonds in list
     207  CutBonds_t CutBonds = gatherCutBonds(atoms, set, treatment);
     208
     209  // add excluded hydrogens to FullMolecule if treated specially
     210  if (treatment == ExcludeHydrogen) {
     211    atomids_t ExcludedHydrogens = gatherPresentExcludedHydrogens(atoms, set, treatment);
     212    FullMolecule.insert(ExcludedHydrogens.begin(), ExcludedHydrogens.end());
     213  }
     214
     215  // go through all cut bonds and replace with a hydrogen
     216  for (CutBonds_t::const_iterator atomiter = CutBonds.begin();
     217      atomiter != CutBonds.end(); ++atomiter) {
     218    atom * const Walker = atomiter->first;
     219    if (!saturateAtom(Walker, atomiter->second))
     220      exit(1);
     221  }
     222}
     223
     224void SaturatedFragment::saturate(
     225    const GlobalSaturationPositions_t &_globalsaturationpositions)
     226{
     227  // so far, we just have a set of keys. Hence, convert to atom refs
     228  // and gather all atoms in a vector
     229  std::vector<atom *> atoms = gatherAllAtoms(FullMolecule);
     230
     231  // go through each atom of the fragment and gather all cut bonds in list
     232  CutBonds_t CutBonds = gatherCutBonds(atoms, set, treatment);
     233
     234  // add excluded hydrogens to FullMolecule if treated specially
     235  if (treatment == ExcludeHydrogen) {
     236    atomids_t ExcludedHydrogens = gatherPresentExcludedHydrogens(atoms, set, treatment);
     237    FullMolecule.insert(ExcludedHydrogens.begin(), ExcludedHydrogens.end());
     238  }
     239
     240  // go through all cut bonds and replace with a hydrogen
     241  if (saturation == DoSaturate) {
     242    for (CutBonds_t::const_iterator atomiter = CutBonds.begin();
     243        atomiter != CutBonds.end(); ++atomiter) {
     244      atom * const Walker = atomiter->first;
     245      LOG(4, "DEBUG: We are now saturating dangling bonds of " << *Walker);
     246
     247      // gather set of positions for this atom from global map
     248      GlobalSaturationPositions_t::const_iterator mapiter =
     249          _globalsaturationpositions.find(Walker->getId());
     250      ASSERT( mapiter != _globalsaturationpositions.end(),
     251          "SaturatedFragment::saturate() - no global information for "
     252          +toString(*Walker));
     253      const SaturationsPositionsPerNeighbor_t &saturationpositions =
     254          mapiter->second;
     255
     256      // go through all cut bonds for this atom
     257      for (BondList::const_iterator bonditer = atomiter->second.begin();
     258          bonditer != atomiter->second.end(); ++bonditer) {
     259        atom * const OtherWalker = (*bonditer)->GetOtherAtom(Walker);
     260
     261        // get positions from global map
     262        SaturationsPositionsPerNeighbor_t::const_iterator positionsiter =
     263            saturationpositions.find(OtherWalker->getId());
     264        ASSERT(positionsiter != saturationpositions.end(),
     265            "SaturatedFragment::saturate() - no information on bond neighbor "
     266            +toString(*OtherWalker)+" to atom "+toString(*Walker));
     267        ASSERT(!positionsiter->second.empty(),
     268            "SaturatedFragment::saturate() - no positions for saturating bond to"
     269            +toString(*OtherWalker)+" to atom "+toString(*Walker));
     270
     271//        // get typical bond distance from elements database
     272//        double BondDistance = Walker->getType()->getHBondDistance(positionsiter->second.size()-1);
     273//        if (BondDistance < 0.) {
     274//          ELOG(2, "saturateAtoms() - no typical hydrogen bond distance of degree "
     275//              +toString(positionsiter->second.size())+" for element "
     276//              +toString(Walker->getType()->getName()));
     277//          // try bond degree 1 distance
     278//          BondDistance = Walker->getType()->getHBondDistance(1-1);
     279//          if (BondDistance < 0.) {
     280//            ELOG(1, "saturateAtoms() - no typical hydrogen bond distance for element "
     281//                +toString(Walker->getType()->getName()));
     282//            BondDistance = 1.;
     283//          }
     284//        }
     285
     286        // place hydrogen at each point
     287        LOG(4, "DEBUG: Places to saturate for atom " << *OtherWalker
     288            << " are " << positionsiter->second);
     289        atom * const father = Walker;
     290        for (SaturationsPositions_t::const_iterator positer = positionsiter->second.begin();
     291            positer != positionsiter->second.end(); ++positer) {
     292          const atom& hydrogen =
     293              setHydrogenReplacement(Walker, *positer, 1., father);
     294          FullMolecule.insert(hydrogen.getId());
    151295        }
    152 //        } else if ((treatment == ExcludeHydrogen) && (OtherWalker->getElementNo() == (atomicNumber_t)1)) {
    153 //          // just copy the atom if it's a hydrogen
    154 //          atom * const OtherWalker = Leaf->AddCopyAtom(OtherWalker);
    155 //          Leaf->AddBond((*iter), OtherWalker, (*BondRunner)->getDegree());
    156 //        }
    157         //NumBonds[(*iter)->getNr()] += Binder->getDegree();
    158296      }
    159297    }
    160   }
     298  } else
     299    LOG(3, "INFO: We are not saturating cut bonds.");
     300}
     301
     302const atom& SaturatedFragment::setHydrogenReplacement(
     303  const atom * const _OwnerAtom,
     304  const Vector &_position,
     305  const double _distance,
     306  atom * const _father)
     307{
     308  atom * const _atom = hydrogens.leaseHydrogen();    // new atom
     309  _atom->setPosition( _OwnerAtom->getPosition() + _distance * _position );
     310  // always set as fixed ion (not moving during molecular dynamics simulation)
     311  _atom->setFixedIon(true);
     312  // if we replace hydrogen, we mark it as our father, otherwise we are just an added hydrogen with no father
     313  _atom->father = _father;
     314  SaturationHydrogens.insert(_atom->getId());
     315
     316  return *_atom;
     317}
     318
     319bool SaturatedFragment::saturateAtom(
     320    atom * const _atom,
     321    const BondList &_cutbonds)
     322{
     323  // go through each bond and replace
     324  for (BondList::const_iterator bonditer = _cutbonds.begin();
     325      bonditer != _cutbonds.end(); ++bonditer) {
     326    atom * const OtherWalker = (*bonditer)->GetOtherAtom(_atom);
     327    if (!AddHydrogenReplacementAtom(
     328        (*bonditer),
     329        _atom,
     330        OtherWalker,
     331        World::getInstance().getConfig()->IsAngstroem == 1))
     332      return false;
     333  }
     334  return true;
    161335}
    162336
     
    270444  if (BondRescale == -1) {
    271445    ELOG(1, "There is no typical hydrogen bond distance in replacing bond (" << Origin->getName() << "<->" << Replacement->getName() << ") of degree " << TopBond->getDegree() << "!");
    272     return false;
    273     BondRescale = bondlength;
     446    BondRescale = Origin->getType()->getHBondDistance(TopBond->getDegree());
     447    if (BondRescale == -1) {
     448      ELOG(1, "There is no typical hydrogen bond distance in replacing bond (" << Origin->getName() << "<->" << Replacement->getName() << ") of any degree!");
     449      return false;
     450      BondRescale = bondlength;
     451    }
    274452  } else {
    275453    if (!IsAngstroem)
Note: See TracChangeset for help on using the changeset viewer.