org.xmlcml.cml.tools.ChainSet Maven / Gradle / Ivy
/**
* Copyright 2011 Peter Murray-Rust et. al.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xmlcml.cml.tools;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.xmlcml.cml.base.AbstractTool;
import org.xmlcml.cml.element.CMLAtom;
import org.xmlcml.cml.element.CMLAtomSet;
import org.xmlcml.cml.element.CMLBond;
import org.xmlcml.cml.element.CMLBondSet;
import org.xmlcml.molutil.ChemicalElement.AS;
/**
* tool to support a ring. not fully developed
*
* @author pmr
*
*/
public class ChainSet extends AbstractTool {
final static Logger LOG = Logger.getLogger(RingNucleus.class);
private Set chainSet;
private Map sproutMap;
private Map atomMap;
private Map bondMap;
private MoleculeLayout moleculeDraw;
/**
*/
public ChainSet() {
init();
}
private void init() {
this.chainSet = new HashSet();
this.sproutMap = new HashMap();
this.atomMap = new HashMap();
this.bondMap = new HashMap();
}
/**
* @param moleculeDraw
*/
public ChainSet(MoleculeLayout moleculeDraw) {
this();
this.setMoleculeDraw(moleculeDraw);
}
/** adds new chain and indexes
* indexes on atoms, bond, sprouts
* @param chain
*/
public void add(Chain chain) {
if (!chainSet.contains(chain)) {
chainSet.add(chain);
chain.setMoleculeDraw(moleculeDraw);
for (Sprout sprout : chain.getSproutList()) {
if (sproutMap.get(sprout) != null) {
throw new RuntimeException("sprout in two chains: "+sprout);
}
sproutMap.put(sprout, chain);
}
CMLAtomSet atomSet = chain.getAtomSet();
for (CMLAtom atom : atomSet.getAtoms()) {
if (atomMap.get(atom) != null) {
throw new RuntimeException("atom in two chains: "+atom.getId());
}
// LOG.debug("adding: "+atom.getId());
atomMap.put(atom, chain);
}
CMLBondSet bondSet = chain.getBondSet();
for (CMLBond bond : bondSet.getBonds()) {
if (bondMap.get(bond) != null) {
throw new RuntimeException("bond in two chains: "+bond.getId());
}
// LOG.debug("adding: "+bond.getId());
bondMap.put(bond, chain);
}
}
}
/** finds chain when there are no ringNuclei.
* looks for first bond which is terminal and then expands
* @param bondSet
*/
public void findOrCreateAndAddChain(CMLBondSet bondSet) {
for (CMLBond bond : bondSet.getBonds()) {
CMLAtom atom0 = bond.getAtom(0);
CMLAtom atom1 = bond.getAtom(1);
if (atom0.getLigandBonds().size() == 1) {
findOrCreateAndAddChain(atom0, bond, null);
break;
} else if (atom1.getLigandBonds().size() == 1) {
findOrCreateAndAddChain(atom1, bond, null);
break;
}
}
}
/** finds chain to which start belongs.
* if none, creates new chain and adds to set
* @param sprout
* @param ringNucleusSet
* @return chain
*/
public Chain findOrCreateAndAddChain(Sprout sprout, RingNucleusSet ringNucleusSet) {
Chain chain = findOrCreateAndAddChain(sprout.getRingAtom(), sprout.getBond(), ringNucleusSet);
sprout.setChain(chain);
return chain;
}
/** finds chain to which start belongs.
* if none, creates new chain and adds to set
* @param startAtom
* @param startBond
* @param ringNucleusSet
* @return chain
*/
public Chain findOrCreateAndAddChain(CMLAtom startAtom, CMLBond startBond, RingNucleusSet ringNucleusSet) {
Chain chain = this.getAtomMap().get(startAtom);
if (chain == null) {
chain = new Chain(moleculeDraw);
this.expandUntilEndOrSprout(chain, startAtom, startBond, ringNucleusSet);
this.add(chain);
}
return chain;
}
private void expandUntilEndOrSprout(Chain chain, CMLAtom usedAtom, CMLBond currentBond,
RingNucleusSet ringNucleusSet) {
chain.addBond(currentBond);
CMLAtom nextAtom = currentBond.getOtherAtom(usedAtom);
// checkHydrogens
List bondList = nextAtom.getLigandBonds();
int nadded = 0;
for (CMLBond ligandBond : bondList) {
CMLAtom otherAtom = ligandBond.getOtherAtom(nextAtom);
// skip hydrogens if required
if (((MoleculeDisplay)moleculeDraw.getAbstractDisplay()).isOmitHydrogens() && AS.H.equals(otherAtom.getElementType())) {
continue;
}
// bond already used
if (chain.getBondSet().contains(ligandBond)) {
} else if (ringNucleusSet != null &&
ringNucleusSet.getBondMap().get(ligandBond) != null) {
} else if (ringNucleusSet != null &&
ringNucleusSet.getBondSproutMap().get(ligandBond) != null) {
// found a sprout
Sprout otherSprout = ringNucleusSet.getBondSproutMap().get(ligandBond);
if (chain.getSproutList().contains(otherSprout)) {
throw new RuntimeException("Sprout detected twice");
} else {
chain.addSprout(otherSprout);
}
} else {
nadded++;
expandUntilEndOrSprout(chain, nextAtom, ligandBond, ringNucleusSet);
}
}
if (nadded == 0) {
chain.addTerminalBond(nextAtom, currentBond);
}
}
/**
* @param moleculeDraw
*/
public void layout(MoleculeLayout moleculeDraw) {
for (Chain chain : this.chainSet) {
chain.calculate2DCoordinates(null, moleculeDraw);
}
}
/**
* @return the atomMap
*/
public Map getAtomMap() {
return atomMap;
}
/**
* @return the bondMap
*/
public Map getBondMap() {
return bondMap;
}
/**
* @return the chainSet
*/
public Set getChainSet() {
return chainSet;
}
/**
* @return the sproutMap
*/
public Map getSproutMap() {
return sproutMap;
}
/**
* @return string
*/
public String toString() {
String s = "chainSet: ";
for (Chain chain : chainSet) {
s += chain+"\n";
}
return s;
}
/**
* @return the moleculeDraw
*/
public MoleculeLayout getMoleculeDraw() {
return moleculeDraw;
}
/**
* @param moleculeDraw the moleculeDraw to set
*/
public void setMoleculeDraw(MoleculeLayout moleculeDraw) {
this.moleculeDraw = moleculeDraw;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy