![JAR search and dependency download from the Maven repository](/logo.png)
org.xmlcml.cml.chemdraw.components.CDXFragment Maven / Gradle / Ivy
/**
* Copyright (C) 2001 Peter Murray-Rust ([email protected])
*
* 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.chemdraw.components;
import java.util.List;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.xmlcml.cml.base.CMLConstants;
import org.xmlcml.cml.element.CMLAtom;
import org.xmlcml.cml.element.CMLBond;
import org.xmlcml.cml.element.CMLBondStereo;
import org.xmlcml.cml.element.CMLLabel;
import org.xmlcml.cml.element.CMLMolecule;
import org.xmlcml.euclid.Real2;
import org.xmlcml.euclid.Vector2;
import nu.xom.Element;
import nu.xom.Elements;
import nu.xom.Nodes;
/**
*
* @author pm286
*
*/
public class CDXFragment extends CDXObject {
static Logger LOG = Logger.getLogger(CDXFragment.class);
static {
LOG.setLevel(Level.INFO);
}
public final static int CODE = 0x8003;
public final static String NAME = "Fragment";
public final static String CDXNAME = "fragment";
private static final double SCALE_GROUPS = 0.3;
public CDXFragment() {
super(CODE, NAME, CDXNAME);
}
/**
* copy node .
* @return Element
*/
public Element copy() {
return new CDXFragment(this);
}
/**
* copy constructor
* @param old
*/
public CDXFragment(CDXFragment old) {
super(old);
}
void process2CML(CMLMolecule molecule) {
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
Elements childElements = this.getChildElements();
for (int i = 0; i < childElements.size(); i++) {
CDXObject child = (CDXObject) childElements.get(i);
if (child instanceof CDXNode) {
((CDXNode)child).process2CML(molecule);
} else if (child instanceof CDXBond) {
((CDXBond)child).process2CML(molecule);
} else if (child instanceof CDXGraphic) {
LOG.debug("Skipped graphic");
((CDXGraphic)child).process2CML(molecule);
} else if (child instanceof CDXText) {
((CDXText)child).process2CML(molecule);
} else {
LOG.error("Cannot parse fragment child: "+child);
}
}
// flatten subgroups
flattenSubGroups(molecule);
}
void flattenSubGroups(CMLMolecule molecule) {
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
List atomList = molecule.getAtoms();
for (CMLAtom replacedAtom : atomList) {
Nodes subMolecules = replacedAtom.query("cml:molecule", CML_XPATH);
if (subMolecules.size() == 0) {
continue;
} else if (subMolecules.size() > 1) {
throw new RuntimeException("too many molecule children");
}
List parentReplacedAtoms = replacedAtom.getLigandAtoms();
CMLAtom replacedAtomParent = null;
if (parentReplacedAtoms.size() == 0) {
LOG.warn("too few ligands of replaced atom");
} else if (parentReplacedAtoms.size() > 1) {
replacedAtomParent = parentReplacedAtoms.get(0);
LOG.warn("too many ligands of replaced atom: "+replacedAtom.getId());
} else {
replacedAtomParent = parentReplacedAtoms.get(0);
}
CMLMolecule subMolecule = (CMLMolecule) subMolecules.get(0);
Nodes atoms = subMolecule.query(
"cml:atomArray/cml:atom[@*[local-name()='NodeType' and .='ExternalConnectionPoint']]", CML_XPATH);
CMLAtom extensionAtom = null;
if (atoms.size() == 0) {
LOG.warn("too few extension points");
} else if (atoms.size() > 1) {
LOG.warn("too many extension points: "+atoms.size());
}
if (atoms.size() > 0) {
extensionAtom = (CMLAtom) atoms.get(0);
List extensionLigandAtoms = extensionAtom.getLigandAtoms();
if (extensionLigandAtoms.size() == 0 || extensionLigandAtoms.size() > 1) {
throw new RuntimeException("too few/many ligands of extension points");
}
CMLAtom replacingAtom = extensionLigandAtoms.get(0);
replaceAtomsAndBonds(molecule, replacedAtom, replacedAtomParent, subMolecule, extensionAtom, replacingAtom);
}
}
}
private void replaceAtomsAndBonds(CMLMolecule molecule, CMLAtom replacedAtom, CMLAtom replacedAtomParent,
CMLMolecule subMolecule, CMLAtom extensionAtom, CMLAtom replacingAtom) {
moveLabelFromStaticAtomToGroup(replacedAtom, replacingAtom);
scaleAndMoveGroup(replacedAtomParent, subMolecule, replacingAtom);
CMLBond replacedBond = transferAtomsAndBondsFromGroup(molecule,
replacedAtom, replacedAtomParent, subMolecule, extensionAtom,
replacingAtom);
createAndAddNewBond(molecule, replacedAtomParent, replacingAtom,
replacedBond);
}
private void createAndAddNewBond(CMLMolecule molecule,
CMLAtom replacedAtomParent, CMLAtom replacingAtom,
CMLBond replacedBond) {
if (replacedBond != null) {
CMLBondStereo bondStereo = replacedBond.getBondStereo();
String order = replacedBond.getOrder();
if (replacedAtomParent != null) {
// make new bond and copy properties
CMLBond newBond = new CMLBond();
newBond.setAtomRefs2(new String[]{replacedAtomParent.getId(), replacingAtom.getId()});
if (bondStereo != null) {
newBond.addBondStereo(bondStereo);
}
newBond.setOrder(order);
molecule.addBond(newBond);
}
}
}
private CMLBond transferAtomsAndBondsFromGroup(CMLMolecule molecule,
CMLAtom replacedAtom, CMLAtom replacedAtomParent,
CMLMolecule subMolecule, CMLAtom extensionAtom,
CMLAtom replacingAtom) {
CMLBond replacedBond = molecule.getBond(replacedAtom, replacedAtomParent);
CMLBond extensionBond = subMolecule.getBond(extensionAtom, replacingAtom);
// delete everything from subMolecule
// delete bonds first
List subMoleculeBonds = subMolecule.getBonds();
List subMoleculeAtoms = subMolecule.getAtoms();
for (CMLBond subMoleculeBond : subMoleculeBonds) {
subMolecule.deleteBond(subMoleculeBond);
}
for (CMLAtom subMoleculeAtom : subMoleculeAtoms) {
subMolecule.deleteAtom(subMoleculeAtom);
}
// replace bonds in target
molecule.deleteBond(replacedBond);
molecule.deleteAtom(replacedAtom);
// transfer atoms
for (CMLAtom subMoleculeAtom : subMoleculeAtoms) {
if (subMoleculeAtom.equals(extensionAtom)) {
continue;
}
molecule.addAtom(subMoleculeAtom);
}
// and bonds
for (CMLBond subMoleculeBond : subMoleculeBonds) {
if (subMoleculeBond.equals(extensionBond)) {
continue;
}
molecule.addBond(subMoleculeBond);
}
return replacedBond;
}
private void moveLabelFromStaticAtomToGroup(CMLAtom replacedAtom,
CMLAtom replacingAtom) {
Nodes labelNodes = replacedAtom.query("./cml:label", CMLConstants.CML_XPATH);
CMLLabel label = (labelNodes.size() >= 1) ? (CMLLabel) labelNodes.get(0) : null;
if (label != null) {
label.detach();
replacingAtom.addLabel(label);
}
}
private void scaleAndMoveGroup(CMLAtom replacedAtomParent,
CMLMolecule subMolecule, CMLAtom replacingAtom) {
if (replacedAtomParent != null) {
Real2 replacedXY2 = replacedAtomParent.getXY2();
Real2 replacingXY2 = replacingAtom.getXY2();
Vector2 bondVector = new Vector2(replacedXY2.subtract(replacingXY2));
bondVector = new Vector2(bondVector.multiplyBy(SCALE_GROUPS));
Real2 newXY2 = replacingXY2.plus(bondVector);
subMolecule.multiply2DCoordsBy(SCALE_GROUPS);
Real2 newReplacingXY2 = replacingAtom.getXY2();
Vector2 translateXY2 = new Vector2(newXY2.subtract(newReplacingXY2));
subMolecule.translate2D(translateXY2);
}
}
};
© 2015 - 2025 Weber Informatics LLC | Privacy Policy