[Git][java-team/openchemlib][master] 4 commits: New upstream version 2022.1.0+dfsg

Andrius Merkys (@merkys) gitlab at salsa.debian.org
Fri Jan 14 14:42:28 GMT 2022



Andrius Merkys pushed to branch master at Debian Java Maintainers / openchemlib


Commits:
c7483100 by Andrius Merkys at 2022-01-14T08:24:53-05:00
New upstream version 2022.1.0+dfsg
- - - - -
da9e9df2 by Andrius Merkys at 2022-01-14T08:25:04-05:00
Update upstream source from tag 'upstream/2022.1.0+dfsg'

Update to upstream version '2022.1.0+dfsg'
with Debian dir ef548b12bb364c21d8caa2976ef8cb50dadb8452
- - - - -
73e9db95 by Andrius Merkys at 2022-01-14T08:26:36-05:00
Bumping copyright years.

- - - - -
4569bc28 by Andrius Merkys at 2022-01-14T08:26:53-05:00
Update changelog for 2022.1.0+dfsg-1 release

- - - - -


14 changed files:

- debian/changelog
- debian/copyright
- pom.xml
- src/main/java/com/actelion/research/chem/AbstractDepictor.java
- src/main/java/com/actelion/research/chem/chemicalspaces/ChemicalSpaceCreator.java
- src/main/java/com/actelion/research/chem/chemicalspaces/synthon/SynthonCreator.java
- src/main/java/com/actelion/research/chem/coords/CoordinateInventor.java
- src/main/java/com/actelion/research/chem/coords/InventorFragment.java
- src/main/java/com/actelion/research/chem/descriptor/flexophore/completegraphmatcher/ObjectiveBlurFlexophoreHardMatchUncovered.java
- src/main/java/com/actelion/research/chem/descriptor/flexophore/example/MatchFlexophoreNodesMain.java
- src/main/java/com/actelion/research/chem/io/CompoundTableConstants.java
- src/main/java/com/actelion/research/chem/io/Mol2FileParser.java
- src/main/java/com/actelion/research/gui/JStructureView.java
- src/main/java/com/actelion/research/util/graph/complete/CompleteGraphMatcher.java


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,10 @@
+openchemlib (2022.1.0+dfsg-1) unstable; urgency=medium
+
+  * New upstream version 2022.1.0+dfsg
+  * Bumping copyright years.
+
+ -- Andrius Merkys <merkys at debian.org>  Fri, 14 Jan 2022 08:26:48 -0500
+
 openchemlib (2021.12.0+dfsg-1) unstable; urgency=medium
 
   * New upstream version 2021.12.0+dfsg


=====================================
debian/copyright
=====================================
@@ -5,11 +5,11 @@ Files-Excluded:
  src/main/java/info
 
 Files: *
-Copyright: 1997-2021, Idorsia Pharmaceuticals Ltd, Hegenheimermattweg 91, CH-4123 Allschwil, Switzerland
+Copyright: 1997-2022, Idorsia Pharmaceuticals Ltd, Hegenheimermattweg 91, CH-4123 Allschwil, Switzerland
 License: BSD-3-clause
 
 Files: debian/*
-Copyright: 2020-2021, Andrius Merkys <merkys at debian.org>
+Copyright: 2020-2022, Andrius Merkys <merkys at debian.org>
 License: BSD-3-clause
 
 Files: src/main/java/com/actelion/research/calc/statistics/median/MedianStatisticFunctions.java
@@ -49,7 +49,7 @@ Files: src/main/java/com/actelion/research/calc/statistics/median/MedianStatisti
  src/main/java/com/actelion/research/gui/JEditableStructureView.java
  src/main/java/com/actelion/research/gui/JStructureView.java
  src/main/java/com/actelion/research/gui/StructureListener.java
-Copyright: 1997-2021, Idorsia Pharmaceuticals Ltd., Hegenheimermattweg 91, CH-4123 Allschwil, Switzerland
+Copyright: 1997-2022, Idorsia Pharmaceuticals Ltd., Hegenheimermattweg 91, CH-4123 Allschwil, Switzerland
 License: GPL-3+
 
 License: BSD-3-clause


=====================================
pom.xml
=====================================
@@ -8,7 +8,7 @@
     Please follow the naming scheme YEAR.MONTH.RELEASE_NO_OF_MONTH
     (eg. 2016.4.1 for second release in Apr 2016)
     -->
-    <version>2021.12.0</version>
+    <version>2022.1.0</version>
 
     <name>OpenChemLib</name>
     <description>Open Source Chemistry Library</description>
@@ -195,7 +195,7 @@
         <connection>scm:git:git at github.com:Actelion/openchemlib.git</connection>
         <developerConnection>scm:git:git at github.com:Actelion/openchemlib.git</developerConnection>
         <url>https://github.com/Actelion/openchemlib</url>
-      <tag>openchemlib-2021.12.0</tag>
+      <tag>openchemlib-2022.1.0</tag>
   </scm>
 
     <distributionManagement>


=====================================
src/main/java/com/actelion/research/chem/AbstractDepictor.java
=====================================
@@ -162,7 +162,7 @@ public abstract class AbstractDepictor<T> {
 	private Rectangle2D.Double		mBoundingRect = new Rectangle2D.Double();
 	private DepictorTransformation	mTransformation;
 	private Point2D.Double			mChiralTextLocation;
-	private int[]					mAtomColor;
+	private int[]					mAtomColor,mAtomHiliteColor;
 	private String[]				mAtomText;
 	private Point2D.Double[]		mAlternativeCoords;
 	private Color					mOverruleForeground,mOverruleBackground,mBondBGHiliteColor,mBondFGHiliteColor,
@@ -198,13 +198,6 @@ public abstract class AbstractDepictor<T> {
 		}
 
 
-/*	@Deprecated
-	public void setDefaultColor(int c) {
-		mStandardForegroundColor = c;
-	    updateBondHiliteColor();
-		}*/
-
-
 	/**
 	 * If the foreground color is set, the molecule is drawn in the foreground
 	 * color except for non carbon atoms, which are drawn in atomicNo specific
@@ -235,6 +228,16 @@ public abstract class AbstractDepictor<T> {
 		}
 
 
+	/**
+	 * If you want this tructure view to also draw an atom background with specific colors for every atom,
+	 * then you need to call this method before calling paint().
+	 * @param argb values with a==0 are not considered (may be null)
+	 */
+	public void setAtomHighlightColors(int[] argb) {
+		mAtomHiliteColor = argb;
+		}
+
+
 	public void setTransformation(DepictorTransformation t) {
 		mTransformation = t;
 		}
@@ -561,6 +564,7 @@ public abstract class AbstractDepictor<T> {
 
 		setColor(COLOR_INITIALIZE);	// to initialize the color tracking mechanism
 
+		hiliteAtomBackgrounds();
 		hiliteExcludeGroups();
 		hiliteBondBackgrounds();
 		indicateQueryFeatures();
@@ -593,7 +597,7 @@ public abstract class AbstractDepictor<T> {
 				  && ((mDisplayMode & cDModeNoImplicitAtomLabelColors) == 0)
 				  && mMol.getAtomList(i) == null
 				  && mMol.getAtomicNo(i) < ATOM_LABEL_COLOR.length) {
-				setRGBColor(getContrastColor(ATOM_LABEL_COLOR[mMol.getAtomicNo(i)]));
+				setRGBColor(getContrastColor(ATOM_LABEL_COLOR[mMol.getAtomicNo(i)], i));
 	    		mpDrawAtom(i, esrGroupMemberCount);
 				setColor(mStandardForegroundColor);
 				}
@@ -607,9 +611,10 @@ public abstract class AbstractDepictor<T> {
 		}
 
 
-	private Color getContrastColor(int rgb) {
+	private Color getContrastColor(int rgb, int atom) {
 		Color bg = (mOverruleBackground != null) ? mOverruleBackground
-				 : (mCustomBackground != null) ? mCustomBackground : Color.WHITE;
+				: (mAtomHiliteColor != null && atom < mAtomHiliteColor.length && (mAtomHiliteColor[atom] & 0xFF000000) != 0) ? new Color(mAtomHiliteColor[atom])
+				: (mCustomBackground != null) ? mCustomBackground : Color.WHITE;
 		Color fg = new Color(rgb);
 		return ColorHelper.getContrastColor(fg, bg);
 		}
@@ -666,6 +671,22 @@ public abstract class AbstractDepictor<T> {
 		}
 
 
+	private void hiliteAtomBackgrounds() {
+		if (mAtomHiliteColor == null
+		 || (mAtomHiliteColor.length < mMol.getAtoms()))
+			return;
+
+		double d = mTransformation.getScaling() * mMol.getAverageBondLength();
+		double r = d/2;
+		for (int atom=0; atom<mMol.getAtoms(); atom++) {
+			if ((mAtomHiliteColor[atom] & 0xFF000000) != 0) {
+				setColor(new Color(mAtomHiliteColor[atom]));
+	            fillCircle(getAtomX(atom)-r, getAtomY(atom)-r, d);
+				}
+			}
+		}
+
+
 	private void hiliteBondBackgrounds() {
         setLineWidth(2*mpBondHiliteRadius);
         DepictorLine line = new DepictorLine();
@@ -1592,7 +1613,6 @@ public abstract class AbstractDepictor<T> {
         if (!mIsValidatingView)
             onDrawAtom(atom,mMol.getAtomLabel(atom), getAtomX(atom), getAtomY(atom));
 
-
 		String propStr = null;
 		if (mMol.getAtomCharge(atom) != 0) {
 			String valStr = (Math.abs(mMol.getAtomCharge(atom)) == 1) ? ""
@@ -1611,8 +1631,6 @@ public abstract class AbstractDepictor<T> {
 				isoStr = append(isoStr, "!a");
 			if ((queryFeatures & Molecule.cAtomQFMoreNeighbours) != 0)
 				isoStr = append(isoStr, "s");
-//			if ((queryFeatures & Molecule.cAtomQFNoMoreNeighbours) != 0)
-//				isoStr = append(isoStr, "!s");
             if ((queryFeatures & Molecule.cAtomQFHydrogen) != 0) {
                 int hydrogens = (queryFeatures & Molecule.cAtomQFHydrogen);
     			if (hydrogens == Molecule.cAtomQFNot1Hydrogen+Molecule.cAtomQFNot2Hydrogen+Molecule.cAtomQFNot3Hydrogen)
@@ -1766,11 +1784,6 @@ public abstract class AbstractDepictor<T> {
 		int hydrogensToAdd = 0;
 		if ((mDisplayMode & cDModeNoImplicitHydrogen) == 0) {
 			if (mMol.isFragment()) {
-/*  			if ((mMol.getAtomicNo(atom) != 6
-				  || !mAtomIsConnected[atom]
-				  || mMol.getAtomCharge(atom) != 0
-				  || mMol.getAtomRadical(atom) != 0)
-				 && (mMol.getAtomQueryFeatures(atom) & Molecule.cAtomQFNoMoreNeighbours) != 0)*/
 				if ((mMol.getAtomQueryFeatures(atom) & Molecule.cAtomQFNoMoreNeighbours) != 0)
 					hydrogensToAdd = mMol.getImplicitHydrogens(atom);
 				}


=====================================
src/main/java/com/actelion/research/chem/chemicalspaces/ChemicalSpaceCreator.java
=====================================
@@ -82,13 +82,13 @@ public class ChemicalSpaceCreator {
 	}
 	
 	public void create() {
+		Map<String,List<Reaction>> allSynthonTransformations = new HashMap<String,List<Reaction>>();
+		generateSynthonTransformations(reactions,allSynthonTransformations);
 		ConcurrentMap<String,String> processedToOrigIDCode = new ConcurrentHashMap<String,String>();
 		ConcurrentMap<String,List<Map<String,String>>> reactionsWithSynthons = new ConcurrentHashMap<String,List<Map<String,String>>>(); 
 		processBuildingBlocks(this.bbs,processedToOrigIDCode,functionalizations);
 		fps = new ConcurrentHashMap<String,long[]>();
 		calcFragFPs(processedToOrigIDCode.keySet(),fps);
-		Map<String,List<Reaction>> allSynthonTransformations = new ConcurrentHashMap<String,List<Reaction>>();
-		generateSynthonTransformations(reactions,allSynthonTransformations);
 		generateSynthons(reactions, processedToOrigIDCode, reactionsWithSynthons,fps,allSynthonTransformations);
 		generateCombinatoriaLibraries(reactionsWithSynthons, bbs, allSynthonTransformations);
 	}
@@ -225,8 +225,6 @@ public class ChemicalSpaceCreator {
 			final int ii = i;
 			
 			processedToOrigIDCode.keySet().stream().forEach(processedIDcode -> { 
-			//for (String processedIDcode : processedToOrigIDCode.keySet()) {
-				//String processedIDcode= processedToOrigIDCode.get(idcode);
 				StereoMolecule mol = new IDCodeParser().getCompactMolecule(processedIDcode);
 				if (mol != null) {
 					long[] fp = fps.get(processedIDcode);
@@ -309,7 +307,7 @@ public class ChemicalSpaceCreator {
 				functionalizations.add(rxn);
 		}
 		List<Long> sizes = new ArrayList<>();
-		reactions.parallelStream().forEach(reaction -> {
+		reactions.stream().forEach(reaction -> {
 			if(reaction.getReactants()<2)
 				return;
 			IDCodeParser parser = new IDCodeParser();
@@ -342,16 +340,16 @@ public class ChemicalSpaceCreator {
 				precursorLibs.add(precursorLib);
 				Reaction synthonTransformation = synthonTransformations.get(libraryReaction).get(libReactantID);
 				StereoMolecule genericProduct = synthonTransformation.getProduct(0);
-				int offset = 0;
+				int offset = 0; //offset is required to correctly mutate connector atoms
 				for(int a=0;a<genericProduct.getAtoms();a++) {
 					if(genericProduct.getAtomicNo(a)>=92)
 						offset++;
 				}
 				
-				for(Reaction reaction2 : reactions) {
-					if(reaction2.getReactants()!=2) 
+				for(Reaction reactionPrec : reactions) { // precursor reaction
+					if(reactionPrec.getReactants()!=2) 
 						continue;
-					String precursorReaction = reaction2.getName();
+					String precursorReaction = reactionPrec.getName();
 
 					for(int reactantID=0;reactantID<reactionsWithSynthons.get(precursorReaction).size();reactantID++) {
 						List<Map<String,String>> libSynthons = new ArrayList<>();
@@ -359,18 +357,17 @@ public class ChemicalSpaceCreator {
 						precursorName = precursorReaction + "_" + reactantID;
 						precursorLib.put(precursorName, libSynthons);
 						Map<Integer,StereoMolecule> dummyReactants = new HashMap<Integer,StereoMolecule>();
-						for(int l=0;l<reaction2.getReactants();l++) {
+						for(int l=0;l<reactionPrec.getReactants();l++) {
 							if(l==reactantID)
 								continue;
 							else {
-								dummyReactants.put(l,reaction2.getReactant(l));
+								dummyReactants.put(l,reactionPrec.getReactant(l));
 							}
 						}
 						for(int i=0;i<reactionsWithSynthons.get(precursorReaction).size();i++) {
 							Map<String,String> precursorSynthons = new HashMap<String,String>();
 							libSynthons.add(precursorSynthons);
-						}
-						
+						}		
 						Map<String,String> twoConnectorSynthons = libSynthons.get(reactantID); 
 					
 						Map<String,String> synthons = reactionsWithSynthons.get(precursorReaction).get(reactantID);
@@ -378,7 +375,7 @@ public class ChemicalSpaceCreator {
 							StereoMolecule mol = new StereoMolecule();
 							String bb = synthons.get(synthon);
 							parser.parse(mol, synthon);
-							StereoMolecule reactedBB = dummyReaction(bb,reaction2,dummyReactants,reactantID); 
+							StereoMolecule reactedBB = dummyReaction(bb,reactionPrec,dummyReactants,reactantID); 
 							if(reactedBB==null)
 								continue;
 							// we create candidate products by a "dummy reaction" and see if it still matches the substructure query of rxn1
@@ -392,7 +389,7 @@ public class ChemicalSpaceCreator {
 
 							else {
 								for(Reaction functionalization : functionalizations) {
-									if(functionalizations.contains(reaction2))
+									if(functionalizations.contains(reactionPrec))
 										continue; //don't couple two functionalization reactions
 									SSSearcher ssearcher = new SSSearcher();
 									ssearcher.setFragment(functionalization.getReactant(0));
@@ -409,8 +406,7 @@ public class ChemicalSpaceCreator {
 												if(prod==null)
 													continue;
 												mutateConnectorAtoms(prod,offset);
-												//for(int j=0;j<reactantID;j++) 
-												//	mutateConnectorAtoms(prod,offset); //mutate again, to prevent same linker atoms appearing in A and B (C) parts of same library
+						
 												String transformedSynthon = transformToSynthon(synthonTransformation,prod);
 												if(!precursorLib.containsKey(precursorName)) {
 													List<Map<String,String>> libSynthons2 = new ArrayList<>();
@@ -431,7 +427,6 @@ public class ChemicalSpaceCreator {
 						}
 			
 						
-
 						// if the BB that is used in the precursor step also matches any role of the second reaction, it is excluded (otherwise multiple products may be formed)
 						for(int j=0;j<reactionsWithSynthons.get(precursorReaction).size();j++) { //get synthons from rxn1 that are compatible with the two-connector synthon
 							if(j==reactantID) {
@@ -451,11 +446,9 @@ public class ChemicalSpaceCreator {
 									}
 									if(!compatible) //matches also role from second reaction --> don't add to library
 										continue;
-
 	
 									mutateConnectorAtoms(mutatedSynthon,offset);
-									//for(int k=0;k<reactantID;k++) 
-										//mutateConnectorAtoms(mutatedSynthon,offset); //mutate again, to prevent same linker atoms appearing in A and B (C) parts of same library
+									
 									mutatedSynthons.put(mutatedSynthon.getIDCode(), compatibleSynthons.get(s));
 								}
 								libSynthons.get(j).putAll(mutatedSynthons);
@@ -470,9 +463,8 @@ public class ChemicalSpaceCreator {
 			}
 			combiLibrary.cleanup();
 			sizes.add(combiLibrary.getSize());
-			combiLibrary.generateRandomProducts(300,productsWithSynthons,productsWithBBs,productsWithReactions);
-			System.out.println("generated");
-			System.out.println(productsWithSynthons.keySet().size() + " compounds");
+			System.out.println(reaction.getName());
+			combiLibrary.generateRandomProducts(1000,productsWithSynthons,productsWithBBs,productsWithReactions);
 			try {
 				
 				writeCombinatorialLibrary(combiLibrary);
@@ -743,10 +735,12 @@ public class ChemicalSpaceCreator {
 				toRemove = new ArrayList<>();
 			}
 				
-			}
+		}
+		
 		
 		public long getSize() {
 			long sizeOneStep = 1;
+			// first calculate size of the single-step space
 			for(Map<String,String> synthons : bbSynthons) {
 				sizeOneStep*=(long)synthons.size();
 			}
@@ -780,12 +774,17 @@ public class ChemicalSpaceCreator {
 			
 		}
 		
+
+
+	
+		
+		
 		public void generateRandomProducts(int nProducts, Map<String,List<String>> productsWithSynthons, Map<String,List<String>> productsWithBBs, Map<String,
 				List<String>> productsWithReactions ) {
-			int count=0;
 			Random rnd = new Random();
 			IDCodeParser parser = new IDCodeParser();
-			while(count<nProducts) {
+			long max = productsWithSynthons.keySet().size() +  Math.min(getSize(), nProducts);
+			while(productsWithSynthons.keySet().size()<max) {
 				List<StereoMolecule> synthons = new ArrayList<>();
 				List<String> bbs = new ArrayList<>();
 				List<String> reactions = new ArrayList<>();
@@ -794,7 +793,8 @@ public class ChemicalSpaceCreator {
 				reactions.add(reaction.getName());
 				for(int i=0;i<reaction.getReactants();i++) {
 					int r = rnd.nextInt(2);
-					if(r==0) { //pick commercial bb
+					Map<String,List<Map<String,String>>> libs = precursorLibs.get(i);
+					if(libs.size()<1 || r==0) { //pick commercial bb
 						if(bbSynthons.get(i).size()<1)
 							return ;
 						int r2 = rnd.nextInt(bbSynthons.get(i).size());
@@ -809,9 +809,6 @@ public class ChemicalSpaceCreator {
 					else { //create random virtual bb
 						//pick random precursor reaction
 						List<StereoMolecule> precursors = new ArrayList<>();
-						Map<String,List<Map<String,String>>> libs = precursorLibs.get(i);
-						if(libs.size()<1)
-							return;
 						int reactionNr = rnd.nextInt(libs.keySet().size());
 						List<String> keys = new ArrayList<>(libs.keySet());
 						List<Map<String,String>> lib = libs.get(keys.get(reactionNr));
@@ -830,31 +827,36 @@ public class ChemicalSpaceCreator {
 							preCoupledSynthons.add(SynthonReactor.react(precursors));
 						}
 						catch(Exception e) {
-	
+							e.printStackTrace();
+							continue;
 						}
 						
 					}
 				}
-				count++;
+				
 				try {
 					StereoMolecule product = SynthonReactor.react(preCoupledSynthons);
 					List<String> bbIDCodes = synthons.stream().map(e -> e.getIDCode()).collect(Collectors.toList());
+					if(productsWithSynthons.containsKey(product.getIDCode()))
+							continue;
 					productsWithSynthons.put(product.getIDCode(),bbIDCodes);
 					productsWithBBs.put(product.getIDCode(),bbs);
 					productsWithReactions.put(product.getIDCode(),reactions);
 
 				}
 				catch(Exception e) {
+					e.printStackTrace();
 
-
-				}
 				}
+			}
+
 			
 		}
 
 		
 	}
 	
+
 	public static boolean matchesReactionRole(Reaction rxn, SSSearcherWithIndex[] searchers, int component, StereoMolecule reactant,
 			long[] index) {
 		boolean isMatch = true;


=====================================
src/main/java/com/actelion/research/chem/chemicalspaces/synthon/SynthonCreator.java
=====================================
@@ -13,6 +13,7 @@ import java.util.Map;
 import java.util.Set;
 
 import com.actelion.research.chem.Molecule;
+import com.actelion.research.chem.RingCollection;
 import com.actelion.research.chem.StereoMolecule;
 import com.actelion.research.chem.coords.CoordinateInventor;
 import com.actelion.research.chem.io.RXNFileCreator;
@@ -21,6 +22,12 @@ import com.actelion.research.chem.reaction.Reaction;
 public class SynthonCreator {
 	
 	
+	/**
+	 * only works for reactions with a single product
+	 * @param rxn
+	 * @return
+	 * @throws Exception
+	 */
 	public static Reaction[] create(Reaction rxn) throws Exception {
 		if(rxn.getProducts()>1)
 			throw new Exception("only reactions with one product are supported");
@@ -41,219 +48,112 @@ public class SynthonCreator {
 		}
 		//find bonds in products that are formed between a) atoms from different reactants or b) between an unmapped and a mapped atom
 		//in a properly mapped reaction, unmapped atoms stem from a reagent or solvent
-		for(int p=0;p<rxn.getProducts();p++) {
-			StereoMolecule product = rxn.getProduct(p);
-			List<Integer> bondsToCut = new ArrayList<>();
-			for(int b=0;b<product.getBonds();b++) {
-				int bondAtom1 = product.getBondAtom(0, b);
-				int bondAtom2 = product.getBondAtom(1, b);
-				int mappedBondAtom1 = product.getAtomMapNo(bondAtom1);
-				int mappedBondAtom2 = product.getAtomMapNo(bondAtom2);
-				if(mappedBondAtom1==0) {
-					if(mappedBondAtom2==0)
-						continue;
-					else 
-						bondsToCut.add(b);
-						
-				}
-				else if(mappedBondAtom2==0) {
-					bondsToCut.add(b);
+		StereoMolecule product = rxn.getProduct(0);
+		//detect homogeneous rings: homogeneous rings are rings that either consist of only one reactant, or 
+		//one reactant and unmapped (reagent) atoms. Bonds in homogeneous rings should not be cut!
+		RingCollection rc = product.getRingSet();
+		List<Integer> homogeneousRingBonds = new ArrayList<>();
+		for(int ringNo=0;ringNo<rc.getSize();ringNo++) {
+			Set<Integer> ringReactant = new HashSet<Integer>();
+			int[] atoms = rc.getRingAtoms(ringNo);
+			for(int a : atoms) {
+				int mappedA = product.getAtomMapNo(a);
+				if(mappedA==0)
 					continue;
-				}
-				else if(mappedAtomToReactant.get(mappedBondAtom1)!=mappedAtomToReactant.get(mappedBondAtom2)) {
-					bondsToCut.add(b);
-				}
+				int reactant = mappedAtomToReactant.get(mappedA);
+				ringReactant.add(reactant);
 			}
-
-			StereoMolecule decomposedProduct = new StereoMolecule(product); 
-			decomposedProduct.ensureHelperArrays(Molecule.cHelperCIP);
-			int counter = 0;
-			for(int cutBond : bondsToCut) {
-				//first check if cutting this bond would result in isolating a fragment that is made of nonmapped atoms --> stem from a reagent
-				//we want to assign these atoms to one of the synthons, so such a cut is forbidden
-				StereoMolecule tmpMol = new StereoMolecule(decomposedProduct);
-				tmpMol.ensureHelperArrays(Molecule.cHelperNeighbours);
-				tmpMol.setBondType(cutBond, Molecule.cBondTypeDeleted);
-				tmpMol.deleteMarkedAtomsAndBonds();
-				StereoMolecule[] tmpFrags = tmpMol.getFragments();
-				boolean acceptCut = true;
-				for(StereoMolecule tmpFrag : tmpFrags) {
-					tmpFrag.ensureHelperArrays(Molecule.cHelperNeighbours);
-					int mapSum = 0;
-					for(int a=0;a<tmpFrag.getAtoms();a++) {
-						mapSum+=tmpFrag.getAtomMapNo(a);
-					}
-					if(mapSum==0) {
-						acceptCut=false;
-						break;
-					}
-				}
-				if(acceptCut) {
-					int bondType = decomposedProduct.getBondType(cutBond);
-					decomposedProduct.setBondType(cutBond, Molecule.cBondTypeDeleted);
-					int connector1 = decomposedProduct.addAtom(92+counter);
-					int connector2 = decomposedProduct.addAtom(92+counter);
-					int newBond1 = decomposedProduct.addBond(decomposedProduct.getBondAtom(0, cutBond), connector1);
-					decomposedProduct.setBondType(newBond1, bondType);
-					int newBond2 = decomposedProduct.addBond(connector2,decomposedProduct.getBondAtom(1, cutBond));
-					decomposedProduct.setBondType(newBond2, bondType);
-					counter++;
-				}
-				
+			if(ringReactant.size()==1) {//homogeneous ring!
+				int[] ringBonds = rc.getRingBonds(ringNo);
+				Arrays.stream(ringBonds).forEach(e -> homogeneousRingBonds.add(e));
 			}
-			decomposedProduct.deleteMarkedAtomsAndBonds();
-			decomposedProduct.ensureHelperArrays(Molecule.cHelperCIP);
-			StereoMolecule[] frags = decomposedProduct.getFragments();
-			for(StereoMolecule frag : frags) {
-				CoordinateInventor inventor = new CoordinateInventor();
-				inventor.setRandomSeed(0x1234567890L);  // create reproducible coordinates
-				inventor.invent(frag);
-				Reaction reaction = new Reaction();
-				int reactantID = -1;
-				for(int a=0;a<frag.getAtoms();a++) {
-					if(frag.getAtomMapNo(a)!=0) {
-						reactantID = mappedAtomToReactant.get(frag.getAtomMapNo(a));
-					}
-						
-				}
-				if(reactantID==-1)
-					throw new Exception("could not process reaction");
-				frag.ensureHelperArrays(Molecule.cHelperCIP);
-				reaction.addReactant(rxn.getReactant(reactantID));
-				reaction.addProduct(frag);
-				synthonTransformations[reactantID] = reaction;
-				//Writer writer = new BufferedWriter(new FileWriter(rxn.getName() + "_" + i + ".rxn"));
-				//new RXNFileCreator(reaction).writeRXNfile(writer);
-				//writer.close();
-
-				
-
-				
-			}
-		
+			
 		}
-		return synthonTransformations;
-		
-		
-		
-		
-	
-	}
-	/**
-	 * does not allow cuts through ring bonds
-	 * @param rxn
-	 * @return
-	 * @throws Exception
-	 */
-	public static Reaction[] createStrict(Reaction rxn) throws Exception {
-		if(rxn.getProducts()>1)
-			throw new Exception("only reactions with one product are supported");
-		Reaction[] synthonTransformations = new Reaction[rxn.getReactants()];
-		Map<Integer,Integer> mappedAtomToReactant = new HashMap<Integer,Integer>(); //stores the information on which mapped atom in the product is contributed by which reactant
-		for(int r=0;r<rxn.getReactants();r++) {
-			if(rxn.getReactants()==0)
-				throw new Exception("cannot create Synthons for reactions with one reactant");
-			StereoMolecule reactant = rxn.getReactant(r);
-			for(int a=0;a<reactant.getAtoms();a++) {
-				int reactantMapNo = reactant.getAtomMapNo(a);
-				if(reactantMapNo==0)
-					continue;
-				else {
-					mappedAtomToReactant.put(reactantMapNo, r);
-				}
-			}
-		}
-		//find bonds in products that are formed between a) atoms from different reactants or b) between an unmapped and a mapped atom
-		//in a properly mapped reaction, unmapped atoms stem from a reagent or solvent
-		for(int p=0;p<rxn.getProducts();p++) {
-			StereoMolecule product = rxn.getProduct(p);
-			List<Integer> bondsToCut = new ArrayList<>();
-			for(int b=0;b<product.getBonds();b++) {
-				int bondAtom1 = product.getBondAtom(0, b);
-				int bondAtom2 = product.getBondAtom(1, b);
-				int mappedBondAtom1 = product.getAtomMapNo(bondAtom1);
-				int mappedBondAtom2 = product.getAtomMapNo(bondAtom2);
-				if(mappedBondAtom1==0) {
-					if(mappedBondAtom2==0)
-						continue;
-					else 
-						bondsToCut.add(b);
-						
-				}
-				else if(mappedBondAtom2==0) {
-					bondsToCut.add(b);
+		List<Integer> bondsToCut = new ArrayList<>();
+		for(int b=0;b<product.getBonds();b++) {
+			if(homogeneousRingBonds.contains(b))
+				continue;
+			int bondAtom1 = product.getBondAtom(0, b);
+			int bondAtom2 = product.getBondAtom(1, b);
+			int mappedBondAtom1 = product.getAtomMapNo(bondAtom1);
+			int mappedBondAtom2 = product.getAtomMapNo(bondAtom2);
+			if(mappedBondAtom1==0) {
+				if(mappedBondAtom2==0) // both atoms unmapped
 					continue;
-				}
-				else if(mappedAtomToReactant.get(mappedBondAtom1)!=mappedAtomToReactant.get(mappedBondAtom2)) {
+				else //bond between a mapped and an unmapped atom
 					bondsToCut.add(b);
-				}
+					
+			}
+			else if(mappedBondAtom2==0) { //bond between a mapped and an umapped atom
+				bondsToCut.add(b);
+				continue;
+			}
+			else if(mappedAtomToReactant.get(mappedBondAtom1)!=mappedAtomToReactant.get(mappedBondAtom2)) { //atoms from two different reactants
+				bondsToCut.add(b);
 			}
+		}
 
-			StereoMolecule decomposedProduct = new StereoMolecule(product); 
-			decomposedProduct.ensureHelperArrays(Molecule.cHelperCIP);
-			int counter = 0;
-			for(int cutBond : bondsToCut) {
-				//first check if cutting this bond would result in isolating a fragment that is made of nonmapped atoms --> stem from a reagent
-				//we want to assign these atoms to one of the synthons, so such a cut is forbidden
-				StereoMolecule tmpMol = new StereoMolecule(decomposedProduct);
-				tmpMol.ensureHelperArrays(Molecule.cHelperNeighbours);
-				tmpMol.setBondType(cutBond, Molecule.cBondTypeDeleted);
-				tmpMol.deleteMarkedAtomsAndBonds();
-				StereoMolecule[] tmpFrags = tmpMol.getFragments();
-				boolean acceptCut = true;
-				for(StereoMolecule tmpFrag : tmpFrags) {
-					tmpFrag.ensureHelperArrays(Molecule.cHelperNeighbours);
-					int mapSum = 0;
-					for(int a=0;a<tmpFrag.getAtoms();a++) {
-						mapSum+=tmpFrag.getAtomMapNo(a);
-					}
-					if(mapSum==0) {
-						acceptCut=false;
-						break;
-					}
+		StereoMolecule decomposedProduct = new StereoMolecule(product); 
+		decomposedProduct.ensureHelperArrays(Molecule.cHelperCIP);
+		int counter = 0;
+		for(int cutBond : bondsToCut) {
+			//first check if cutting this bond would result in isolating a fragment that is made of nonmapped atoms --> stem from a reagent
+			//we want to assign these atoms to one of the synthons, so such a cut is forbidden
+			StereoMolecule tmpMol = new StereoMolecule(decomposedProduct);
+			tmpMol.ensureHelperArrays(Molecule.cHelperNeighbours);
+			tmpMol.setBondType(cutBond, Molecule.cBondTypeDeleted);
+			tmpMol.deleteMarkedAtomsAndBonds();
+			StereoMolecule[] tmpFrags = tmpMol.getFragments();
+			boolean acceptCut = true;
+			for(StereoMolecule tmpFrag : tmpFrags) {
+				tmpFrag.ensureHelperArrays(Molecule.cHelperNeighbours);
+				int mapSum = 0;
+				for(int a=0;a<tmpFrag.getAtoms();a++) {
+					mapSum+=tmpFrag.getAtomMapNo(a);
 				}
-				if(acceptCut) {
-					int bondType = decomposedProduct.getBondType(cutBond);
-					decomposedProduct.setBondType(cutBond, Molecule.cBondTypeDeleted);
-					int connector1 = decomposedProduct.addAtom(92+counter);
-					int connector2 = decomposedProduct.addAtom(92+counter);
-					int newBond1 = decomposedProduct.addBond(decomposedProduct.getBondAtom(0, cutBond), connector1);
-					decomposedProduct.setBondType(newBond1, bondType);
-					int newBond2 = decomposedProduct.addBond(connector2,decomposedProduct.getBondAtom(1, cutBond));
-					decomposedProduct.setBondType(newBond2, bondType);
-					counter++;
+				if(mapSum==0) {
+					acceptCut=false;
+					break;
 				}
-				
 			}
-			decomposedProduct.deleteMarkedAtomsAndBonds();
-			decomposedProduct.ensureHelperArrays(Molecule.cHelperCIP);
-			StereoMolecule[] frags = decomposedProduct.getFragments();
-			for(StereoMolecule frag : frags) {
-				CoordinateInventor inventor = new CoordinateInventor();
-				inventor.setRandomSeed(0x1234567890L);  // create reproducible coordinates
-				inventor.invent(frag);
-				Reaction reaction = new Reaction();
-				int reactantID = -1;
-				for(int a=0;a<frag.getAtoms();a++) {
-					if(frag.getAtomMapNo(a)!=0) {
-						reactantID = mappedAtomToReactant.get(frag.getAtomMapNo(a));
-					}
-						
+			if(acceptCut) {
+				int bondType = decomposedProduct.getBondType(cutBond);
+				decomposedProduct.setBondType(cutBond, Molecule.cBondTypeDeleted);
+				int connector1 = decomposedProduct.addAtom(92+counter);
+				int connector2 = decomposedProduct.addAtom(92+counter);
+				int newBond1 = decomposedProduct.addBond(decomposedProduct.getBondAtom(0, cutBond), connector1);
+				decomposedProduct.setBondType(newBond1, bondType);
+				int newBond2 = decomposedProduct.addBond(connector2,decomposedProduct.getBondAtom(1, cutBond));
+				decomposedProduct.setBondType(newBond2, bondType);
+				counter++;
+			}
+			
+		}
+		decomposedProduct.deleteMarkedAtomsAndBonds();
+		decomposedProduct.ensureHelperArrays(Molecule.cHelperCIP);
+		StereoMolecule[] frags = decomposedProduct.getFragments();
+		for(StereoMolecule frag : frags) {
+			CoordinateInventor inventor = new CoordinateInventor();
+			inventor.setRandomSeed(0x1234567890L);  // create reproducible coordinates
+			inventor.invent(frag);
+			Reaction reaction = new Reaction();
+			int reactantID = -1;
+			for(int a=0;a<frag.getAtoms();a++) {
+				if(frag.getAtomMapNo(a)!=0) {
+					reactantID = mappedAtomToReactant.get(frag.getAtomMapNo(a));
 				}
-				if(reactantID==-1)
-					throw new Exception("could not process reaction");
-				frag.ensureHelperArrays(Molecule.cHelperCIP);
-				reaction.addReactant(rxn.getReactant(reactantID));
-				reaction.addProduct(frag);
-				synthonTransformations[reactantID] = reaction;
-				//Writer writer = new BufferedWriter(new FileWriter(rxn.getName() + "_" + i + ".rxn"));
-				//new RXNFileCreator(reaction).writeRXNfile(writer);
-				//writer.close();
-
-				
-
-				
+					
 			}
+			if(reactantID==-1)
+				throw new Exception("could not process reaction");
+			frag.ensureHelperArrays(Molecule.cHelperCIP);
+			reaction.addReactant(rxn.getReactant(reactantID));
+			reaction.addProduct(frag);
+			synthonTransformations[reactantID] = reaction;
+			Writer writer = new BufferedWriter(new FileWriter(rxn.getName() + "_" + reactantID + ".rxn"));
+			new RXNFileCreator(reaction).writeRXNfile(writer);
+			writer.close();
+
 		
 		}
 		return synthonTransformations;
@@ -264,7 +164,6 @@ public class SynthonCreator {
 	
 	}
 	
-	
 	/*
 	public static void main(String[] args) {
 		List<Reaction> htmcReactions = ReactionList.INSTANCE.getReactionsHTMC();


=====================================
src/main/java/com/actelion/research/chem/coords/CoordinateInventor.java
=====================================
@@ -108,12 +108,13 @@ public class CoordinateInventor {
 
 
 	/**
-	 * By providing a custom template list containing substructures with predefined atom
-	 * coordinates, any occurence of any of these substructures will receive the
-	 * relative atom coordinates of the provided template, unless the substructure
-	 * shares more than one atom with a previously found substructure or the substructure
-	 * shares more than one atom with the non marked atoms and mode is
-	 * MODE_????_MARKED_ATOM_COORDS.
+	 * A custom template list contains substructures with predefined atom coordinates.
+	 * When such a list is provided, and if a molecules contains one of the list's substructures,
+	 * then the matching atoms will receive the relative atom coordinates of the provided template,
+	 * unless the substructure shares two or more atoms with another earlier found template or
+	 * if mode is MODE_????_MARKED_ATOM_COORDS and the substructure match contains two or more
+	 * non-marked (and therefore untouchable) atoms. If a template substructure contains an E- or Z-
+	 * double bound, then the query feature 'match EZ-parity' should be set.
 	 * @param templateList
 	 */
 	public void setCustomTemplateList(List<InventorTemplate> templateList) {


=====================================
src/main/java/com/actelion/research/chem/coords/InventorFragment.java
=====================================
@@ -195,7 +195,8 @@ public class InventorFragment {
 				boolean coreOnSide = false;
 				boolean coreOffSide = false;
 				for (int i = 0; i< mGlobalAtom.length; i++) {
-					if (mMol.isMarkedAtom(mGlobalAtom[i])) {
+					int atom = mGlobalAtom[i];
+					if (mMol.isMarkedAtom(atom) && atom != atom1 && atom != atom2) {
 						if (isOnSide[mGlobalAtom[i]])
 							coreOnSide = true;
 						else


=====================================
src/main/java/com/actelion/research/chem/descriptor/flexophore/completegraphmatcher/ObjectiveBlurFlexophoreHardMatchUncovered.java
=====================================
@@ -511,6 +511,56 @@ public class ObjectiveBlurFlexophoreHardMatchUncovered implements IObjectiveComp
 
 	}
 
+	/**
+	 *
+	 * @param solution a valid solution for IMolDistHis base and IMolDistHis query. Query and base must be set before
+	 *                 starting the similarity calculation.
+	 * @param indexHeap heap index of the node for which the histogram similarities to all other nodes will be calculated.
+	 *                  indexHeap is the index from the list of matching query and base nodes.
+	 * @return histogram similarity for a single node. Calculated as average from the sum of histogram similarities.
+	 */
+	public float getSimilarityHistogramsForNode(SolutionCompleteGraph solution, int indexHeap) {
+		int heap = solution.getSizeHeap();
+
+		//
+		// the query must hit with all pharmacophore nodes
+		//
+		if(modeQuery) {
+			if (nodesQuery != heap) {
+				return 0;
+			}
+		}
+
+		double sumPairwiseMapping = 0;
+
+		int indexNode1Query = solution.getIndexQueryFromHeap(indexHeap);
+
+		int indexNode1Base = solution.getIndexCorrespondingBaseNode(indexNode1Query);
+
+		for (int i = 0; i < heap; i++) {
+			if(indexHeap==i)
+				continue;
+
+			int indexNode2Query = solution.getIndexQueryFromHeap(i);
+
+			int indexNode2Base = solution.getIndexCorrespondingBaseNode(indexNode2Query);
+
+			double simHists = getSimilarityHistogram(indexNode1Query, indexNode2Query, indexNode1Base, indexNode2Base);
+
+			sumPairwiseMapping += simHists;
+
+			if(verbose) {
+				System.out.println("scorePairwiseMapping " + Formatter.format2(simHists));
+			}
+		}
+
+		double mappings = heap-1;
+
+		double avrPairwiseMapping = sumPairwiseMapping/mappings;
+
+		return (float)avrPairwiseMapping;
+	}
+
 	public long getDeltaNanoQueryBlur() {
 		return deltaNanoQueryBlur;
 	}
@@ -835,12 +885,10 @@ public class ObjectiveBlurFlexophoreHardMatchUncovered implements IObjectiveComp
 		
 		double simHists = getSimilarityHistogram(indexNode1Query, indexNode2Query, indexNode1Base, indexNode2Base);
 		
-		if(simHists==0){
-
-			System.out.println("ObjectiveFlexophoreHardMatchUncovered getScorePairwiseMapping(int indexNode1Query, int indexNode2Query, int indexNode1Base, int indexNode2Base)");
-
-			System.out.println("Sim hists = 0");
-		}
+//		if(simHists==0){
+//			System.out.println("ObjectiveFlexophoreHardMatchUncovered getScorePairwiseMapping(int indexNode1Query, int indexNode2Query, int indexNode1Base, int indexNode2Base)");
+//			System.out.println("Sim hists = 0");
+//		}
 
 		if(verbose){
 			System.out.println("simHists " + Formatter.format2(simHists));


=====================================
src/main/java/com/actelion/research/chem/descriptor/flexophore/example/MatchFlexophoreNodesMain.java
=====================================
@@ -7,8 +7,13 @@ import com.actelion.research.chem.descriptor.DescriptorHandlerFlexophore;
 import com.actelion.research.chem.descriptor.flexophore.ModelSolutionSimilarity;
 import com.actelion.research.chem.descriptor.flexophore.MolDistHistViz;
 import com.actelion.research.chem.descriptor.flexophore.PPNodeViz;
+import com.actelion.research.chem.descriptor.flexophore.completegraphmatcher.ObjectiveBlurFlexophoreHardMatchUncovered;
+import com.actelion.research.gui.table.ChemistryRenderPanel;
+import com.actelion.research.util.ArrayUtils;
 import com.actelion.research.util.Formatter;
 
+import javax.swing.*;
+
 
 public class MatchFlexophoreNodesMain {
 
@@ -26,45 +31,61 @@ public class MatchFlexophoreNodesMain {
         pairMatch(idcode, idcodeQuery);
     }
 
-    public static void pairMatch(String idcode, String idcodeQuery) {
+    public static void pairMatch(String idcodeBase, String idcodeQuery) {
         DescriptorHandlerFlexophore dhFlexophore = new DescriptorHandlerFlexophore();
+
+        ObjectiveBlurFlexophoreHardMatchUncovered objectiveBlurFlexophoreHardMatchUncovered = dhFlexophore.getObjectiveCompleteGraph();
+
         IDCodeParser parser = new IDCodeParser();
 
-        MolDistHistViz mdh = create(parser, dhFlexophore, idcode);
+        MolDistHistViz mdhvBase = create(parser, dhFlexophore, idcodeBase);
+
 
-        System.out.println("Num pp nodes base " + mdh.getNumPPNodes());
 
-        MolDistHistViz mdhQuery = create(parser, dhFlexophore, idcodeQuery);
-        System.out.println("Num pp nodes query " + mdhQuery.getNumPPNodes());
 
-        System.out.println(mdh.toString());
-        System.out.println(mdhQuery.toString());
+        System.out.println("Num pp nodes base " + mdhvBase.getNumPPNodes());
 
-        ModelSolutionSimilarity modelSolutionSimilarity = dhFlexophore.getBestMatch(mdh, mdhQuery);
+        MolDistHistViz mdhvQuery = create(parser, dhFlexophore, idcodeQuery);
+        System.out.println("Num pp nodes query " + mdhvQuery.getNumPPNodes());
+
+        System.out.println(mdhvBase.toString());
+        System.out.println(mdhvQuery.toString());
+
+        ModelSolutionSimilarity modelSolutionSimilarity = dhFlexophore.getBestMatch(mdhvBase, mdhvQuery);
         int heap = modelSolutionSimilarity.getSizeHeap();
 
         // System.out.println(Formatter.format3(sim) + "\t" + Formatter.format3(simDH));
         // System.out.println(Formatter.format3(sim) +"\t"+ Formatter.format3(simNormalized));
 
+        objectiveBlurFlexophoreHardMatchUncovered.setBase(mdhvBase);
+        objectiveBlurFlexophoreHardMatchUncovered.setQuery(mdhvQuery);
+
         for (int i = 0; i <heap; i++) {
 
             int indexQuery = modelSolutionSimilarity.getIndexQueryFromHeap(i);
             int indexBase = modelSolutionSimilarity.getIndexBaseFromHeap(i);
 
-            PPNodeViz ppv = mdh.getNode(indexBase);
-            PPNodeViz ppvQuery = mdhQuery.getNode(indexQuery);
-            System.out.println(ppv.toString());
+            PPNodeViz ppvBase = mdhvBase.getNode(indexBase);
+
+            int [] arrAtomIndexBase = ArrayUtils.toIntArray(ppvBase.getListIndexOriginalAtoms());
+
+            PPNodeViz ppvQuery = mdhvQuery.getNode(indexQuery);
+
+            int [] arrAtomIndexQuery = ArrayUtils.toIntArray(ppvQuery.getListIndexOriginalAtoms());
+
+            System.out.println(ppvBase.toString());
             System.out.println(ppvQuery.toString());
             // System.out.println(Formatter.format3((double)ppv.getSimilarityMappingNodes()) + "\t" + Formatter.format3((double)ppvQuery.getSimilarityMappingNodes()));
-            System.out.println(Formatter.format3((double)modelSolutionSimilarity.getSimilarityNode(indexQuery)));
+
+            float simHistogram = objectiveBlurFlexophoreHardMatchUncovered.getSimilarityHistogramsForNode(modelSolutionSimilarity, i);
+
+            System.out.println("Node similarity " + Formatter.format3((double)modelSolutionSimilarity.getSimilarityNode(indexQuery)) + ", histogram similarity " + Formatter.format3((double)simHistogram) + ".");
 
             System.out.println();
         }
 
         System.out.println("Un-normalized similarity " + Formatter.format3(modelSolutionSimilarity.getSimilarity()));
 
-
-
     }
 
 


=====================================
src/main/java/com/actelion/research/chem/io/CompoundTableConstants.java
=====================================
@@ -181,6 +181,7 @@ public interface CompoundTableConstants {
     String cColumnProperty3DFragmentSplit = "split3D"; // if "true": unconnected fragments of 3D-structure are shown as differently colored V3DMolecules
     String cColumnPropertyCommentUploadStatus = "commentUploadStatus";
     String cColumnPropertyCommentDepartment = "commentDepartment";
+    String cColumnPropertyCalculated = "calculated"; //for columns that can be calculated by a task
 
     String cSuperposeValueReferenceRow = "refRow";  // "reference" or null
     String cSuperposeAlignValueShape = "shape";  // "reference" or null


=====================================
src/main/java/com/actelion/research/chem/io/Mol2FileParser.java
=====================================
@@ -4,31 +4,14 @@
  */
 package com.actelion.research.chem.io;
 
-import java.io.File;
+import com.actelion.research.chem.*;
+
 import java.io.LineNumberReader;
 import java.io.Reader;
 import java.io.Writer;
 import java.text.DecimalFormat;
 import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
-import com.actelion.research.chem.AromaticityResolver;
-import com.actelion.research.chem.Canonizer;
-import com.actelion.research.chem.ExtendedMolecule;
-import com.actelion.research.chem.Molecule3D;
-import com.actelion.research.chem.Molecule;
-import com.actelion.research.chem.SmilesCreator;
-import com.actelion.research.chem.StereoMolecule;
-import com.actelion.research.chem.io.pdb.converter.BondsCalculator;
-import com.actelion.research.chem.io.AbstractParser;
+import java.util.*;
 
 /**
  * 
@@ -87,8 +70,7 @@ public class Mol2FileParser extends AbstractParser {
 			for (int i=0; i<mol.getBonds(); i++) {
 				m.setBondOrder(i, mol.getBondOrder(bondMap[i]));
 			}
-			
-		} 
+		}
 		/*
 		else {
 			//Use BondsCalculator.aromatize
@@ -105,7 +87,6 @@ public class Mol2FileParser extends AbstractParser {
 		m.setAllAtomFlag(Molecule3D.LIGAND, true);
 
 		res.add(m);
-
 	}
 	
 	private void assignCharges(Molecule3D mol) {
@@ -140,9 +121,7 @@ public class Mol2FileParser extends AbstractParser {
 	
 	
 	public static String getChargeType(int type) {
-		
 		if(hmIndex_CHARGETYPE==null){
-			
 			hmIndex_CHARGETYPE = new HashMap<Integer, String>();
 			hmIndex_CHARGETYPE.put(iNO_CHARGES, sNO_CHARGES);
 			hmIndex_CHARGETYPE.put(iDEL_RE, sDEL_RE);
@@ -163,8 +142,7 @@ public class Mol2FileParser extends AbstractParser {
 	
 	
 	/**
-	 * @see com.actelion.research.chem.parsers.AbstractParser#parse(java.io.Reader,
-	 *      com.actelion.research.chem.Molecule3D)
+	 * @see com.actelion.research.chem.io.AbstractParser#loadGroup(String, java.io.Reader, int, int)
 	 */
 	@Override
 	public List<Molecule3D> loadGroup(String fileName, Reader in, int from, int to) throws Exception {
@@ -303,11 +281,8 @@ public class Mol2FileParser extends AbstractParser {
 						} else {
 							throw new RuntimeException("Unknown bond type " + order + ".");
 						}
-						
 					}
 
-					
-
 					int a1 = i1.intValue();
 					int a2 = i2.intValue();
 					int b = m.addBond(a1, a2,order);
@@ -356,9 +331,7 @@ public class Mol2FileParser extends AbstractParser {
 	 */
 	public void save(List<Molecule3D> mols, int chargeType, Writer writer) throws Exception {
 		DecimalFormat df = new DecimalFormat("0.0000");
-		
-		
-		
+
 		for (Molecule3D mol : mols) {
 			
 			//Count the number of bonds and atoms (except lone pairs)
@@ -373,8 +346,7 @@ public class Mol2FileParser extends AbstractParser {
 				if(mol.getAtomicNo(mol.getBondAtom(1, i))<=0) continue;
 				nBonds++;
 			}
-			
-			
+
 			// Write the molecule
 			writer.write("@<TRIPOS>MOLECULE" + NEWLINE);
 			writer.write(mol.getName() + NEWLINE);
@@ -423,10 +395,8 @@ public class Mol2FileParser extends AbstractParser {
 				writer.write(NEWLINE);
 			}
 		}
-
 	}
 
-
 	
 	public static void main(String[] args) throws Exception {
 		List<Molecule3D> res = new Mol2FileParser().loadGroup("c:/mopac11971.mol2");
@@ -434,7 +404,4 @@ public class Mol2FileParser extends AbstractParser {
 		System.out.println("models=" +res.size()+" atm="+res.get(0).getAllAtoms()+" "+res.get(0).getAtoms());
 		//new Mol2FileParser().save(res.get(0), "c:/t.mol2");
 	}
-
-	
-
 }


=====================================
src/main/java/com/actelion/research/gui/JStructureView.java
=====================================
@@ -65,6 +65,7 @@ public class JStructureView extends JComponent implements ActionListener,MouseLi
 	protected int mAllowedDragAction;
 	protected int mAllowedDropAction;
 	private String mWarningMessage;
+	private int[] mAtomHiliteColor;
 
 	public JStructureView() {
         this(null);
@@ -216,6 +217,15 @@ public class JStructureView extends JComponent implements ActionListener,MouseLi
 		mAllowFragmentStatusChangeOnPasteOrDrop = allow;
 		}
 
+	/**
+	 * If you want this tructure view to also draw an atom background with specific colors for every atom,
+	 * then you need to call this method before or just after one of the structureChanged() calls.
+	 * @param argb values with a==0 are not considered (may be null)
+	 */
+	public void setAtomHighlightColors(int[] argb) {
+		mAtomHiliteColor = argb;
+		}
+
 	public boolean canDrop() {
 		return mIsEditable && isEnabled() && !mIsDraggingThis;
 	    }
@@ -257,6 +267,7 @@ public class JStructureView extends JComponent implements ActionListener,MouseLi
 			mDepictor = new GenericDepictor(mDisplayMol);
             mDepictor.setDisplayMode(mDisplayMode);
             mDepictor.setAtomText(mAtomText);
+            mDepictor.setAtomHighlightColors(mAtomHiliteColor);
 
 			if (!isEnabled())
                 mDepictor.setOverruleColor(ColorHelper.getContrastColor(Color.GRAY, bg), bg);


=====================================
src/main/java/com/actelion/research/util/graph/complete/CompleteGraphMatcher.java
=====================================
@@ -153,7 +153,6 @@ public class CompleteGraphMatcher<T extends ICompleteGraph> {
 		initSearch();
 
 		if(nodesBase==1 && nodesQuery==1) {
-			SolutionCompleteGraph solution = liliSolution.get(1).get(0);
 			double sim = objectiveCompleteGraph.getSimilarityNodes(0,0);
 			return sim;
 		}



View it on GitLab: https://salsa.debian.org/java-team/openchemlib/-/compare/eaa5350449d28a28c22c3592b6579017ac1b6822...4569bc2804db071f8f402d61d54cc259ee7da279

-- 
View it on GitLab: https://salsa.debian.org/java-team/openchemlib/-/compare/eaa5350449d28a28c22c3592b6579017ac1b6822...4569bc2804db071f8f402d61d54cc259ee7da279
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20220114/9b929086/attachment.htm>


More information about the pkg-java-commits mailing list