All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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;
        }

    }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy