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

com.actelion.research.chem.chemicalspaces.ChemicalSpaceCreator Maven / Gradle / Ivy

There is a newer version: 2024.11.2
Show newest version
package com.actelion.research.chem.chemicalspaces;

import com.actelion.research.chem.*;
import com.actelion.research.chem.chemicalspaces.synthon.SynthonCreator;
import com.actelion.research.chem.chemicalspaces.synthon.SynthonReactor;
import com.actelion.research.chem.descriptor.DescriptorHandlerLongFFP512;
import com.actelion.research.chem.io.DWARFileCreator;
import com.actelion.research.chem.reaction.Reaction;
import com.actelion.research.chem.reaction.Reactor;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;


public class ChemicalSpaceCreator {

	private File outdirectory;
	private Set bbs;
	private Map>> bbData;
	private List reactions;
	private final List functionalizations;

	public ChemicalSpaceCreator(Set bbs, List reactions, File outdirectory) {
		this.bbs = bbs;
		this.reactions = reactions;
		this.outdirectory = outdirectory;
		this.functionalizations = new ArrayList<>(); //reactions that only consist of modifications ("functionalizations") of one building block are treated specially
		for(Reaction rxn : reactions ) {
			if(rxn.getReactants()==1)
				functionalizations.add(rxn);
		}
		reactions.removeAll(functionalizations);
	}
	
	public void setOutdirectory(File outdirectory) {
		this.outdirectory = outdirectory;
	}

	public void setBBs(Set bbs) {
		this.bbs = bbs;
	}

	public void setBBData(Map>> bbData) {
		this.bbData = bbData;
	}

	public void setReactions(List reactions) {
		this.reactions = reactions;
	}
	
	public void create() {
		Map> allSynthonTransformations = new HashMap>();
		generateSynthonTransformations(reactions,allSynthonTransformations);
		ConcurrentMap processedToOrigIDCode = new ConcurrentHashMap();
		ConcurrentMap>> reactionsWithSynthons = new ConcurrentHashMap>>(); 
		processBuildingBlocks(this.bbs,processedToOrigIDCode,functionalizations);
		ConcurrentMap fps = new ConcurrentHashMap<>();
		calcFragFPs(processedToOrigIDCode.keySet(), fps);
		generateSynthons(reactions, processedToOrigIDCode, reactionsWithSynthons, fps,allSynthonTransformations);
		generateCombinatoriaLibraries(reactionsWithSynthons, allSynthonTransformations);
	}
	
	private static void calcFragFPs(Collection idcodes, ConcurrentMap fps) {
		idcodes.parallelStream().forEach(idc -> {
			IDCodeParser parser = new IDCodeParser();
			DescriptorHandlerLongFFP512 dhf = new DescriptorHandlerLongFFP512();
			StereoMolecule mol = new StereoMolecule();
			try {
				parser.parse(mol, idc);
				long[] desc = dhf.createDescriptor(mol);
				fps.put(idc, desc);
			}
			catch(Exception e) {}
		});
	}
	
	private static void processBuildingBlocks(Collection bbs, ConcurrentMap processedToOrigIDCode, List functionalizations) {
		bbs.parallelStream().forEach( idcode -> {
			StereoMolecule mol = new IDCodeParser().getCompactMolecule(idcode);
			if (mol != null) {
				mol.ensureHelperArrays(Molecule.cHelperCIP);
				mol.stripSmallFragments();
				mol.normalizeAmbiguousBonds();
				if(processedToOrigIDCode.get(mol.getIDCode())!=null)
					return;
				processedToOrigIDCode.put(mol.getIDCode(), idcode);
				
				for(Reaction functionalization : functionalizations) {
					SSSearcher searcher = new SSSearcher();
					searcher.setFragment(functionalization.getReactant(0));
					searcher.setMolecule(mol);
					
					if (searcher.isFragmentInMolecule()) {
						StereoMolecule product = getProduct(functionalization,Arrays.asList(mol));
						if(product!=null)
							processedToOrigIDCode.put(product.getIDCode(), idcode);
					}
				}
			}
		});
	}
	
	private static void generateSynthons(List reactions,
		ConcurrentMap processedBBToBB,
		ConcurrentMap>> reactionsWithSynthons,ConcurrentMap fps,
		Map> allSynthonTransformations) {

		for(Reaction rxn : reactions) {
			processReaction(rxn, processedBBToBB, reactionsWithSynthons, fps, allSynthonTransformations);
        }
  	}
	
	private static void generateSynthonTransformations(List reactions, Map> allSynthonTransformations) {
		for(Reaction rxn : reactions) {
			List synthonTransformations = new ArrayList<>();
	     	try {	
	     		Reaction[] transformations = SynthonCreator.create(rxn);
	     		synthonTransformations = Arrays.asList(transformations);
	     	}
	     	catch(Exception e) {
	     		e.printStackTrace();
	     	}
	     	allSynthonTransformations.put(rxn.getName(), synthonTransformations);
		}
	}
	
	private static void processReaction(Reaction rxn,  ConcurrentMap processedToOrigBB, 
			ConcurrentMap>> reactionsWithSynthons, ConcurrentMap fps,
			Map> synthonTransformations) {

		List> reactants = new ArrayList<>();
     	//System.out.println(rxn);
     	getReactants(rxn, processedToOrigBB, reactants,fps);

     	reactionsWithSynthons.putIfAbsent(rxn.getName(), new ArrayList<>());
		
     	//System.out.println("bbs");

     	for(int i=0;i rList = reactants.get(i);
     		ConcurrentMap synthonList = new ConcurrentHashMap();
     		reactionsWithSynthons.get(rxn.getName()).add(synthonList);
     		Reaction synthonTransformation = synthonTransformations.get(rxn.getName()).get(i);

     		//for(String idcode : rList) {

     		rList.parallelStream().forEach(idcode -> {
     			IDCodeParser parser = new IDCodeParser();
     			StereoMolecule bb = new StereoMolecule();
     			parser.parse(bb, idcode);
     			bb.ensureHelperArrays(Molecule.cHelperCIP);
     			String synthonIDCode = transformToSynthon(synthonTransformation,bb);
     			String origIDCode = processedToOrigBB.get(idcode);
     			if(synthonIDCode!=null) {
     				synthonList.put(synthonIDCode, origIDCode);
     			}
     		});
     	}
   	}

	private static void getReactants(Reaction rxn,  ConcurrentMap processedToOrigIDCode,
			List> reactants, Map fps) {
		
		SSSearcherWithIndex[] searchers = new SSSearcherWithIndex[rxn.getReactants()];
		for(int i=0;i reactantList = Collections.synchronizedList(new ArrayList());
			final int ii = i;
			
			processedToOrigIDCode.keySet().stream().forEach(processedIDcode -> { 
				StereoMolecule mol = new IDCodeParser().getCompactMolecule(processedIDcode);
				if (mol != null) {
					long[] fp = fps.get(processedIDcode);
					if(fp==null)
						return;
					boolean matchesReaction = matchesReactionRole(rxn, searchers,ii,mol,fp);
					if(matchesReaction)
						reactantList.add(processedIDcode);
						
				
				}	
			});
			reactants.add(reactantList);
		}
	}
	
	private static String transformToSynthon(Reaction synthonTransformation, StereoMolecule bb) {
		String synthonIDCode = null;
		Reactor reactor = new Reactor(synthonTransformation, Reactor.MODE_RETAIN_COORDINATES
					+Reactor.MODE_FULLY_MAP_REACTIONS+Reactor.MODE_REMOVE_DUPLICATE_PRODUCTS+Reactor.MODE_ALLOW_CHARGE_CORRECTIONS, Integer.MAX_VALUE);
		bb.ensureHelperArrays(Molecule.cHelperCIP);
		reactor.setReactant(0, bb);

		String[][] productCodes = reactor.getProductIDCodes();
		int productCount = getNormalizedProductsCount(reactor.getProducts());
		
		if(productCount==0 || productCount>1)
			return synthonIDCode;
		else {
     		synthonIDCode = productCodes[0][0]; 
			}
		return synthonIDCode;
	}
	
	private static StereoMolecule getProduct(Reaction rxn, List reactants) {
		Reactor reactor = new Reactor(rxn, Reactor.MODE_RETAIN_COORDINATES
					+Reactor.MODE_FULLY_MAP_REACTIONS+Reactor.MODE_REMOVE_DUPLICATE_PRODUCTS+Reactor.MODE_ALLOW_CHARGE_CORRECTIONS, Integer.MAX_VALUE);
		for(int i=0;i normalizedProducts = new HashSet<>();
		for(int i=0;i>> reactionsWithSynthons,
			Map> synthonTransformations) {

		// iterate over reactions twice (inner loop, outer loop)
		// check if synthons from the first reaction match the generic substructure of the second
		Map> productsWithSynthons = new HashMap>();
		Map> productsWithBBs = new HashMap>();
		Map> productsWithReactions = new HashMap>();
		Set functionalizations = new HashSet();
		for(Reaction rxn : reactions) {
			if(rxn.getReactants()==1)
				functionalizations.add(rxn);
		}
		List sizes = new ArrayList<>();
		reactions.stream().forEach(reaction -> {
			if(reaction.getReactants()<2)
				return;
			IDCodeParser parser = new IDCodeParser();
			CombinatorialLibrary combiLibrary = new CombinatorialLibrary();
			combiLibrary.reaction = reaction;
			String libraryReaction = reaction.getName();
			combiLibrary.bbSynthons = reactionsWithSynthons.get(libraryReaction);
			List>>> precursorLibs = new ArrayList<>();
			combiLibrary.precursorLibs = precursorLibs;
			if(reaction.getReactants()>2) { //no addditional steps for 3-cmpd reactions
				combiLibrary.cleanup();
				sizes.add(combiLibrary.getSize());
				try {
					writeCombinatorialLibrary(combiLibrary);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return;
			}
			SSSearcherWithIndex[] searchers = new SSSearcherWithIndex[reaction.getReactants()];
			for(int i=0;i>> precursorLib = new HashMap>>();
				precursorLibs.add(precursorLib);
				Reaction synthonTransformation = synthonTransformations.get(libraryReaction).get(libReactantID);
				StereoMolecule genericProduct = synthonTransformation.getProduct(0);
				int offset = 0; //offset is required to correctly mutate connector atoms
				for(int a=0;a=92)
						offset++;
				}
				
				for(Reaction reactionPrec : reactions) { // precursor reaction
					if(reactionPrec.getReactants()!=2) 
						continue;
					String precursorReaction = reactionPrec.getName();

					for(int reactantID=0;reactantID> libSynthons = new ArrayList<>();
						String precursorName = null;
						precursorName = precursorReaction + "_" + reactantID;
						precursorLib.put(precursorName, libSynthons);
						Map dummyReactants = new HashMap();
						for(int l=0;l precursorSynthons = new HashMap();
							libSynthons.add(precursorSynthons);
						}		
						Map twoConnectorSynthons = libSynthons.get(reactantID); 
					
						Map synthons = reactionsWithSynthons.get(precursorReaction).get(reactantID);
						for(String synthon : synthons.keySet()) {
							StereoMolecule mol = new StereoMolecule();
							String bb = synthons.get(synthon);
							parser.parse(mol, synthon);
//if (reactionPrec.getReactants() <= reactantID)  // to prevent OutOfBoundsExceptions; TLS 25-Mar-2024 in dummyReaction
//	continue;
							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
							if (matchesReactionRole(reaction, searchers, libReactantID, reactedBB,null)) { // synthon also matches library rxn
								mutateConnectorAtoms(mol,offset);
								String transformedSynthon = transformToSynthon(synthonTransformation,mol);
								if(transformedSynthon!=null)
									twoConnectorSynthons.put(transformedSynthon,bb);
							}
							//now check if a functionalization/deprotection step can lead to additional matches to the library rxn
							else {
								for(Reaction functionalization : functionalizations) {
									if(functionalizations.contains(reactionPrec))
										continue; //don't couple two functionalization reactions
									SSSearcher ssearcher = new SSSearcher();
									ssearcher.setFragment(functionalization.getReactant(0));
									ssearcher.setMolecule(reactedBB);
									if (ssearcher.isFragmentInMolecule()) {// can be functionalized
										StereoMolecule product = getProduct(functionalization,Arrays.asList(reactedBB));
										if(product==null)
											continue;
										else {
											if(matchesReactionRole(reaction, searchers,libReactantID, product,null)) { //functionalized BB matches rxn1
												//now functionalize synthon BB and create second linker
												StereoMolecule prod = getProduct(functionalization,Arrays.asList(mol));
												if(prod==null)
													continue;
												mutateConnectorAtoms(prod,offset);
						
												String transformedSynthon = transformToSynthon(synthonTransformation,prod);
												if(!precursorLib.containsKey(precursorName)) {
													List> libSynthons2 = new ArrayList<>();
													precursorLib.put(precursorName, libSynthons2);
													for(int i=0;i precursorSynthons2 = new HashMap();
														libSynthons2.add(precursorSynthons2);
													}
												}
												precursorLib.get(precursorName).get(reactantID).put(transformedSynthon, bb);
											}
										}
									}
								}
							}
						}
						
						// 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 compatibleSynthons = reactionsWithSynthons.get(precursorReaction).get(j);
								Map mutatedSynthons = new HashMap();
								for(String s: compatibleSynthons.keySet()) {
									StereoMolecule mutatedSynthon = new StereoMolecule();
									boolean compatible = true;
									parser.parse(mutatedSynthon, s);
									for(SSSearcherWithIndex sssearcher : searchers) {
										sssearcher.setMolecule(mutatedSynthon,(long[]) null);
										if(sssearcher.isFragmentInMolecule())
											compatible = false;
									}
									if(!compatible) //matches also role from second reaction --> don't add to library
										continue;
	
									mutateConnectorAtoms(mutatedSynthon,offset);
									
									mutatedSynthons.put(mutatedSynthon.getIDCode(), compatibleSynthons.get(s));
								}
								libSynthons.get(j).putAll(mutatedSynthons);
							}
						}
					}
				}
			}
			combiLibrary.cleanup();
			sizes.add(combiLibrary.getSize());
			System.out.println(reaction.getName());
			combiLibrary.generateRandomProducts(1000,productsWithSynthons,productsWithBBs,productsWithReactions);
			try {
				writeCombinatorialLibrary(combiLibrary);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		});
		try {
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("space.dwar"), StandardCharsets.UTF_8));
			DWARFileCreator creator = new DWARFileCreator(writer);
			List synthonColumns = new ArrayList<>();
			for(int i=0;i<4;i++) {
				synthonColumns.add(creator.addStructureColumn("Synthon" + (i + 1), "IDcode"));
			} 
			List bbColumns = new ArrayList<>();
			for(int i=0;i<4;i++) {
				bbColumns.add(creator.addStructureColumn("BB" + (i + 1), "IDcode"));
			}
			List reactionColumns = new ArrayList<>();
			for(int i=0;i<3;i++) {
				reactionColumns.add(creator.addAlphanumericalColumn("Reaction" + (i + 1)));
			}
			
			int structureColumn = creator.addStructureColumn("Product", "IDcode");
			creator.writeHeader(-1);
			productsWithSynthons.entrySet().stream().forEach(e -> {
				creator.setRowStructure(e.getKey(), structureColumn);
				List synthons = e.getValue();
				for(int i=0;i bbs = productsWithBBs.get(e.getKey());
				for(int i=0;i reactions = productsWithReactions.get(e.getKey());
				for(int i=0;i e1+e2);
		System.out.println("totSize");
		System.out.println(size);
	}
	
	private static StereoMolecule dummyReaction(String bbIDCode, Reaction rxn, Map reactants, int reactantID){
		StereoMolecule product = null;
		SSSearcher searcher = new SSSearcher();
		searcher.setFragment(rxn.getReactant(reactantID));
		StereoMolecule mol = new IDCodeParser().getCompactMolecule(bbIDCode);
		if (mol != null) {
			searcher.setMolecule(mol);
			if (searcher.isFragmentInMolecule()) {
				Reactor reactor = new Reactor(rxn, Reactor.MODE_RETAIN_COORDINATES
     					+Reactor.MODE_FULLY_MAP_REACTIONS+Reactor.MODE_REMOVE_DUPLICATE_PRODUCTS+Reactor.MODE_ALLOW_CHARGE_CORRECTIONS, Integer.MAX_VALUE);
				reactor.setReactant(reactantID, mol);
				for(int i : reactants.keySet()) {
					reactor.setReactant(i, reactants.get(i));
				}
				StereoMolecule[][] products = reactor.getProducts();
				if(products.length == 1 && products[0].length == 1)
					product = products[0][0];
			}
		}
		return product;
	}
	
	private static void mutateConnectorAtoms(StereoMolecule mol, int offset) {
		for(int a=0;a=92) {
				atomicNo += offset;
				mol.setAtomicNo(a, atomicNo);
			}
		}
		mol.ensureHelperArrays(Molecule.cHelperRings);
	}

	private  void writeCombinatorialLibrary(CombinatorialLibrary combiLib) throws IOException {
		File htmcdir = new File(this.outdirectory + "/CombinatorialLibraries/");
		htmcdir.mkdir();
		File htmcSubDir = new File(htmcdir.getAbsolutePath() + "/" +  combiLib.reaction.getName());
		htmcSubDir.mkdir();
		File dirA = new File(htmcSubDir.getAbsolutePath() + "/A");
		dirA.mkdir();
		File dirB = new File(htmcSubDir.getAbsolutePath() + "/B");
		dirB.mkdir();
		File dirC = null;
		File dirD = null;
		if(combiLib.bbSynthons.size()>2) {
			dirC = new File(htmcSubDir.getAbsolutePath() + "/C");
			dirC.mkdir();
		}
		if(combiLib.bbSynthons.size()>3) {
			dirD = new File(htmcSubDir.getAbsolutePath() + "/D");
			dirD.mkdir();
		}

		if(combiLib.precursorLibs.size()==2) {
			for(int i=0;i> flowSynthons = combiLib.precursorLibs.get(i).get(flowReaction);
					int counter=1;
					for(Map synthons : flowSynthons) {
						if(synthons.isEmpty())
							continue;
						BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
								new FileOutputStream(flowDir + "_" + counter + ".dwar"), StandardCharsets.UTF_8));
						DWARFileCreator creator = new DWARFileCreator(writer);
						int synthonColumn = creator.addStructureColumn("Synthon", "IDcode");
						int structureColumn = creator.addStructureColumn("Building Block", "IDcode");
						List fields = new ArrayList<>();
						if (bbData != null) {
							bbData.values().stream().forEach(e -> {
								for (String key : e.keySet()) {
									if (!fields.contains(key))
										fields.add(key);
								}
							});
						}
						List fieldIndexes = new ArrayList<>();
						for(String field : fields) {
							int columnIndex = creator.addAlphanumericalColumn(field);
							fieldIndexes.add(columnIndex);
						}

						creator.writeHeader(-1);
						for(String s : synthons.keySet()) {
							String origIDCode = synthons.get(s);
							if (bbData != null) {
								Map> propertyMap = bbData.get(origIDCode);
								for(int j=0;j values = propertyMap.get(field);
									if(values!=null) {
										values.forEach(e -> sb.append(e).append(";"));
									}
									creator.setRowValue(sb.toString(), fieldIndexes.get(j));
								}
							}
							creator.setRowStructure(s, synthonColumn);
							creator.setRowStructure(origIDCode,structureColumn);
							creator.writeCurrentRow();
						}
						creator.writeEnd();
						counter++;
					}
				}
			}
		}

		int i=0;
		for(Map synthons : combiLib.bbSynthons) {
			if(synthons.isEmpty())
				continue;

			File dir = null;
			switch(i) {
				case 0:
					dir = dirA;
					break;
				case 1: 
					dir = dirB;
					break;
				case 2: 
					dir = dirC;
					break;
				case 3: 
					dir = dirD;
					break;
				default: 
					break;
			}

			String outfile = dir + "/" + combiLib.reaction.getName() + ".dwar";
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfile), StandardCharsets.UTF_8));
			DWARFileCreator creator = new DWARFileCreator(writer);
			int synthonColumn = creator.addStructureColumn("Synthon", "IDcode");
			int structureColumn = creator.addStructureColumn("Building Block", "IDcode");
			List fields = new ArrayList<>();
			if (bbData != null) {
				bbData.values().stream().forEach(e -> {
					for (String key : e.keySet()) {
						if (!fields.contains(key))
							fields.add(key);
					}
				});
			}
			List fieldIndeces = new ArrayList<>();
			for(String field : fields) {
				int columnIndex = creator.addAlphanumericalColumn(field);
				fieldIndeces.add(columnIndex);
			}
			creator.writeHeader(-1);
			for(String s : synthons.keySet()) {
				String origIDCode = synthons.get(s);
				if (bbData != null) {
					Map> propertyMap = bbData.get(origIDCode);
					for(int j=0;j values = propertyMap.get(field);
						if(values!=null) {
							values.forEach(e -> sb.append(e + ";"));
						}
						creator.setRowValue(sb.toString(), fieldIndeces.get(j));
					}
				}
				creator.setRowStructure(s, synthonColumn);
				creator.setRowStructure(synthons.get(s),structureColumn);
				creator.writeCurrentRow();
			}
			creator.writeEnd();
			i++;
		}
	}
	
	private static class CombinatorialLibrary {
		public Reaction reaction;
		public List> bbSynthons;
		public List>>> precursorLibs;
		
		List toRemove = new ArrayList<>();
		
		private void cleanup() { //remove precursor reactions with missing synthon sets
			for(Map>> precursorLib : precursorLibs) {
				for(String reaction : precursorLib.keySet()) {
					for(Map synthons : precursorLib.get(reaction)) {
						if(synthons==null)
							toRemove.add(reaction);
						else if(synthons.isEmpty())
							toRemove.add(reaction);
					}
				}
				for(String r : toRemove) {
					precursorLib.remove(r);
				}
				toRemove = new ArrayList<>();
			}
		}
		
		public long getSize() {
			long sizeOneStep = 1;
			// first calculate size of the single-step space
			for(Map synthons : bbSynthons) {
				sizeOneStep*=synthons.size();
			}
			if(precursorLibs.size()==2) {
				long reactantsA = bbSynthons.get(0).size();
				Map>> precursorLibsA = precursorLibs.get(0);
				long reactantsB = bbSynthons.get(1).size();
				Map>> precursorLibsB = precursorLibs.get(1);
				for(String precReaction : precursorLibsA.keySet()) {
					List> precLibA = precursorLibsA.get(precReaction);
					int precSize = 1;
					for(Map precLib : precLibA) {
						precSize*=precLib.size();
					}
					reactantsA += precSize;
				}
				for(String precReaction : precursorLibsB.keySet()) {
					List> precLibB = precursorLibsB.get(precReaction);
					int precSize = 1;
					for(Map precLib : precLibB) {
						precSize*=precLib.size();
					}
					reactantsB += precSize;
				}
				return reactantsA*reactantsB;
			}
			else 
				return sizeOneStep;
		}

		
		public void generateRandomProducts(int nProducts, Map> productsWithSynthons, Map> productsWithBBs, Map> productsWithReactions ) {
			Random rnd = new Random();
			IDCodeParser parser = new IDCodeParser();
			long max = productsWithSynthons.keySet().size() +  Math.min(getSize(), nProducts);
			while(productsWithSynthons.keySet().size() synthons = new ArrayList<>();
				List bbs = new ArrayList<>();
				List reactions = new ArrayList<>();
				List preCoupledSynthons = new ArrayList<>();
				String precursorName = "";
				reactions.add(reaction.getName());
				for(int i=0;i>> libs = precursorLibs.get(i);
					if(libs.isEmpty() || r==0) { //pick commercial bb
						if(bbSynthons.get(i).isEmpty())
							return ;
						int r2 = rnd.nextInt(bbSynthons.get(i).size());
						StereoMolecule mol = new StereoMolecule();
						Map s = bbSynthons.get(i);
						List keys = new ArrayList<>(s.keySet());
						parser.parse(mol, keys.get(r2));
						synthons.add(mol);
						bbs.add(s.get(keys.get(r2)));
						preCoupledSynthons.add(mol);
					}
					else { //create random virtual bb
						//pick random precursor reaction
						List precursors = new ArrayList<>();
						int reactionNr = rnd.nextInt(libs.keySet().size());
						List keys = new ArrayList<>(libs.keySet());
						List> lib = libs.get(keys.get(reactionNr));
						precursorName = keys.get(reactionNr);
						reactions.add(precursorName);
						for(Map precursorBBs : lib) {
							List keySet2 = new ArrayList<>(precursorBBs.keySet());
							int r3 = rnd.nextInt(keySet2.size());
							StereoMolecule mol = new StereoMolecule();
							parser.parse(mol, keySet2.get(r3));
							synthons.add(mol);
							bbs.add(precursorBBs.get(keySet2.get(r3)));
							precursors.add(mol);
						}
						try {
							preCoupledSynthons.add(SynthonReactor.react(precursors));
						}
						catch(Exception e) {
							e.printStackTrace();
						}
					}
				}
				
				try {
					StereoMolecule product = SynthonReactor.react(preCoupledSynthons);
					if(product == null || productsWithSynthons.containsKey(product.getIDCode()))
						continue;
					List bbIDCodes = synthons.stream().map(e -> e.getIDCode()).collect(Collectors.toList());
					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;
		SSSearcherWithIndex searcher = searchers[component];
		searcher.setMolecule(reactant,index);
		if (searcher.isFragmentInMolecule()) {
			//check if reactant also matches other roles in the reaction, if yes, exclude it (to prevent self-polymerization)
			for(int j=0;j




© 2015 - 2024 Weber Informatics LLC | Privacy Policy