use of org.openscience.cdk.ringsearch.RingSearch in project cdk by cdk.
the class FischerRecognition method recognise.
/**
* Recognise the tetrahedral stereochemistry in the provided structure.
*
* @param projections allowed projection types
* @return zero of more stereo elements
*/
List<IStereoElement> recognise(Set<Projection> projections) {
if (!projections.contains(Projection.Fischer))
return Collections.emptyList();
// build atom index and only recognize 2D depictions
Map<IAtom, Integer> atomToIndex = new HashMap<>();
for (IAtom atom : container.atoms()) {
if (atom.getPoint2d() == null)
return Collections.emptyList();
atomToIndex.put(atom, atomToIndex.size());
}
RingSearch ringSearch = new RingSearch(container, graph);
final List<IStereoElement> elements = new ArrayList<>(5);
for (int v = 0; v < container.getAtomCount(); v++) {
IAtom focus = container.getAtom(v);
Elements elem = Elements.ofNumber(focus.getAtomicNumber());
if (elem != Carbon)
continue;
if (ringSearch.cyclic(v))
continue;
if (stereocenters.elementType(v) != Tetracoordinate)
continue;
if (!stereocenters.isStereocenter(v))
continue;
ITetrahedralChirality element = newTetrahedralCenter(focus, neighbors(v, graph, bonds));
if (element == null)
continue;
// east/west bonds must be to terminal atoms
IAtom east = element.getLigands()[EAST];
IAtom west = element.getLigands()[WEST];
if (!east.equals(focus) && !isTerminal(east, atomToIndex))
continue;
if (!west.equals(focus) && !isTerminal(west, atomToIndex))
continue;
elements.add(element);
}
return elements;
}
use of org.openscience.cdk.ringsearch.RingSearch in project cdk by cdk.
the class CyclicCarbohydrateRecognition method recognise.
/**
* Recognise the cyclic carbohydrate projections.
*
* @param projections the types of projections to recognise
* @return recognised stereocenters
*/
List<IStereoElement> recognise(Set<Projection> projections) {
if (!projections.contains(Projection.Haworth) && !projections.contains(Projection.Chair))
return Collections.emptyList();
List<IStereoElement> elements = new ArrayList<>();
RingSearch ringSearch = new RingSearch(container, graph);
for (int[] isolated : ringSearch.isolated()) {
if (isolated.length < 5 || isolated.length > 7)
continue;
int[] cycle = Arrays.copyOf(GraphUtil.cycle(graph, isolated), isolated.length);
Point2d[] points = coordinatesOfCycle(cycle, container);
Turn[] turns = turns(points);
WoundProjection projection = WoundProjection.ofTurns(turns);
if (!projections.contains(projection.projection))
continue;
// ring is not aligned correctly for haworth
if (projection.projection == Projection.Haworth && !checkHaworthAlignment(points))
continue;
final Point2d horizontalXy = horizontalOffset(points, turns, projection.projection);
// near vertical, should also flag as potentially ambiguous
if (1 - Math.abs(horizontalXy.y) < QUART_CARDINALITY_THRESHOLD)
continue;
int[] above = cycle.clone();
int[] below = cycle.clone();
if (!assignSubstituents(cycle, above, below, projection, horizontalXy))
continue;
elements.addAll(newTetrahedralCenters(cycle, above, below, projection));
}
return elements;
}
use of org.openscience.cdk.ringsearch.RingSearch in project cdk by cdk.
the class AtomContainerManipulator method setSingleOrDoubleFlags.
/**
* Assigns {@link CDKConstants#SINGLE_OR_DOUBLE} flags to the bonds of
* a container. The single or double flag indicates uncertainty of bond
* order and in this case is assigned to all aromatic bonds (and atoms)
* which occur in rings. If any such bonds are found the flag is also set
* on the container.
*
* <blockquote><pre>
* SmilesParser parser = new SmilesParser(...);
* parser.setPreservingAromaticity(true);
*
* IAtomContainer biphenyl = parser.parseSmiles("c1cccc(c1)c1ccccc1");
*
* AtomContainerManipulator.setSingleOrDoubleFlags(biphenyl);
* </pre></blockquote>
*
* @param ac container to which the flags are assigned
* @return the input for convenience
*/
public static IAtomContainer setSingleOrDoubleFlags(IAtomContainer ac) {
// note - we could check for any aromatic bonds to avoid RingSearch but
// RingSearch is fast enough it probably wouldn't do much to check
// before hand
RingSearch rs = new RingSearch(ac);
boolean singleOrDouble = false;
for (IBond bond : rs.ringFragments().bonds()) {
if (bond.getFlag(CDKConstants.ISAROMATIC)) {
bond.setFlag(SINGLE_OR_DOUBLE, true);
bond.getBegin().setFlag(SINGLE_OR_DOUBLE, true);
bond.getEnd().setFlag(SINGLE_OR_DOUBLE, true);
singleOrDouble = singleOrDouble | true;
}
}
if (singleOrDouble) {
ac.setFlag(CDKConstants.SINGLE_OR_DOUBLE, true);
}
return ac;
}
use of org.openscience.cdk.ringsearch.RingSearch in project cdk by cdk.
the class Cycles method markRingAtomsAndBonds.
/**
* Find and mark all cyclic atoms and bonds in the provided molecule. This optimised version
* allows the caller to optionally provided indexed fast access structure which would otherwise
* be created.
*
* @param mol molecule
* @see IBond#isInRing()
* @see IAtom#isInRing()
* @return Number of rings found (circuit rank)
* @see <a href="https://en.wikipedia.org/wiki/Circuit_rank">Circuit Rank</a>
*/
public static int markRingAtomsAndBonds(IAtomContainer mol, int[][] adjList, EdgeToBondMap bondMap) {
RingSearch ringSearch = new RingSearch(mol, adjList);
for (int v = 0; v < mol.getAtomCount(); v++) {
mol.getAtom(v).setIsInRing(false);
for (int w : adjList[v]) {
// clear flag on first visit (or if non-cyclic)
if (v > w && ringSearch.cyclic(v, w)) {
bondMap.get(v, w).setIsInRing(true);
mol.getAtom(v).setIsInRing(true);
mol.getAtom(w).setIsInRing(true);
} else {
bondMap.get(v, w).setIsInRing(false);
}
}
}
return ringSearch.numRings();
}
use of org.openscience.cdk.ringsearch.RingSearch in project MORTAR by FelixBaensch.
the class SugarRemovalUtility method removeSugarCandidatesWithCyclicAtoms.
/**
* Alternative method to removing all cyclic atoms from the linear sugar candidates: Rejecting
* every candidate completely that contains a cyclic atom. This method was deprecated because this way also connected
* linear moieties get discarded.
* Note: here, the given list is altered, unlike in some other methods! Therefore, the list is not returned again.
* Note also that it is not checked whether the given parent molecule is actually the parent of the given
* substructures.
*
* @param aCandidateList a list of linear sugar candidates from the same atom container object
* @param aMolecule the molecule that is currently scanned for linear sugars to detect its circular sugars
* @throws NullPointerException if any parameter is 'null'
*/
@Deprecated
protected void removeSugarCandidatesWithCyclicAtoms(List<IAtomContainer> aCandidateList, IAtomContainer aMolecule) throws NullPointerException {
Objects.requireNonNull(aCandidateList, "Given list is 'null'.");
if (aCandidateList.isEmpty()) {
return;
}
Objects.requireNonNull(aMolecule, "Given molecule is 'null'.");
int[][] tmpAdjList = GraphUtil.toAdjList(aMolecule);
RingSearch tmpRingSearch = new RingSearch(aMolecule, tmpAdjList);
boolean tmpMoleculeHasRings = tmpRingSearch.numRings() > 0;
if (!tmpMoleculeHasRings) {
// nothing to process
return;
}
for (int i = 0; i < aCandidateList.size(); i++) {
IAtomContainer tmpCandidate = aCandidateList.get(i);
for (int j = 0; j < tmpCandidate.getAtomCount(); j++) {
IAtom tmpAtom = tmpCandidate.getAtom(j);
if (tmpRingSearch.cyclic(tmpAtom)) {
aCandidateList.remove(i);
// removal shifts the remaining indices
i = i - 1;
break;
}
}
}
}
Aggregations