org.openscience.cdk.geometry.cip.rules.CIPLigandRule2 Maven / Gradle / Ivy
package org.openscience.cdk.geometry.cip.rules;
import java.util.Arrays;
import org.openscience.cdk.geometry.cip.CIPTool;
import org.openscience.cdk.geometry.cip.CIPToolMod;
import org.openscience.cdk.geometry.cip.ILigand;
/**
* This class does the same as {@link CIPLigandRule2} only it also orders
* sub-ligands based on its own rule rather than based on the {@link CombinedAtomicMassNumberRule}
* order. This fixes a CDK bug detailed in {@link CIPToolMod}.
* @author tyler
*
*/
public class CIPLigandRule2 implements ISequenceSubRule {
CombinedAtomicMassNumberRule numberRule = new CombinedAtomicMassNumberRule();
/** {@inheritDoc} */
@Override
public int compare(ILigand ligand1, ILigand ligand2) {
int numberComp = numberRule.compare(ligand1, ligand2);
if (numberComp != 0) return numberComp;
// OK, now I need to recurse...
ILigand[] ligand1Ligands = CIPTool.getLigandLigands(ligand1);
ILigand[] ligand2Ligands = CIPTool.getLigandLigands(ligand2);
// if neither have ligands:
if (ligand1Ligands.length == 0 && ligand2Ligands.length == 0) return 0;
// else if one has no ligands
if (ligand1Ligands.length == 0) return -1;
if (ligand2Ligands.length == 0) return 1;
// ok, both have at least one ligand
int minLigandCount = Math.min(ligand1Ligands.length, ligand2Ligands.length);
if (ligand1Ligands.length > 1) ligand1Ligands = order(ligand1Ligands);
if (ligand2Ligands.length > 1) ligand2Ligands = order(ligand2Ligands);
// first do a basic number rule
for (int i = 0; i < minLigandCount; i++) {
int comparison = numberRule.compare(ligand1Ligands[i], ligand2Ligands[i]);
if (comparison != 0) return comparison;
}
if (ligand1Ligands.length == ligand2Ligands.length) {
// it that does not resolve it, do a full, recursive compare
for (int i = 0; i < minLigandCount; i++) {
int comparison = compare(ligand1Ligands[i], ligand2Ligands[i]);
if (comparison != 0) return comparison;
}
}
// OK, if we reached this point, then the ligands they 'share' are all equals, so the one
// with more ligands wins
if (ligand1Ligands.length > ligand2Ligands.length)
return 1;
else if (ligand1Ligands.length < ligand2Ligands.length)
return -1;
else
return 0;
}
/**
* Order the ligands from high to low precedence according to atomic and mass numbers.
*/
private ILigand[] order(ILigand[] ligands) {
ILigand[] newLigands = new ILigand[ligands.length];
System.arraycopy(ligands, 0, newLigands, 0, ligands.length);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//THIS IS THE ONLY LINE OF CODE THAT NEEDS TO BE CHANGED
//FOR CDK CIP TO WORK
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Arrays.sort(newLigands, this);
// this above list is from low to high precendence, so we need to revert the array
ILigand[] reverseLigands = new ILigand[newLigands.length];
for (int i = 0; i < newLigands.length; i++) {
reverseLigands[(newLigands.length - 1) - i] = newLigands[i];
}
return reverseLigands;
}
}