org.xmlcml.cml.tools.ReactionBondChange 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.Map;
import org.xmlcml.cml.element.CMLAtom;
import org.xmlcml.cml.element.CMLBond;
import org.xmlcml.cml.element.CMLBondSet;
import org.xmlcml.cml.graphics.SVGAnimate;
import org.xmlcml.cml.graphics.SVGElement;
import org.xmlcml.cml.graphics.SVGG;
import org.xmlcml.cml.graphics.SVGLine;
public class ReactionBondChange extends ReactionChange {
CMLBond reactantBond = null;
CMLBond productBond = null;
private String reactantOrder;
private String productOrder;
private CMLAtom[] reactantAtom = new CMLAtom[2];
private CMLAtom[] productAtom = new CMLAtom[2];
private ReactionAtomChange[] reactionAtomChange = new ReactionAtomChange[2];
private ReactionBondChange(CMLBond reactantBond, CMLBond productBond) {
setDefaults();
this.reactantBond = reactantBond;
this.productBond = productBond;
getBondProperties(reactantBond, productBond);
}
private void setDefaults() {
}
private void getBondProperties(CMLBond reactantBond, CMLBond productBond) {
reactantOrder = getNormalizedOrder(reactantBond);
productOrder = getNormalizedOrder(productBond);
reactantAtom[0] = (reactantBond == null) ? null : reactantBond.getAtom(0);
reactantAtom[1] = (reactantBond == null) ? null : reactantBond.getAtom(1);
productAtom[0] = (productBond == null) ? null : productBond.getAtom(0);
productAtom[1] = (productBond == null) ? null : productBond.getAtom(1);
reactionAtomChange[0] = ReactionAtomChange.getReactionAtomChange(reactantAtom[0], productAtom[0]);
reactionAtomChange[1] = ReactionAtomChange.getReactionAtomChange(reactantAtom[1], productAtom[1]);
reactantOccupancy = isZero(reactantOrder) ? 0.0 : 1.0;
productOccupancy = isZero(productOrder) ? 0.0 : 1.0;
reactantElectrons = ElectronTool.getElectronCount(reactantBond, ElectronTool.ELECTRONS);
productElectrons = ElectronTool.getElectronCount(productBond, ElectronTool.ELECTRONS);
}
private String getNormalizedOrder(CMLBond bond) {
String order = bond.getOrder();
if (order == null) {
order = CMLBond.UNKNOWN_ORDER;
}
return order;
}
public static ReactionBondChange getReactionBondChange(
CMLBond reactantBond, CMLBond productBond) {
if (reactantBond == null && productBond == null) {
return null;
}
ReactionBondChange bondChange = new ReactionBondChange(reactantBond, productBond);
if (bondChange.hasChange()) {
return bondChange;
} else {
return null;
}
}
boolean hasDisplayChange() {
return hasTypeChange() || hasOccupancyChange();
}
boolean hasTypeChange() {
return hasNormalOrderChange();
}
boolean hasOccupancyChange() {
return isZero(reactantOrder) || isZero(productOrder);
}
private boolean hasChange() {
return hasTypeChange() ||
reactionAtomChange[0] != null && reactionAtomChange[0].hasXY2Change() ||
reactionAtomChange[1] != null && reactionAtomChange[1].hasXY2Change();
}
private boolean hasNormalOrderChange() {
return !reactantOrder.equals(productOrder);
}
public void applyAnimation(SVGElement svgReactant, SVGElement svgProduct) {
if (hasOccupancyChange()) {
if (reactantOccupancy > productOccupancy) {
svgProduct.detach();
svgProduct = null;
animateOpacity(svgReactant, reactantOccupancy, productOccupancy);
} else {
svgReactant.detach();
svgReactant = null;
animateOpacity(svgProduct, reactantOccupancy, productOccupancy);
}
} else {
if (hasTypeChange()) {
animateOpacity(svgReactant, 1.0, 0.0);
animateOpacity(svgProduct, 0.0, 1.0);
}
}
animateBondEnd(0, svgReactant, svgProduct);
animateBondEnd(1, svgReactant, svgProduct);
}
private void animateBondEnd(int bondEnd, SVGElement svgReactant, SVGElement svgProduct) {
ReactionAtomChange atomChange = reactionAtomChange[bondEnd];
if (atomChange != null && atomChange.hasXY2Change()) {
animateXY2ForNonNullElement(atomChange, bondEnd, svgReactant);
if (svgProduct != null) {
animateXY2ForNonNullElement(atomChange, bondEnd, svgProduct);
}
}
}
private void animateXY2ForNonNullElement(ReactionChange atomChange, int bondEnd, SVGElement svgComponent) {
if (svgComponent != null) {
for (int i = 0; i < svgComponent.getChildCount(); i++) {
SVGElement childElement = (SVGElement) svgComponent.getChildElements().get(i);
if (childElement.getLocalName().equals(SVGLine.TAG)) {
addAnimateChild(atomChange, SVGElement.X+(bondEnd+1),
atomChange.reactantXY.getX(), atomChange.productXY.getX(), childElement);
addAnimateChild(atomChange, SVGElement.Y+(bondEnd+1),
atomChange.reactantXY.getY(), atomChange.productXY.getY(), childElement);
}
}
}
}
private void addAnimateChild(ReactionChange atomChange, String coordName, double coord0, double coord1,
SVGElement svgComponent) {
SVGAnimate svgAnimate = new SVGAnimate();
svgAnimate.setFill(SVGAnimate.FREEZE);
svgAnimate.setAttribute(coordName, coord0, coord1);
svgComponent.appendChild(svgAnimate);
}
private boolean isZero(String order) {
return order == null || order.equals("") || order.equals(CMLBond.ZERO);
}
static Map addBondChangeById(CMLBondSet productBondSet, CMLBondSet reactantBondSet) {
Map bondChangeById = new HashMap();
addBondChangeByProductId(bondChangeById, productBondSet, reactantBondSet);
addBondChangeByReactantId(bondChangeById, productBondSet, reactantBondSet);
return bondChangeById;
}
private static void addBondChangeByReactantId(Map bondChangeById,
CMLBondSet productBondSet, CMLBondSet reactantBondSet) {
for (CMLBond reactantBond : reactantBondSet.getBonds()) {
String reactantId = reactantBond.getId();
CMLBond productBond = productBondSet.getBondById(reactantId);
if (!bondChangeById.containsKey(reactantId)) {
bondChangeById.put(reactantId,
ReactionBondChange.getReactionBondChange(reactantBond, productBond));
}
}
}
private static void addBondChangeByProductId(Map bondChangeById,
CMLBondSet productBondSet, CMLBondSet reactantBondSet) {
for (CMLBond productBond : productBondSet.getBonds()) {
String productId = productBond.getId();
CMLBond reactantBond = reactantBondSet.getBondById(productId);
bondChangeById.put(productId,
ReactionBondChange.getReactionBondChange(reactantBond, productBond));
}
}
public SVGElement createAndAddReactantDisplay(SVGG g, MoleculeDisplayList displayList) {
SVGElement svgReactant = createSVGElement(PRODUCT_P, this.reactantBond, displayList);
if ((productBond == null || this.hasDisplayChange()) && svgReactant != null) {
g.appendChild(svgReactant);
}
return svgReactant;
}
public SVGElement createAndAddProductDisplay(SVGG g, MoleculeDisplayList displayList) {
SVGElement svgProduct = createSVGElement(PRODUCT_P, this.productBond, displayList);
if ((productBond == null || this.hasDisplayChange()) && svgProduct != null) {
g.appendChild(svgProduct);
}
return svgProduct;
}
public static SVGElement createSVGElement(String type, CMLBond bond, MoleculeDisplayList displayList) {
SVGElement bondElement = BondTool.getOrCreateTool(bond).createGraphicsElement(displayList);
if (bondElement != null) {
bondElement.setId(type+"_"+bond.getId());
}
return bondElement;
}
public void processElectrons() {
// System.err.println("BB "+this.reactantBond.getId());
if (this.hasElectronChange()) {
System.err.println(this.reactantBond.getId()+": ...bond e "+this.getElectronChange());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy