From: <eg...@us...> - 2008-07-01 07:55:29
|
Revision: 11474 http://cdk.svn.sourceforge.net/cdk/?rev=11474&view=rev Author: egonw Date: 2008-07-01 00:55:15 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Removed the deterministics structure generator; it never functioned properly Modified Paths: -------------- cdk/trunk/META-INF/MANIFEST.MF cdk/trunk/src/test/org/openscience/cdk/modulesuites/MstructgenTests.java Removed Paths: ------------- cdk/trunk/src/main/org/openscience/cdk/structgen/deterministic/EquivalentClassesDeterministicGenerator.java cdk/trunk/src/main/org/openscience/cdk/structgen/deterministic/GENMDeterministicGenerator.java cdk/trunk/src/main/org/openscience/cdk/structgen/deterministic/Graph.java cdk/trunk/src/test/org/openscience/cdk/structgen/deterministic/EquivalentClassesDeterministicGeneratorTest.java cdk/trunk/src/test/org/openscience/cdk/structgen/deterministic/GENMDeterministicGeneratorTest.java cdk/trunk/src/test/org/openscience/cdk/structgen/deterministic/structuregenerator.html Modified: cdk/trunk/META-INF/MANIFEST.MF =================================================================== --- cdk/trunk/META-INF/MANIFEST.MF 2008-06-30 18:45:26 UTC (rev 11473) +++ cdk/trunk/META-INF/MANIFEST.MF 2008-07-01 07:55:15 UTC (rev 11474) @@ -101,7 +101,6 @@ org.openscience.cdk.smiles.smarts.parser, org.openscience.cdk.smiles.smarts.parser.visitor, org.openscience.cdk.structgen, - org.openscience.cdk.structgen.deterministic, org.openscience.cdk.structgen.stochastic, org.openscience.cdk.structgen.stochastic.operator, org.openscience.cdk.templates, Deleted: cdk/trunk/src/main/org/openscience/cdk/structgen/deterministic/EquivalentClassesDeterministicGenerator.java =================================================================== --- cdk/trunk/src/main/org/openscience/cdk/structgen/deterministic/EquivalentClassesDeterministicGenerator.java 2008-06-30 18:45:26 UTC (rev 11473) +++ cdk/trunk/src/main/org/openscience/cdk/structgen/deterministic/EquivalentClassesDeterministicGenerator.java 2008-07-01 07:55:15 UTC (rev 11474) @@ -1,79 +0,0 @@ -/* $Revision$ $Author$ $Date$ - * - * Copyright (C) 1997-2007 The Chemistry Development Kit (CDK) project - * - * Contact: cdk...@li... - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - */ -package org.openscience.cdk.structgen.deterministic; - -import java.util.ArrayList; -import java.util.List; - -import org.openscience.cdk.interfaces.IAtom; -import org.openscience.cdk.interfaces.IAtomContainer; -import org.openscience.cdk.tools.LoggingTool; - -/** - * An implementation of Faulons equivalent classes deterministic generator. - * - * @author steinbeck - * @cdk.created 2000-10-02 - * @cdk.module structgen - * @cdk.svnrev $Revision$ - */ -public class EquivalentClassesDeterministicGenerator { - - LoggingTool logger = new LoggingTool(EquivalentClassesDeterministicGenerator.class); - - /* The initial, unbonded AtomContainer - * From this we construct a number of AtomContainers that contain the - * initial heavy atoms with assigned hydrogen counts. - */ - IAtomContainer baseAtomContainer = null; - List graphs = null; - - public EquivalentClassesDeterministicGenerator() - { - Graph graph = new Graph(); - graphs = new ArrayList(); - graphs.add(graph); - } - - public void setAtomContainer(IAtomContainer ac) { - baseAtomContainer = ac; - initGraph(); - logger.debug("Number of classes after initialization: ", ((Graph)graphs.get(0)).size()); - } - - private void initGraph() - { - IAtomContainer ac = null; - IAtom atom = null; - Graph graph = (Graph)graphs.get(0); - for (int f = 0; f < baseAtomContainer.getAtomCount(); f++) - { - ac = baseAtomContainer.getBuilder().newAtomContainer(); - atom = baseAtomContainer.getAtom(f); - ac.addAtom(atom); - ac.setProperty("class", new Integer(atom.getHydrogenCount())); - graph.add(ac); - } - graph.partition(); - logger.debug("Number of initial distinct classes: ", graph.getNumberOfClasses()); - } - -} Deleted: cdk/trunk/src/main/org/openscience/cdk/structgen/deterministic/GENMDeterministicGenerator.java =================================================================== --- cdk/trunk/src/main/org/openscience/cdk/structgen/deterministic/GENMDeterministicGenerator.java 2008-06-30 18:45:26 UTC (rev 11473) +++ cdk/trunk/src/main/org/openscience/cdk/structgen/deterministic/GENMDeterministicGenerator.java 2008-07-01 07:55:15 UTC (rev 11474) @@ -1,2932 +0,0 @@ -/* $Revision$ $Author$ $Date$ - * - * Copyright (C) 2004-2007 Junfeng Hao - * - * Contact: cdk...@li... - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - */ -package org.openscience.cdk.structgen.deterministic; - -import java.io.FileWriter; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; - -import org.openscience.cdk.formula.MolecularFormulaManipulator; -import org.openscience.cdk.interfaces.IAtomContainer; -import org.openscience.cdk.interfaces.IBond; -import org.openscience.cdk.interfaces.IChemObjectBuilder; -import org.openscience.cdk.interfaces.IMolecularFormula; -import org.openscience.cdk.interfaces.IMolecule; -import org.openscience.cdk.nonotify.NoNotificationChemObjectBuilder; -import org.openscience.cdk.structgen.IStructureGenerationListener; -import org.openscience.cdk.tools.LoggingTool; - - -/** - * An adapted implementation of the Molodtsov structure generator. - * Changes to the original idea include issues of - * normalization and strong canonicity criteria - * - * <pre> - * gdg = new GENMDeterministicGenerator(formula,""); - * gdg.addListener(this); - * gdg.setStructuresAtATime(500); - * gdg.generate(); - * </pre> - * - * <p>Please note that the number of isomers generated by this generator can quickly - * become quite large and their storage in memory will take some space. - * In order to handle to large amount of potential data, the generator hands you the - * structures in small packets. You register with the generator as a - * StructureGeneratorListener. In the respective stateChanged() method which you - * must implement, you can do with the latest list of generated structures - * whatever you want. Please not that the generatore deletes things internally - * after handing over the list. Make sure to remove reference to structure in - * which you are not interested anymore, to the garbage collector can clean them up. - * - * <p>If no StructureGeneratorListener is registered, the generator will not store - * the molecular structures, and only count them. The total number of constitutional - * isomers can be calculated with: - * <pre> - * gdg = new GENMDeterministicGenerator(formula,""); - * gdg.generate(); - * int isomerCount = gdg.getNumberOfStructure(); - * </pre> - * - * <p>Details are found in the following papers - * {@cdk.cite Molodtsov94, Molchanova96, Hu94, Hu94b, Hu99}. - * - * @author Junfeng Hao - * @author Christoph Steinbeck - * @cdk.created 2004-02-16 - * @cdk.module structgen - * @cdk.svnrev $Revision$ - * @cdk.bug 1678346 - * @cdk.bug 1743861 - * @cdk.bug 1744463 - */ -public class GENMDeterministicGenerator { - - private LoggingTool logger; - - private int numberOfSetFragment; - private int numberOfStructures; - private IAtomContainer atomContainer; - private int[] molecularFormula; - private int[] numberOfBasicUnit; - private int[] numberOfBasicFragment; - private List basicFragment; - private List structures; - private PrintWriter structureout; - private long returnedStructureCount = 500; - private static double LOST=0.000000000001; - private List listeners = null; - boolean hasMoreStructures = false; - int structuresAtATime = 500; - - private IChemObjectBuilder builder = null; - - /** - * Constructor for the GENMDeterministicGenerator. - * Allows for setting the molecular formula for which the - * isomers are to be generated as well as for setting an output path - * for a file with generated structures. - * - * @param mf molecular formula string - * @param path Path to the file used for writing structures. Leave blank if current directory should be used. - * If set to null then no structure file is written. - */ - public GENMDeterministicGenerator(String mf, String path) throws Exception - { - logger = new LoggingTool(GENMDeterministicGenerator.class); - builder = NoNotificationChemObjectBuilder.getInstance(); - - numberOfSetFragment=0; - numberOfStructures=0; - logger.debug(mf); - molecularFormula=new int[12]; - numberOfBasicUnit=new int[23]; - numberOfBasicFragment=new int[34]; - basicFragment=new ArrayList(); - structures=new ArrayList(); - listeners = new ArrayList(); - - if (path != null) structureout=new PrintWriter(new FileWriter(path+"structuredata.txt"),true); - else structureout = null; - - initializeParameters(); - analyseMolecularFormula(MolecularFormulaManipulator.getMolecularFormula(mf, builder)); - - } - - /** - * Central method of this Generator. Call - * - * @throws Exception - */ - public void generate() throws Exception - { - numberOfStructures = 0; - generateBasicUnits(); - logger.debug("numberofstructure is=", numberOfStructures); - fireChange(); - - } - - - public void setBasicUnits(List basicUnits) - { - if(basicUnits!=null)getBasicUnit(basicUnits); - else - logger.error("input false"); - } - - /** - * Get basic units from input information. - * - * @param basicUnits vector contains basic units which stored as string - */ - public void getBasicUnit(List basicUnits) - { - int i; - for(i=0;i<basicUnits.size();i++) - { - String s=(String)basicUnits.get(i); - if(s.equals("Si"))numberOfBasicUnit[1]+=1; - else if(s.equals("P"))numberOfBasicUnit[2]+=1; - else if(s.equals("S"))numberOfBasicUnit[3]+=1; - else if(s.equals("N"))numberOfBasicUnit[4]+=1; - else if(s.equals("O"))numberOfBasicUnit[5]+=1; - else if(s.equals("C"))numberOfBasicUnit[6]+=1; - else if(s.equals("SiH3"))numberOfBasicUnit[7]+=1; - else if(s.equals("SiH2"))numberOfBasicUnit[8]+=1; - else if(s.equals("SiH"))numberOfBasicUnit[9]+=1; - else if(s.equals("PH2"))numberOfBasicUnit[10]+=1; - else if(s.equals("PH"))numberOfBasicUnit[11]+=1; - else if(s.equals("SH"))numberOfBasicUnit[12]+=1; - else if(s.equals("NH2"))numberOfBasicUnit[13]+=1; - else if(s.equals("NH"))numberOfBasicUnit[14]+=1; - else if(s.equals("OH"))numberOfBasicUnit[15]+=1; - else if(s.equals("CH3"))numberOfBasicUnit[16]+=1; - else if(s.equals("CH2"))numberOfBasicUnit[17]+=1; - else if(s.equals("CH"))numberOfBasicUnit[18]+=1; - else - logger.error("input error"); - } - } - - - /** - * Initialize the basic fragment. For the definition, please see the BasicFragment class. - */ - public void initializeParameters() throws java.lang.Exception - { - - basicFragment.add(new BasicFragment(1,4,1,0,1,">C<","C")); - basicFragment.add(new BasicFragment(2,3,102,0,2,">C=","C")); - basicFragment.add(new BasicFragment(3,2,2,0,3,"=C=","C")); - basicFragment.add(new BasicFragment(4,2,103,0,4,"-C#","C")); - basicFragment.add(new BasicFragment(5,3,1,1,5,">CH-","C")); - basicFragment.add(new BasicFragment(6,2,102,1,6,"=CH-","C")); - basicFragment.add(new BasicFragment(7,1,3,1,6,"CH#","C")); - basicFragment.add(new BasicFragment(8,3,1,0,8,">N-","N")); - basicFragment.add(new BasicFragment(9,2,102,0,9,"=N-","N")); - basicFragment.add(new BasicFragment(10,1,3,0,10,"N#","N")); - basicFragment.add(new BasicFragment(11,2,1,2,11,"-CH2-","C")); - basicFragment.add(new BasicFragment(12,1,2,2,12,"CH2=","C")); - - basicFragment.add(new BasicFragment(13,2,1,1,13,"-NH-","N")); - basicFragment.add(new BasicFragment(14,1,2,1,14,"NH=","N")); - basicFragment.add(new BasicFragment(15,2,1,0,15,"-O-","O")); - basicFragment.add(new BasicFragment(16,1,2,0,16,"O=","O")); - basicFragment.add(new BasicFragment(17,2,1,0,17,"-S-","S")); - basicFragment.add(new BasicFragment(18,1,2,0,18,"S=","S")); - basicFragment.add(new BasicFragment(19,1,1,3,19,"CH3-","C")); - basicFragment.add(new BasicFragment(20,1,1,2,20,"NH2-","N")); - basicFragment.add(new BasicFragment(21,1,1,1,21,"OH-","O")); - basicFragment.add(new BasicFragment(22,1,1,1,22,"-SH","S")); - basicFragment.add(new BasicFragment(23,3,1,0,23,">P-","P")); - basicFragment.add(new BasicFragment(24,2,1,1,24,"-PH-","P")); - basicFragment.add(new BasicFragment(25,1,1,2,25,"PH2-","P")); - basicFragment.add(new BasicFragment(26,4,1,0,26,">Si<","Si")); - basicFragment.add(new BasicFragment(27,3,1,1,26,">SiH-","Si")); - basicFragment.add(new BasicFragment(28,2,1,2,28,"-SiH2-","Si")); - basicFragment.add(new BasicFragment(29,1,1,3,29,"SiH3-","Si")); - basicFragment.add(new BasicFragment(30,1,1,0,30,"F-","F")); - basicFragment.add(new BasicFragment(31,1,1,0,31,"Cl-","Cl")); - basicFragment.add(new BasicFragment(32,1,1,0,32,"Br-","Br")); - basicFragment.add(new BasicFragment(33,1,1,0,33,"I-","I")); - - /*for decompose the complex fragment*/ - - basicFragment.add(new BasicFragment(42,2,1,0,2,">C","C")); - basicFragment.add(new BasicFragment(43,1,2,0,2,"C=","C")); - - - basicFragment.add(new BasicFragment(44,1,1,0,4,"C-","C")); - basicFragment.add(new BasicFragment(45,1,3,0,4,"C#","C")); - - - basicFragment.add(new BasicFragment(46,1,1,1,6,"CH-","C")); - basicFragment.add(new BasicFragment(47,1,2,1,6,"CH=","C")); - - - basicFragment.add(new BasicFragment(50,1,1,0,9,"N-","N")); - basicFragment.add(new BasicFragment(51,1,2,0,9,"N=","N")); - //Maybe add later - return; - } - - /** - * Analyse molecular formula to verify it is valid. - * - * @param mfa MFAnalyser object to operate the molecular formula - */ - public void analyseMolecularFormula(IMolecularFormula formula) throws java.lang.Exception - { - molecularFormula[1]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("C")); - molecularFormula[2]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("H")); - molecularFormula[3]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("O")); - molecularFormula[4]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("N")); - molecularFormula[5]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("S")); - molecularFormula[6]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("P")); - molecularFormula[7]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("Si")); - molecularFormula[8]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("F")); - molecularFormula[9]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("Cl")); - molecularFormula[10]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("Br")); - molecularFormula[11]= MolecularFormulaManipulator.getElementCount(formula, builder.newElement("I")); - - molecularFormula[0]=2*molecularFormula[1]+molecularFormula[4]+molecularFormula[6]+ - 2*molecularFormula[7]+2-molecularFormula[2]-molecularFormula[8]-molecularFormula[9]- - molecularFormula[10]-molecularFormula[11]; - if(molecularFormula[0]<0) - { - logger.debug("Input molecular formula error!"); - } - - // for(i=1;i<=11;i++) - // logger.debug("molecularFormula["+i+"]="+molecularFormula[i]); - - - return; - } - - /** - * The first step: generate sets of basic units by backtracking algorithm. - */ - public void generateBasicUnits() throws java.lang.Exception - { - int[] maxNumberOfBasicUnit=new int[23]; - int i,j,k; - int iter1,iter2,iter3,iter4; - int numberSi,numberP,numberS,numberN,numberNH; // numberSiH,numberSH,numberPH - int numberO,numberOH,numberCH,numberH; - int basicUnit; - - /* Generate the maximum number of basic units based on molecular formula. The corresponding - basic units is Si,P,S,N,O,C,SiH3,SiH2,SiH,PH2,PH,SH,NH2,NH,OH,CH3,CH2,CH,F,Cl,Br,I. We could - get the basic units directly for F,Cl,Br,I as they do not contain hydrogen atoms.*/ - maxNumberOfBasicUnit[1]=molecularFormula[7];//Si - maxNumberOfBasicUnit[2]=molecularFormula[6];//P - maxNumberOfBasicUnit[3]=molecularFormula[5];//S - maxNumberOfBasicUnit[4]=molecularFormula[4];//N - maxNumberOfBasicUnit[5]=molecularFormula[3];//O - maxNumberOfBasicUnit[6]=molecularFormula[1];//C - maxNumberOfBasicUnit[7]=molecularFormula[7];//SiH3 - maxNumberOfBasicUnit[8]=molecularFormula[7];//SiH2 - maxNumberOfBasicUnit[9]=molecularFormula[7];//SiH - maxNumberOfBasicUnit[10]=molecularFormula[6];//PH2 - maxNumberOfBasicUnit[11]=molecularFormula[6];//PH - maxNumberOfBasicUnit[12]=molecularFormula[5];//SH - maxNumberOfBasicUnit[13]=molecularFormula[4];//NH2 - maxNumberOfBasicUnit[14]=molecularFormula[4];//NH - maxNumberOfBasicUnit[15]=molecularFormula[3];//OH - maxNumberOfBasicUnit[16]=molecularFormula[1];//CH3 - maxNumberOfBasicUnit[17]=molecularFormula[1];//CH2 - maxNumberOfBasicUnit[18]=molecularFormula[1];//CH - - /* for CH3, CH2 the number of H should be consider at the same time*/ - i=molecularFormula[2]; - j=i/3; - k=i/2; - if(maxNumberOfBasicUnit[16]>j)maxNumberOfBasicUnit[16]=j; - if(maxNumberOfBasicUnit[17]>k)maxNumberOfBasicUnit[17]=k; - - /* initialization */ - for(i=1;i<=22;i++)numberOfBasicUnit[i]=0; - numberSi=0; - //numberSiH=0; - numberP=0; - //numberPH=0; - numberS=0; - //numberSH=0; - numberN=0; - numberNH=0; - numberO=0; - numberOH=0; - numberCH=0; - numberH=0; - basicUnit=0; - - /* to distribute the hydrogen into heavy atoms. It is easily to see that only the basic - units which contain hydrogens need to be considered. Therefore */ - iter1=6; - iter2=18; - do - { - iter1++; - while(iter1<iter2) - { - numberOfBasicUnit[iter1]=0; - switch(iter1-1) - { - case 9: - numberSi=numberOfBasicUnit[7]+numberOfBasicUnit[8]+numberOfBasicUnit[9]; - //numberSiH=numberSi+2*numberOfBasicUnit[7]+numberOfBasicUnit[8]; - break; - case 11: - numberP=numberOfBasicUnit[10]+numberOfBasicUnit[11]; - //numberPH=numberSiH+numberP+numberOfBasicUnit[10]; - break; - case 12: - numberS=numberOfBasicUnit[12]; - //numberSH=numberPH+numberS; - break; - case 14: - numberN=numberOfBasicUnit[13]+numberOfBasicUnit[14]; - numberNH=numberS+numberN+numberOfBasicUnit[13]; - break; - case 15: - numberO=numberOfBasicUnit[15]; - numberOH=numberNH+numberO; - break; - } - iter1++; - } - - do - { - /* begin from CH*/ - numberCH=numberOH+3*numberOfBasicUnit[16]+2*numberOfBasicUnit[17]; - numberH=molecularFormula[2]-numberCH;//left number of hydrogen atoms - if(numberH>maxNumberOfBasicUnit[18])break; - if(numberH<0)break; - numberOfBasicUnit[18]=numberH; - - /* for Si */ - numberOfBasicUnit[1]=molecularFormula[7]-numberSi; - if(numberOfBasicUnit[1]>maxNumberOfBasicUnit[1])break; - if(numberOfBasicUnit[1]<0)break; - - /* for P */ - numberOfBasicUnit[2]=molecularFormula[6]-numberP; - if(numberOfBasicUnit[2]>maxNumberOfBasicUnit[2])break; - if(numberOfBasicUnit[2]<0)break; - - /* for S */ - numberOfBasicUnit[3]=molecularFormula[5]-numberS; - if(numberOfBasicUnit[3]>maxNumberOfBasicUnit[3])break; - if(numberOfBasicUnit[3]<0)break; - - /* for N */ - numberOfBasicUnit[4]=molecularFormula[4]-numberN; - if(numberOfBasicUnit[4]>maxNumberOfBasicUnit[4])break; - if(numberOfBasicUnit[4]<0)break; - - /* for O */ - numberOfBasicUnit[5]=molecularFormula[3]-numberO; - if(numberOfBasicUnit[5]>maxNumberOfBasicUnit[5])break; - if(numberOfBasicUnit[5]<0)break; - - /* for C */ - numberOfBasicUnit[6]=molecularFormula[1]-numberOfBasicUnit[16]-numberOfBasicUnit[17]-numberOfBasicUnit[18]; - if(numberOfBasicUnit[6]>maxNumberOfBasicUnit[6])break; - if(numberOfBasicUnit[6]<0)break; - - - basicUnit+=1; - numberOfBasicUnit[0]=basicUnit; - /* for F,Cl,Br,I */ - for(i=19;i<=22;i++) - if(molecularFormula[i-11]!=0)numberOfBasicUnit[i]=molecularFormula[i-11]; - if (logger.isDebugEnabled()) { - for(i=0;i<=22;i++) { - if(numberOfBasicUnit[i]!=0) { - logger.debug("numberOfBasicUnit["+i+"]="+numberOfBasicUnit[i]); - logger.debug("numberOfBasicUnit["+i+"]="+numberOfBasicUnit[i]); - } - } - } - - /* If all the following judgement are satisfactory, it should be one set of basic unit.Output them*/ - generateBasicFragments(); - }while(false); - - /* exit from the distribution hydrogen, backtracking*/ - do - { - iter1-=1; - if(iter1==6)return; - if(numberOfBasicUnit[iter1]>=maxNumberOfBasicUnit[iter1])continue; - - do - { - numberOfBasicUnit[iter1]+=1; - if(iter1==7)//SiH3 - { - iter3=numberOfBasicUnit[7]; - if(iter3>molecularFormula[7])break; - } - else if(iter1==8)//SiH2 - { - iter3=numberOfBasicUnit[7]+numberOfBasicUnit[8]; - if(iter3>molecularFormula[7])break; - } - else if(iter1==9)//SiH2 - { - iter3=numberOfBasicUnit[7]+numberOfBasicUnit[8]+numberOfBasicUnit[9]; - if(iter3>molecularFormula[7])break; - } - else if(iter1==10)//PH2 - { - iter3=numberOfBasicUnit[10]; - if(iter3>molecularFormula[6])break; - } - else if(iter1==11)//PH - { - iter3=numberOfBasicUnit[10]+numberOfBasicUnit[11]; - if(iter3>molecularFormula[6])break; - } - else if(iter1==13)//NH2 - { - iter3=numberOfBasicUnit[13]; - if(iter3>molecularFormula[4])break; - } - else if(iter1==14)//NH - { - iter3=numberOfBasicUnit[13]+numberOfBasicUnit[14]; - if(iter3>molecularFormula[4])break; - } - else if(iter1==16)//CH3 - { - iter3=numberOfBasicUnit[16]; - if(iter3>molecularFormula[1])break; - iter4=numberOH+3*numberOfBasicUnit[16]; - if(iter4>molecularFormula[2])break; - i=molecularFormula[2]-iter4; - j=molecularFormula[1]-iter3; - k=2*j; - if(i>k)continue; - else break; - } - else if(iter1==17)//CH2 - { - iter3=numberOfBasicUnit[16]+numberOfBasicUnit[17]; - if(iter3>molecularFormula[1])break; - iter4=numberOH+3*numberOfBasicUnit[16]+2*numberOfBasicUnit[17]; - if(iter4>molecularFormula[2])break; - i=molecularFormula[2]-iter4; - j=molecularFormula[1]-iter3; - if(i>j)continue; - else break; - } - else - { - break; - } - break; - }while(true); - break; - }while(true); - - }while(iter1>6); - return; - } - - - /** - * Second step: generate basic fragments, the generating rules from basic - * units are as follows. - * For carbon: - * <ul> - * <li>>C<, >C=,=C=,-C#(triple bond), 1~4 - * <li>CH: >CH-,=CH-,CH#, 5~7 - * <li>CH2: -CH2-,CH2=, 11~12 - * <li>CH3: CH3-,19 - * </ul> - * - * For nitrogen: - * <ul> - * <li>>N-,-N=,N#,8~10 - * <li>NH: -NH-, NH= ,13~14 - * <li>NH2: NH2-,20 - * </ul> - * - * For oxygen: - * <ul> - * <li>-O-,O=, 15~16 - * <li>OH: -OH, 21 - * </ul> - * - * For sulfur: - * <ul> - * <li>-S-,S=, 17~18 - * <li>SH, -SH,22 - * </ul> - * - * For phosphorus: - * <ul> - * <li>>P-, 23 - * <li>PH: -PH-,24 - * <li>PH2: -PH2,25 - * </ul> - * - * For silicon: - * <ul> - * <li>>Si< 26 - * <li>SiH: >SiH- 27 - * <li>SiH2: -SiH2- 28 - * <li>SiH3: SiH3- 29 - * </ul> - * - * For others: - * <ul> - * <li>F- 30 - * <li>Cl- 31 - * <li>Br- 32 - * <li>I- 33 - * </ul> - * It could be easily add the new fragments, such as valence, variable - * valence, such as N,P,also, fragments contains charges. - * It is a combinatorial algorithm, as in n1*n2*n3. - */ - public void generateBasicFragments() throws java.lang.Exception - { - int i,k; - int iter1; - boolean flag; - int[] maxNumberOfBasicFragment=new int[34]; - /*initialization for the variables*/ - if (logger.isDebugEnabled()) for(i=0;i<=22;i++) if(numberOfBasicUnit[i]!=0)logger.debug("numberOfBasicUnit["+i+"]=", numberOfBasicUnit[i]); - for(i=1;i<34;i++)numberOfBasicFragment[i]=0; - - /* maximum number of basic fragments*/ - maxNumberOfBasicFragment[1]=numberOfBasicUnit[6];//>C< - maxNumberOfBasicFragment[2]=numberOfBasicUnit[6];//>C= - maxNumberOfBasicFragment[3]=numberOfBasicUnit[6];//=C= - maxNumberOfBasicFragment[4]=numberOfBasicUnit[6];//-C# - - maxNumberOfBasicFragment[5]=numberOfBasicUnit[18];//>CH- - maxNumberOfBasicFragment[6]=numberOfBasicUnit[18];//=CH- - maxNumberOfBasicFragment[7]=numberOfBasicUnit[18];//CH# - - maxNumberOfBasicFragment[8]=numberOfBasicUnit[4];//>N- - maxNumberOfBasicFragment[9]=numberOfBasicUnit[4];//-N= - maxNumberOfBasicFragment[10]=numberOfBasicUnit[4];//N# - - maxNumberOfBasicFragment[11]=numberOfBasicUnit[17];//-CH2- - maxNumberOfBasicFragment[12]=numberOfBasicUnit[17];//CH2= - - maxNumberOfBasicFragment[13]=numberOfBasicUnit[14];//-NH- - maxNumberOfBasicFragment[14]=numberOfBasicUnit[14];//NH= - - maxNumberOfBasicFragment[15]=numberOfBasicUnit[5];//-O- - maxNumberOfBasicFragment[16]=numberOfBasicUnit[5];//O= - - maxNumberOfBasicFragment[17]=numberOfBasicUnit[3];//-S- - maxNumberOfBasicFragment[18]=numberOfBasicUnit[3];//S= - - numberOfBasicFragment[19]=numberOfBasicUnit[16]; - numberOfBasicFragment[20]=numberOfBasicUnit[13]; - numberOfBasicFragment[21]=numberOfBasicUnit[15]; - numberOfBasicFragment[22]=numberOfBasicUnit[12]; - numberOfBasicFragment[23]=numberOfBasicUnit[2]; - numberOfBasicFragment[24]=numberOfBasicUnit[11]; - numberOfBasicFragment[25]=numberOfBasicUnit[10]; - numberOfBasicFragment[26]=numberOfBasicUnit[1]; - numberOfBasicFragment[27]=numberOfBasicUnit[9]; - numberOfBasicFragment[28]=numberOfBasicUnit[8]; - numberOfBasicFragment[29]=numberOfBasicUnit[7]; - numberOfBasicFragment[30]=numberOfBasicUnit[19]; - numberOfBasicFragment[31]=numberOfBasicUnit[20]; - numberOfBasicFragment[32]=numberOfBasicUnit[21]; - numberOfBasicFragment[33]=numberOfBasicUnit[22]; - - iter1=17; - //iter2=0; - while(iter1>0) - { - iter1+=1; - - while(iter1<18) - { - numberOfBasicFragment[iter1]=0; - iter1+=1; - } - - do - { - numberOfBasicFragment[18]=numberOfBasicUnit[3]-numberOfBasicFragment[17]; - if(numberOfBasicFragment[18]<0)break; - numberOfBasicFragment[16]=numberOfBasicUnit[5]-numberOfBasicFragment[15]; - if(numberOfBasicFragment[16]<0)break; - numberOfBasicFragment[14]=numberOfBasicUnit[14]-numberOfBasicFragment[13]; - if(numberOfBasicFragment[14]<0)break; - numberOfBasicFragment[12]=numberOfBasicUnit[17]-numberOfBasicFragment[11]; - if(numberOfBasicFragment[12]<0)break; - numberOfBasicFragment[10]=numberOfBasicUnit[4]-numberOfBasicFragment[8]-numberOfBasicFragment[9]; - if(numberOfBasicFragment[10]<0)break; - - numberOfBasicFragment[7]=numberOfBasicUnit[18]-numberOfBasicFragment[5]-numberOfBasicFragment[6]; - if(numberOfBasicFragment[7]<0)break; - numberOfBasicFragment[4]=numberOfBasicUnit[6]-numberOfBasicFragment[1]-numberOfBasicFragment[2]-numberOfBasicFragment[3]; - if(numberOfBasicFragment[4]<0)break; - - flag=testBasicFragment(); - if(flag) - { - numberOfSetFragment+=1; - logger.debug("Fragment Set ", numberOfSetFragment); - if (logger.isDebugEnabled()) { - for(i=1;i<34;i++) { - if(numberOfBasicFragment[i]!=0)logger.debug(((BasicFragment)(basicFragment.get(i-1))).getBasicFragment()+" "+numberOfBasicFragment[i]); - } - } - generateIsomers(); - } - - }while(false); - - do - { - iter1=iter1-1; - if(iter1==0)return; - - if(numberOfBasicFragment[iter1]>=maxNumberOfBasicFragment[iter1])continue; - numberOfBasicFragment[iter1]=numberOfBasicFragment[iter1]+1; - - if(iter1==2) - { - k=numberOfBasicFragment[1]+numberOfBasicFragment[2]; - if(k>numberOfBasicUnit[6])continue; - else break; - } - else if(iter1==3) - { - k=numberOfBasicFragment[1]+numberOfBasicFragment[2]+numberOfBasicFragment[3]; - if(k>numberOfBasicUnit[6])continue; - else break; - } - else if(iter1==4) - { - k=numberOfBasicFragment[1]+numberOfBasicFragment[2]+numberOfBasicFragment[3]+numberOfBasicFragment[4]; - if(k>numberOfBasicUnit[6])continue; - else break; - } - else if(iter1==6) - { - k=numberOfBasicFragment[5]+numberOfBasicFragment[6]; - if(k>numberOfBasicUnit[18])continue; - else break; - } - else if(iter1==7) - { - k=numberOfBasicFragment[5]+numberOfBasicFragment[6]+numberOfBasicFragment[7]; - if(k>numberOfBasicUnit[18])continue; - else break; - } - - else if(iter1==9) - { - k=numberOfBasicFragment[8]+numberOfBasicFragment[9]; - if(k>numberOfBasicUnit[4])continue; - else break; - } - else if(iter1==10) - { - k=numberOfBasicFragment[8]+numberOfBasicFragment[9]+numberOfBasicFragment[10]; - if(k>numberOfBasicUnit[4])continue; - else break; - } - else if(iter1==12) - { - k=numberOfBasicFragment[11]+numberOfBasicFragment[12]; - if(k>numberOfBasicUnit[17])continue; - else break; - } - else if(iter1==14) - { - k=numberOfBasicFragment[13]+numberOfBasicFragment[14]; - if(k>numberOfBasicUnit[14])continue; - else break; - } - else if(iter1==16) - { - k=numberOfBasicFragment[15]+numberOfBasicFragment[16]; - if(k>numberOfBasicUnit[5])continue; - else break; - } - else if(iter1==18) - { - k=numberOfBasicFragment[17]+numberOfBasicFragment[18]; - if(k>numberOfBasicUnit[3])continue; - else break; - } - break; - }while(true); - } - } - - - - /** - * Test for the set of basic fragment. - */ - public boolean testBasicFragment() - { - int i,j; - int numberOfFragment,numberOfOneFreeValence,numberOfTwoFreeValence; - int numberOfThreeFreeValence,numberOfFourFreeValence; - int numberOfSideDoubleBond,numberOfMiddleDoubleBond; - int totalFreeValence,totalDoubleBond,totalTripleBond; - int numberOfSideTripleBond,numberOfMiddleTripleBond; - //boolean flag=true; - - /* initialization the variable*/ - numberOfFragment=0; - numberOfOneFreeValence=0; - numberOfTwoFreeValence=0; - numberOfThreeFreeValence=0; - numberOfFourFreeValence=0; - numberOfSideDoubleBond=0; - numberOfMiddleDoubleBond=0; - numberOfSideTripleBond=0; - numberOfMiddleTripleBond=0; - totalTripleBond=0; - totalFreeValence=0; - - for(i=1;i<34;i++) - { - numberOfFragment+=numberOfBasicFragment[i]; - j=((BasicFragment)(basicFragment.get(i-1))).getNumberOfFreeValence(); - switch(j) - { - case 1: numberOfOneFreeValence+=numberOfBasicFragment[i];break; - case 2: numberOfTwoFreeValence+=numberOfBasicFragment[i];break; - case 3: numberOfThreeFreeValence+=numberOfBasicFragment[i];break; - case 4: numberOfFourFreeValence+=numberOfBasicFragment[i];break; - } - - } - /* 1. total free valence test*/ - totalFreeValence=numberOfOneFreeValence+numberOfTwoFreeValence*2+numberOfThreeFreeValence*3+numberOfFourFreeValence*4; - if((totalFreeValence%2)!=0)return false; - - totalFreeValence/=2; - if(numberOfFragment>(totalFreeValence+1))return false; - - /*2. double bond test: */ - numberOfSideDoubleBond=numberOfBasicFragment[12]+numberOfBasicFragment[14]+numberOfBasicFragment[16]+numberOfBasicFragment[18]; - numberOfMiddleDoubleBond=numberOfBasicFragment[2]+numberOfBasicFragment[6]+numberOfBasicFragment[9]; - if(numberOfBasicFragment[3]==0) - { - if(numberOfSideDoubleBond>numberOfMiddleDoubleBond && numberOfMiddleDoubleBond>0)return false; - totalDoubleBond=numberOfSideDoubleBond+numberOfMiddleDoubleBond; - if((totalDoubleBond%2)!=0)return false; - if((numberOfMiddleDoubleBond==0)&& (numberOfSideDoubleBond==2)&&(numberOfFragment>2))return false; - } - if(numberOfBasicFragment[3]>0) - { - if((numberOfMiddleDoubleBond==0)&&(numberOfBasicFragment[3]<(numberOfFragment-2)))return false; - if((numberOfMiddleDoubleBond+numberOfSideDoubleBond==0)&&(numberOfBasicFragment[3]<numberOfFragment))return false; - } - - /*triple bond test*/ - - numberOfSideTripleBond=numberOfBasicFragment[7]+numberOfBasicFragment[10]; - numberOfMiddleTripleBond=numberOfBasicFragment[4]; - totalTripleBond=numberOfSideTripleBond+numberOfMiddleTripleBond; - - if((totalTripleBond%2)!=0)return false; - if(numberOfMiddleTripleBond==0 && numberOfSideTripleBond!=0)return false; - return true; - } - - List setOfBasicFragment = new ArrayList(); - IntArray storedSymbolOfStructure = new IntArray(); - - /** - * The thrid step: generate all the possible consititional isomers. - */ - public void generateIsomers() - { - int i,j,rows; - int step,firstUnfilledRow;//equivalentClass; - int[] totalNumberOfTheSet=new int[1]; - int totalNumberOfAtomAndBond=0; - totalNumberOfTheSet[0]=0; - - boolean flag,nextWCF,isForced,isPossibleFilling; - int[][] adjacencyMatrix; - int[][] previousMatrix; - int[] rowMatrix; - //int[] setOfStability; - //int[] category; - int[] bondAttribute; - int[] parentID; - // reinitialize - storedSymbolOfStructure.clear(); - setOfBasicFragment.clear(); - IAtomContainer atomContainer=null; - - /*1. prepare the vector of basic fragment and atomContainer - * atomContainer put the bond formed, while set of basic fragment - * put the source basic fragment. - */ - - - for(i=1;i<34;i++) - if(numberOfBasicFragment[i]!=0) - { - for(j=1;j<=numberOfBasicFragment[i];j++) - totalNumberOfAtomAndBond+=((BasicFragment)(basicFragment.get(i-1))).getNumberOfFreeValence(); - - } - totalNumberOfAtomAndBond/=2; - - - for(i=1;i<34;i++) - if(numberOfBasicFragment[i]!=0) - { - for(j=1;j<=numberOfBasicFragment[i];j++) - { - totalNumberOfAtomAndBond+=1; - } - - // consider the complex fragment - switch(i) - { - case 2: - for(j=1;j<=numberOfBasicFragment[i];j++) - { - setOfBasicFragment.add((BasicFragment)(basicFragment.get(33))); - setOfBasicFragment.add((BasicFragment)(basicFragment.get(34))); - } - - break; - case 4: - for(j=1;j<=numberOfBasicFragment[i];j++) - { - setOfBasicFragment.add((BasicFragment)(basicFragment.get(35))); - setOfBasicFragment.add((BasicFragment)(basicFragment.get(36))); - } - break; - case 6: - for(j=1;j<=numberOfBasicFragment[i];j++) - { - setOfBasicFragment.add((BasicFragment)(basicFragment.get(37))); - setOfBasicFragment.add((BasicFragment)(basicFragment.get(38))); - } - break; - case 9: - for(j=1;j<=numberOfBasicFragment[i];j++) - { - setOfBasicFragment.add((BasicFragment)(basicFragment.get(39))); - setOfBasicFragment.add((BasicFragment)(basicFragment.get(40))); - } - break; - default: - for(j=1;j<=numberOfBasicFragment[i];j++) - setOfBasicFragment.add((BasicFragment)(basicFragment.get(i-1))); - break; - } - - } - - //order the fragments - atomContainer= builder.newAtomContainer(); - - parentID=new int[setOfBasicFragment.size()]; - - /* sort the fragment set according to the free valence*/ - setOfBasicFragment=getOrderOfBasicFragmentSet(setOfBasicFragment,parentID); - - rows=setOfBasicFragment.size(); - adjacencyMatrix=new int[rows][rows]; - previousMatrix=new int[rows][rows]; - rowMatrix=new int[rows]; - //setOfStability=new int[rows]; - bondAttribute=new int[rows]; - - for(i=0;i<rows;i++) - { - bondAttribute[i]=((BasicFragment)(setOfBasicFragment.get(i))).getAttribute(); - } - - for(i=0;i<setOfBasicFragment.size();i++) - { - atomContainer.addAtom( - builder.newAtom(((BasicFragment)(setOfBasicFragment.get(i))).getHeavyAtomSymbol()) - ); - } - - //IAtom[] atom=atomContainer.getAtoms(); - - for(i=0;i<atomContainer.getAtomCount();i++) - { - atomContainer.getAtom(i).setHydrogenCount(((BasicFragment)(setOfBasicFragment.get(i))).getNumberOfHydrogen()); - } - - //2. initialize the matrix - initializeMatrix(setOfBasicFragment,bondAttribute,adjacencyMatrix,previousMatrix); - // Initial equivalent - //equivalentClass=getEquivalentClass(setOfBasicFragment,setOfStability); - //3. begin, see the flowchart - step=0; - - //Maximum WCF(M) - isPossibleFilling=getMaximumWCF(setOfBasicFragment,0,rowMatrix,adjacencyMatrix,previousMatrix,parentID); - if(!isPossibleFilling)return; - while(step<(rows-1)) - { - // Force filling the left lines - step+=1; - firstUnfilledRow=forceFilling(step,setOfBasicFragment,adjacencyMatrix,previousMatrix); - do - { - // Check admissibility - flag=checkAdmissibility(step,setOfBasicFragment,adjacencyMatrix); - if(!flag)break; - - // constraint checker - flag=checkConstraint(firstUnfilledRow,setOfBasicFragment,adjacencyMatrix,atomContainer); - if(!flag)break; - }while(false); - - if(flag) - { - if(firstUnfilledRow<rows) - { - step=firstUnfilledRow; - isPossibleFilling=getMaximumWCF(setOfBasicFragment,step,rowMatrix,adjacencyMatrix,previousMatrix,parentID); - if(!isPossibleFilling)return; - continue; - } - else - { - getFinalStructure(setOfBasicFragment,adjacencyMatrix,storedSymbolOfStructure,totalNumberOfTheSet,totalNumberOfAtomAndBond); - step-=1; - } - } - else step-=1; - - // judge whether the line is forcefilling or not - isForced=isForceFilling(step,previousMatrix,adjacencyMatrix); - while(isForced) - { - step-=1; - isForced=isForceFilling(step,previousMatrix,adjacencyMatrix); - } - - //get rowMatrix - for(i=0;i<rowMatrix.length;i++)rowMatrix[i]=adjacencyMatrix[step][i]; - // backtracking: restore the matrix to previous step - restoreMatrix(step,bondAttribute,previousMatrix,adjacencyMatrix); - nextWCF=getNextWCF(setOfBasicFragment,step,rowMatrix,adjacencyMatrix,previousMatrix,parentID); - - while(!nextWCF) - { - step-=1; - if(step<0)return; - else - { - isForced=isForceFilling(step,previousMatrix,adjacencyMatrix); - while(isForced) - { - step-=1; - isForced=isForceFilling(step,previousMatrix,adjacencyMatrix); - } - for(i=0;i<rowMatrix.length;i++) - { - rowMatrix[i]=adjacencyMatrix[step][i]; - } - restoreMatrix(step,bondAttribute,previousMatrix,adjacencyMatrix); - nextWCF=getNextWCF(setOfBasicFragment,step,rowMatrix,adjacencyMatrix,previousMatrix,parentID); - if(nextWCF)break; - } - } - } - return; - } - - /** - * Initialized the adjacency matrix. - * - * @param setOfBasicFragment set of basic fragment - * @param bondAttribute to distinguish the bond - * @param adjacency adjacency matrix - * @param previousMatrix tracing the change of adjacency matrix - */ - public void initializeMatrix(List setOfBasicFragment, int[] bondAttribute,int[][] adjacency,int[][] previousMatrix) - { - int i,j,row,sum; - row=setOfBasicFragment.size(); - - int[] valenceOfFragment=new int[row]; - - - for(i=0;i<adjacency.length;i++) - for(j=0;j<adjacency.length;j++) - adjacency[i][j]=-1; - for(i=0;i<adjacency.length;i++) - { - adjacency[i][i]=0; - valenceOfFragment[i]=0; - } - - - /* if there are two basic fragments which is 1 free valence, appraently it is impossible to - * be bonded between these two fragments. - */ - sum=0; - if(row>2) - { - for(i=0;i<row;i++) - { - if(((BasicFragment)(setOfBasicFragment.get(i))).getNumberOfFreeValence()==1 - && ((BasicFragment)(setOfBasicFragment.get(i))).getID()<=33)valenceOfFragment[i]=1; - sum+=valenceOfFragment[i]; - } - if(sum>1) - for(i=0;i<row-1;i++) - for(j=i+1;j<row;j++) - { - if(valenceOfFragment[i]==1 &&valenceOfFragment[j]==1) - { - adjacency[i][j]=0; - adjacency[j][i]=0; - } - } - } - // The following loop is to give the zero element for bond unmatch. 28-11-2003 - for(i=0;i<row-1;i++) - for(j=i;j<row;j++) - if(bondAttribute[i]!=bondAttribute[j]) - { - adjacency[i][j]=0; - adjacency[j][i]=0; - } - for(i=0;i<adjacency.length;i++) - { - for(j=0;j<adjacency.length;j++) - { - previousMatrix[i][j]=adjacency[i][j]; - } - } - return; - } - - - /** - * Restore the adjacency matrix to previous step. - * - * @param step the line is filling - * @param freeValence array for free valence of each node left - * @param sourceMatrix the reference matrix - * @param destMatrix the matrix need to backtrack - */ - public void restoreMatrix(int step,int[] freeValence,int[][] sourceMatrix,int[][] destMatrix) - { - int i,j; - for(i=step;i<sourceMatrix.length;i++) - { - if(sourceMatrix[i][i]>step) - { - destMatrix[i][i]=0;sourceMatrix[i][i]=0; - } - - for(j=0;j<sourceMatrix.length;j++) - { - if(sourceMatrix[i][j]>step) - { - if(i!=j) - { - destMatrix[i][j]=-1;sourceMatrix[i][j]=-1; - } - } - } - } - return; - } - - /** - * Maximum weakly canonical filling of line M. - * - * @param setOfBasicFragment set of basic fragment - * @param step the line is filling - * @param rowMatrix the row which contains the filling line - * @param adjacency adjacency matrix - * @param previousMatrix matrix is used for tracing the change of adjacency matrix. - * @param parentID mainly used for unsaturated part - */ - public boolean getMaximumWCF(List setOfBasicFragment,int step,int[] rowMatrix, int[][] adjacency,int[][] previousMatrix,int[] parentID) - { - int i,iter,bondOrder,size; - int totalBond,existBond,leftBond; - int[] setOfStability; - setOfStability=new int[rowMatrix.length]; - - /*Get the row matrix*/ - size=setOfBasicFragment.size(); - iter=0; - for(i=0;i<adjacency.length;i++) - { - rowMatrix[i]=adjacency[step][i]; - if(rowMatrix[i]==-1)iter+=1; - } - getSetOfStability(setOfBasicFragment,step,rowMatrix,adjacency,setOfStability,parentID); - existBond=0; - for(i=0;i<adjacency.length;i++)if(rowMatrix[i]>0)existBond+=rowMatrix[i]; - totalBond=((BasicFragment)(setOfBasicFragment.get(step))).getNumberOfFreeValence(); - bondOrder=((BasicFragment)(setOfBasicFragment.get(step))).getAttribute(); - leftBond=totalBond-existBond; - if(leftBond>iter)return false; - - /* maximum this line*/ - iter=leftBond; - for(i=1;i<rowMatrix.length;i++) - { - if(setOfStability[i]!=0) - { - if(iter>0){rowMatrix[i]=bondOrder;iter-=1;} - else rowMatrix[i]=0; - } - } - /* A(i,j)=A(j,i)*/ - for(i=0;i<adjacency.length;i++) - { - adjacency[step][i]=rowMatrix[i]; - if(previousMatrix[step][i]==-1)previousMatrix[step][i]=step+1; - - adjacency[i][step]=rowMatrix[i]; - if(previousMatrix[i][step]==-1)previousMatrix[i][step]=step+1; - } - - //for unsaturated part - int decomposedNumber=0; - int number1=0; - int number2=0; - if(parentID[step]==-1)return true; - else - { - - for(i=0;i<size;i++) - if(parentID[i]!=-1)decomposedNumber+=1; - for(i=0;i<adjacency.length;i++) - if(rowMatrix[i]>0 && parentID[i]!=-1) - { - - number1=parentID[step]; - number2=parentID[i]; - if((adjacency[step][i]>0 || adjacency[i][step]>0) && adjacency[number1][number2]==-1) - { - adjacency[number1][number2]=0; - adjacency[number2][number1]=0; - if(previousMatrix[number1][number2]==-1) - previousMatrix[number1][number2]=step+1; - if(previousMatrix[number2][number1]==-1) - previousMatrix[number2][number1]=step+1; - } - } - } - return true; - } - - - /** - * Get the partition for the left fragment at every step. - * - * @param setOfBasicFragment set of basic fragment - * @param step the line is filling - * @param rowMatrix the row which contains the filling line - * @param adjacency adjacency matrix - * @param setOfStability the previous equivalent partition - * @param parentID mainly used for unsaturated part - */ - public void getSetOfStability(List setOfBasicFragment,int step,int[] rowMatrix, int[][] adjacency,int[] setOfStability,int[] parentID) - { - int i,j,count,line; - int temp,size; - size=rowMatrix.length; - //boolean[] isAdded=new boolean[size]; - int[] category=new int[size+1]; - int[] equivalentClass=new int[size]; - - line=0; - for(i=0;i<adjacency.length;i++)setOfStability[i]=0; - if(step==0) - { - for(i=1;i<setOfBasicFragment.size();i++) - { - if(rowMatrix[i]==-1) - { - setOfStability[i]=((BasicFragment)(setOfBasicFragment.get(i))).getID(); - } - } - - } - else - { - for(i=step+1;i<setOfBasicFragment.size();i++) - { - if(rowMatrix[i]==-1) - { - setOfStability[i]=((BasicFragment)(setOfBasicFragment.get(i))).getID(); - } - } - - /* judge temporatory equivalent at this line. */ - for(i=step+1;i<setOfStability.length-1;i++) - for(j=i+1;j<setOfStability.length;j++) - { - if(rowMatrix[i]==-1 && rowMatrix[j]==-1 && setOfStability[i]==setOfStability[j]) - { - for(line=0;line<step;line++) - { - if(adjacency[line][i]==adjacency[line][j])continue; - else break; - } - if(line<step)setOfStability[j]+=100;// - } - } - } - - temp=0; - for(i=0;i<parentID.length;i++) - { - if(parentID[i]!=-1)temp+=1; - } - if(temp>4) - { - int[] fragmentID=new int[setOfBasicFragment.size()]; - for(i=0;i<setOfBasicFragment.size();i++) - fragmentID[i]=((BasicFragment)(setOfBasicFragment.get(i))).getID(); - for(i=step+1;i<setOfBasicFragment.size()-1;i++) - for(j=i+1;j<setOfBasicFragment.size();j++) - { - int temp1=parentID[i]; - int temp2=parentID[j]; - if(rowMatrix[i]==-1 && rowMatrix[j]==-1) - { - if(fragmentID[i]>33 && fragmentID[j]>33 - && rowMatrix[temp1]!=-1 && rowMatrix[temp2]!=-1 - && setOfStability[i]==setOfStability[j]) - setOfStability[j]+=100; - } - } - } - /* get the category for this line*/ - count=1; - for(i=step+1;i<setOfStability.length;i++)if(rowMatrix[i]==-1){line=i;break;} - category[1]=setOfStability[line]; - for(i=step+1;i<setOfStability.length;i++) - { - if(setOfStability[i]!=0) - { - for(j=1;j<=count;j++) - { - if(rowMatrix[i]==-1) - { - temp=setOfStability[i]-category[j]; - if(temp==0)break; - } - else continue; - } - if(j>count) - { - count+=1; - category[count]=setOfStability[i]; - } - } - } - for(i=1;i<setOfStability.length;i++) - for(j=1;j<=count;j++) - { - if(rowMatrix[i]==-1) - { - temp=setOfStability[i]-category[j]; - if(temp==0)equivalentClass[i]=j; - } - } - equivalentClass[0]=count; - - for(i=0;i<setOfStability.length;i++) - { - setOfStability[i]=equivalentClass[i]; - } - } - - /** - * Force filling the left matrix at every step. - * - * @param step the line is filling - * @param setOfBasicFragment vector contains the set of basic fragment. - * @param adjacencyMatrix adjacency matrix of the given basic fragment. - * @param previousMatrix matrix is used for tracing the change of adjacency matrix. - * @return the first line which is unfilled - */ - public int forceFilling(int step,List setOfBasicFragment,int[][] adjacencyMatrix,int[][] previousMatrix) - { - /* 1. Minimal forcing. The sum of filled elements of each unfilled row i->J(B) - * is equal to the valence of the corresponding vertex. - * 2. Maximal forcing. The sum of all maximal multiplicity of edges of the Vi-th vertex, i->J(B) - * is equal to the valence of the vertex. - */ - int i,j,iter,sum,bondOrder; - int filledValence,unfilledValence,changedLine; - - do - { - changedLine=0; - for(i=step;i<adjacencyMatrix.length;i++) - { - sum=0; - unfilledValence=0; - if(previousMatrix[i][i]>0)continue; - for(j=0;j<adjacencyMatrix.length;j++) - { - if(adjacencyMatrix[i][j]>0)sum+=1; - else if(adjacencyMatrix[i][j]==-1)unfilledValence+=1; - } - - if(previousMatrix[i][i]==0 && unfilledValence==0) - { - previousMatrix[i][i]=step; - } - if(sum==((BasicFragment)(setOfBasicFragment.get(i))).getNumberOfFreeValence() && unfilledValence>0) - { - //Satisfy the minimal forcing, fill this line - for(iter=0;iter<adjacencyMatrix.length;iter++) - { - if(adjacencyMatrix[i][iter]==-1) - { - adjacencyMatrix[i][iter]=0; - previousMatrix[i][iter]=step; - adjacencyMatrix[iter][i]=0; - previousMatrix[iter][i]=step; - } - - } - previousMatrix[i][i]=step; - changedLine+=1; - } - } - - /* maximal forcing. */ - for(i=step;i<adjacencyMatrix.length;i++) - { - sum=0; - filledValence=0; - if(previousMatrix[i][i]>0)continue; - for(j=0;j<adjacencyMatrix.length;j++) - { - - if(adjacencyMatrix[i][j]==-1)sum+=1; - else if(adjacencyMatrix[i][j]>0)filledValence+=1; - } - if(previousMatrix[i][i]==0 && sum==0) - { - previousMatrix[i][i]=step; - } - if(sum==(((BasicFragment)(setOfBasicFragment.get(i))).getNumberOfFreeValence()-filledValence) && sum>0) - { - bondOrder=((BasicFragment)(setOfBasicFragment.get(i))).getAttribute(); - //Satisfy the maximal forcing, fill this line - for(iter=0;iter<adjacencyMatrix.length;iter++) - { - if(adjacencyMatrix[i][iter]==-1) - { - adjacencyMatrix[i][iter]=bondOrder; - previousMatrix[i][iter]=step; - adjacencyMatrix[iter][i]=bondOrder; - previousMatrix[iter][i]=step; - } - - } - previousMatrix[i][i]=step; - changedLine+=1; - } - } - }while(changedLine>0); - - /* find the first unfilled line*/ - for(i=step;i<adjacencyMatrix.length;i++) - for(j=0;j<adjacencyMatrix.length;j++)if(adjacencyMatrix[i][j]==-1)return i; - return adjacencyMatrix.length; - } - - - /** - * Check admissibility of the matrix. - * Details see Sergey G. Molodtsov, Computer-Aided Generation of Molecular Graphs, - * Match, 30(213),1994 - * - * @param step the line is filling. - * @param setOfBasicFragment set of basic fragment - * @param adjacencyMatrix adjacency matrix - * @return a boolean value whether this line could pass adissibility or not - */ - public boolean checkAdmissibility(int step,List setOfBasicFragment,int[][] adjacencyMatrix) - { - for(int i=step;i<adjacencyMatrix.length;i++) - { - int sum=0; - int unfilledValence=0; - { - for(int j=0;j<adjacencyMatrix.length;j++) - { - if(adjacencyMatrix[i][j]>0)sum+=1; - if(adjacencyMatrix[i][j]==-1)unfilledValence+=1; - } - if(sum>((BasicFragment)(setOfBasicFragment.get(i))).getNumberOfFreeValence()){return false;} - if(unfilledValence<(((BasicFragment)(setOfBasicFragment.get(i))).getNumberOfFreeValence()-sum) && unfilledValence>=0) - { - return false; - } - } - - } - return true; - } - - - /** - * Check constraint of the matrix. Currently, there is only connectivity test. - * Later, there might be other tests. - * - * @param step the line is filling. - * @param setOfBasicFragment set of basic fragment - * @param adjacencyMatrix adjacency matrix - * @param ac atomContainer of the node set, not used now - * @return a boolean value whether this adjacency matrix pass the constraint check or not - */ - public boolean checkConstraint(int step,List setOfBasicFragment,int[][] adjacencyMatrix, IAtomContainer ac) - { - int i,j,partialSum,totalSum,decomposedNumber; - //boolean isConnectivity; - boolean[] isVisited=new boolean[adjacencyMatrix.length]; - int[] isDecomposed=new int[adjacencyMatrix.length]; - int[] parentID=new int[adjacencyMatrix.length]; - for(i=0;i<adjacencyMatrix.length;i++) - { - isVisited[i]=false; - isDecomposed[i]=0; - parentID[i]=0; - } - /* check connectivity first. This time, it is substructure or structure*/ - if(step==1)return true; - else if(step==adjacencyMatrix.length) - { - decomposedNumber=0; - for(i=0;i<adjacencyMatrix.length;i++) - { - if(((BasicFragment)(setOfBasicFragment.get(i))).getID()>33) - { - isDecomposed[i]=((BasicFragment)(setOfBasicFragment.get(i))).getID(); - parentID[i]=((BasicFragment)(setOfBasicFragment.get(i))).getParentID(); - decomposedNumber+=1; - } - } - if(decomposedNumber>0) - { - for(i=0;i<adjacencyMatrix.length-1;i++) - for(j=i+1;j<adjacencyMatrix.length;j++) - if(isDecomposed[i]!=isDecomposed[j] && parentID[i]==parentID[j] && - i!=j && adjacencyMatrix[i][i]==0 && adjacencyMatrix[j][j]==0) - { - adjacencyMatrix[i][j]=10; - adjacencyMatrix[j][i]=10; - adjacencyMatrix[i][i]=10; - adjacencyMatrix[j][j]=10; - } - } - - DFSM(adjacencyMatrix,0,isVisited); - if(decomposedNumber>0) - { - for(i=0;i<adjacencyMatrix.length;i++) - for(j=0;j<adjacencyMatrix.length;j++) - if(adjacencyMatrix[i][j]==10)adjacencyMatrix[i][j]=0; - } - for(i=0;i<adjacencyMatrix.length;i++)if(!isVisited[i])return false; - return true; - // } - - } - else - { - decomposedNumber=0; - for(i=0;i<adjacencyMatrix.length;i++) - { - if(((BasicFragment)(setOfBasicFragment.get(i))).getID()>33) - { - isDecomposed[i]=((BasicFragment)(setOfBasicFragment.get(i))).getID(); - parentID[i]=((BasicFragment)(setOfBasicFragment.get(i))).getParentID(); - decomposedNumber+=1; - } - } - if(decomposedNumber>0) - { - for(i=0;i<adjacencyMatrix.length-1;i++) - for(j=i;j<adjacencyMatrix.length;j++) - if(isDecomposed[i]!=isDecomposed[j] && parentID[i]==parentID[j] && - i!=j && adjacencyMatrix[i][i]==0 && adjacencyMatrix[j][j]==0) - { - adjacencyMatrix[i][j]=10; - adjacencyMatrix[j][i]=10; - adjacencyMatrix[i][i]=10; - adjacencyMatrix[j][j]=10; - } - } - DFSM(adjacencyMatrix,0,isVisited); - if(decomposedNumber>0) - { - for(i=0;i<adjacencyMatrix.length;i++) - for(j=0;j<adjacencyMatrix.length;j++) - if(adjacencyMatrix[i][j]==10)adjacencyMatrix[i][j]=0; - } - - partialSum=0; - totalSum=0; - for(i=0;i<step;i++) - { - if(isVisited[i])partialSum+=1; - } - for(i=0;i<adjacencyMatrix.length;i++) - { - if(isVisited[i])totalSum+=1; - } - if(partialSum==step && partialSum==totalSum)return false; - else if(totalSum==adjacencyMatrix.length)return true; - else return true; - } - } - - /** - * Get the next WCF (weakly canonical complement). - * Details see Sergey G. Molodtsov, Computer-Aided Generation of Molecular Graphs, - * Match, 30(213),1994 - * - * @param setOfBasicFragment set of basic fragment - * @param step the step of the generation - * @param rowMatrix the row which contains the filling line - * @param adjacencyMatrix adjacency matrix - * @param previousMatrix matrix to trace the change of adjacency matrix - * @param parentID array mainly used for complex bond - * @return a boolean value whether there is next WCF or not - * - */ - public boolean getNextWCF(List setOfBasicFragment,int step,int[] rowMatrix,int[][] adjacencyMatrix,int[][] previousMatrix,int[] parentID) - { - int i,j,iter,existBond,leftBond,totalBond,changedCategory,sum; // changedFilledValue,nextNonZeroElement - int bondOrder; - int[] setOfStability; - int[] previousLine; - int[] category; - int[] previousFilledValue; - int[] currentFilledValue; - - setOfStability=new int[rowMatrix.length]; - previousLine=new int[rowMatrix.length]; - category=new int[rowMatrix.length]; - previousFilledValue=new int[rowMatrix.length]; - currentFilledValue=new int[rowMatrix.length]; - for(i=step;i<rowMatrix.length;i++) - { - previousLine[i]=rowMatrix[i]; - } - - iter=0; - for(i=0;i<rowMatrix.length;i++) - { - rowMatrix[i]=adjacencyMatrix[step][i]; - if(rowMatrix[i]==-1)iter+=1; - } - getSetOfStability(setOfBasicFragment,step,rowMatrix,adjacencyMatrix,setOfStability,parentID); - - existBond=0; - for(i=0;i<adjacencyMatrix.length;i++)if(rowMatrix[i]>0)existBond+=1; - totalBond=((BasicFragment)(setOfBasicFragment.get(step))).getNumberOfFreeValence(); - bondOrder=((BasicFragment)(setOfBasicFragment.get(step))).getAttribute(); - leftBond=totalBond-existBond; - iter=1; - while(iter<=setOfStability[0]) - { - for(i=1;i<rowMatrix.length;i++) - { - if(setOfStability[i]==iter)category[iter]+=1; - if(setOfStability[i]==iter) - if(previousLine[i]>0)previousFilledValue[iter]+=1; - } - iter+=1; - } - category[0]=setOfStability[0]; - changedCategory=0; - for(i=category[0];i>=1;i--)if(previousFilledValue[i]!=0){changedCategory=i;break;} - - /* judge mininal WCF*/ - if(changedCategory==category[0]) - { - if(previousFilledValue[category[0]]< category[changedCategory] && previousFilledValue[category[0]]==leftBond) - return false; - else if(previousFilledValue[category[0]]==category[changedCategory]) - { - sum=0; - for(i=category[0];i>=1;i--) - { - sum+=previousFilledValue[i]; - if(previousFilledValue[i]==category[i] && sum<leftBond)continue; - if(sum==leftBond)return false; - break;//non-termination - } - } - } - - /*get next WCF*/ - if(changedCategory!=category[0]) - { - for(i=1;i<=category[0];i++) - { - if(i<changedCategory)currentFilledValue[i]=previousFilledValue[i]; - else if(i==changedCategory)currentFilledValue[i]=previousFilledValue[i]-1; - else if(i==(changedCategory+1))currentFilledValue[i]=1; - } - } - else if(changedCategory==category[0] && (previousFilledValue[changedCategory]<category[changedCategory]||previousFilledValue[changedCategory-1]==0)) - { - while(previousFilledValue[changedCategory-1]==0)changedCategory-=1; - sum=0; - for(i=1;i<(changedCategory-1);i++) - { - currentFilledValue[i]=previousFilledValue[i]; - sum+=currentFilledValue[i]; - } - - currentFilledValue[changedCategory-1]=previousFilledValue[changedCategory-1]-1; - sum+=currentFilledValue[changedCategory-1]; - iter=changedCategory; - while(leftBond>sum) - { - currentFilledValue[iter]=leftBond-sum; - if(currentFilledValue[iter]>category[iter] && iter<category[0]) - { - currentFilledValue[iter]=category[iter]; - sum+=currentFilledValue[iter]; - iter+=1; - continue; - } - else break; - } - } - else if(changedCategory==category[0]&& previousFilledValue[changedCategory]==category[changedCategory] && - previousFil... [truncated message content] |