1package denoptim.fragmenter;
4import java.io.FileInputStream;
5import java.io.IOException;
6import java.util.ArrayList;
7import java.util.HashMap;
8import java.util.HashSet;
12import java.util.logging.Level;
13import java.util.logging.Logger;
15import javax.vecmath.Point3d;
17import org.openscience.cdk.Bond;
18import org.openscience.cdk.DefaultChemObjectBuilder;
19import org.openscience.cdk.PseudoAtom;
20import org.openscience.cdk.config.Isotopes;
21import org.openscience.cdk.exception.CDKException;
22import org.openscience.cdk.interfaces.IAtom;
23import org.openscience.cdk.interfaces.IAtomContainer;
24import org.openscience.cdk.interfaces.IBond;
25import org.openscience.cdk.interfaces.IIsotope;
26import org.openscience.cdk.io.iterator.IteratingSDFReader;
27import org.openscience.cdk.isomorphism.Mappings;
28import org.openscience.cdk.isomorphism.Pattern;
29import org.openscience.cdk.silent.SilentChemObjectBuilder;
30import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;
32import denoptim.constants.DENOPTIMConstants;
33import denoptim.exception.DENOPTIMException;
34import denoptim.files.FileFormat;
35import denoptim.files.UndetectedFileFormatException;
36import denoptim.graph.APClass;
37import denoptim.graph.AttachmentPoint;
38import denoptim.graph.DGraph;
39import denoptim.graph.Edge;
40import denoptim.graph.Fragment;
41import denoptim.graph.Template;
42import denoptim.graph.Vertex;
43import denoptim.graph.Vertex.BBType;
44import denoptim.graph.rings.RingClosingAttractor;
45import denoptim.io.DenoptimIO;
46import denoptim.io.IteratingAtomContainerReader;
47import denoptim.molecularmodeling.ThreeDimTreeBuilder;
48import denoptim.programs.RunTimeParameters.ParametersType;
49import denoptim.programs.fragmenter.CuttingRule;
50import denoptim.programs.fragmenter.FragmenterParameters;
51import denoptim.programs.fragmenter.MatchedBond;
52import denoptim.utils.DummyAtomHandler;
53import denoptim.utils.FormulaUtils;
54import denoptim.utils.ManySMARTSQuery;
55import denoptim.utils.MoleculeUtils;
56import denoptim.utils.Randomizer;
78 File output, Logger logger)
81 FileInputStream fis =
new FileInputStream(input);
82 IteratingSDFReader reader =
new IteratingSDFReader(fis,
83 DefaultChemObjectBuilder.getInstance());
86 int maxBufferSize = 2000;
87 ArrayList<IAtomContainer> buffer =
new ArrayList<IAtomContainer>(500);
89 while (reader.hasNext())
94 logger.log(Level.FINE,
"Checking elemental analysis of "
95 +
"structure " + index);
97 IAtomContainer mol = reader.next();
101 +
"' not found in molecule " + index +
" in file "
102 + input +
". Cannot compare formula with elemental"
115 logger.log(Level.INFO,
"Inconsistency between elemental "
116 +
"analysis of structure and molecular formula."
117 +
" Rejecting structure " + index +
": "
123 if (buffer.size() >= maxBufferSize)
134 if (buffer.size() < maxBufferSize)
169 }
catch (CDKException e)
171 if (e.getMessage().contains(
"Cannot assign Kekulé structure"))
175 settings.
getLogger().log(Level.WARNING,
"Some bond order "
176 +
"are unset and attempt to kekulize the "
177 +
"system has failed "
178 +
"for structure " + index +
". "
179 +
"This hampers use of SMARTS queries, which "
181 +
"not work as expected. Structure " + index
182 +
" will be rejected. "
183 +
"You can avoid rejection by using "
186 +
"UNSETTOSINGLEBO, but you'll "
187 +
"still be using a peculiar connectivity "
189 +
"many bonds are artificially marked as "
191 +
"avoid use of 'UNSET' bond order. "
192 +
"Further details on the problem: "
196 settings.
getLogger().log(Level.WARNING,
"Failed "
198 +
"for structure " + index
199 +
" but UNSETTOSINGLEBO "
200 +
"keyword used. Forcing use of single bonds to "
201 +
"replace bonds with unset order.");
202 for (IBond bnd : mol.bonds())
204 if (bnd.getOrder().equals(IBond.Order.UNSET))
206 bnd.setOrder(IBond.Order.SINGLE);
229 File output, Logger logger)
232 FileInputStream fis =
new FileInputStream(input);
233 IteratingSDFReader reader =
new IteratingSDFReader(fis,
234 DefaultChemObjectBuilder.getInstance());
237 Map<String, String> smartsMap =
new HashMap<String, String>();
238 for (String s : smarts)
241 smartsMap.put(
"prefilter-"+i, s);
245 int maxBufferSize = 2000;
246 ArrayList<IAtomContainer> buffer =
new ArrayList<IAtomContainer>(500);
248 while (reader.hasNext())
253 logger.log(Level.FINE,
"Prefiltering structure " + index);
255 IAtomContainer mol = reader.next();
260 String msg =
"WARNING! Problems while searching for "
261 +
"specific atoms/bonds using SMARTS: "
267 if (allMatches.size()==0)
272 for (String s : allMatches.keySet())
273 hits = hits + DenoptimIO.NL + smartsMap.get(s);
276 logger.log(Level.INFO,
"Found match for " + hits
277 +
"Rejecting structure " + index +
": "
283 if (buffer.size() >= maxBufferSize)
293 if (buffer.size() < maxBufferSize)
322 File output, Logger logger)
throws CDKException, IOException,
337 logger.log(Level.FINE,
"Fragmenting structure " + index);
339 IAtomContainer mol = iterator.
next();
340 String molName =
"noname-mol" + index;
341 if (mol.getTitle()!=
null && !mol.getTitle().isBlank())
342 molName = mol.getTitle();
345 List<Vertex> fragments =
new ArrayList<Vertex>();
346 if (settings.getFragmentationTmpls().size()>0)
348 fragments =
fragmentation(mol, settings.getFragmentationTmpls(),
349 settings.getRandomizer(), logger);
356 logger.log(Level.FINE,
"Fragmentation produced "
357 + fragments.size() +
" fragments.");
359 totalProd += fragments.size();
362 List<Vertex> keptFragments =
new ArrayList<Vertex>();
364 for (
Vertex frag : fragments)
367 String fragIdStr =
"From_" + molName +
"_" + fragCounter;
368 frag.setProperty(
"cdk:Title", fragIdStr);
371 keptFragments, logger);
375 logger.log(Level.FINE,
"Fragments surviving post-"
376 +
"processing: " + keptFragments.size());
378 totalKept += keptFragments.size();
379 if (!settings.doManageIsomorphicFamilies() && totalKept>0)
394 logger.log(Level.WARNING,
"No fragment produced. Cutting rules "
395 +
"were ineffective on the given structures.");
398 }
else if (totalKept==0)
402 logger.log(Level.WARNING,
"No fragment kept out of " + totalProd
403 +
" produced fragments. Filtering criteria might be "
404 +
"too restrictive.");
426 Set<IAtom> boundaryAtoms =
new HashSet<>();
427 Map<IAtom, Long> atomToVertexId =
new HashMap<>();
430 for (IAtom atom : templateMol.atoms())
438 Long vid = Long.parseLong(vidProp.toString());
439 atomToVertexId.put(atom, vid);
442 List<IAtom> neighbors = templateMol.getConnectedAtomsList(atom);
443 for (IAtom neighbor : neighbors)
446 if (nbrVidProp !=
null)
448 Long nbrVid = Long.parseLong(nbrVidProp.toString());
449 if (!vid.equals(nbrVid))
451 boundaryAtoms.add(atom);
452 boundaryAtoms.add(neighbor);
460 if (boundaryAtoms.isEmpty())
466 Set<IAtom> atomsToKeep =
new HashSet<>(boundaryAtoms);
469 List<IAtom> boundaryList =
new ArrayList<>(boundaryAtoms);
470 for (
int i = 0; i < boundaryList.size(); i++)
472 for (
int j = i + 1; j < boundaryList.size(); j++)
474 IAtom start = boundaryList.get(i);
475 IAtom end = boundaryList.get(j);
481 atomsToKeep.addAll(path);
487 IAtomContainer reduced = SilentChemObjectBuilder.getInstance().newAtomContainer();
488 Map<IAtom, IAtom> originalToReduced =
new HashMap<>();
491 for (IAtom originalAtom : atomsToKeep)
493 IAtom reducedAtom = originalAtom.getBuilder().newInstance(IAtom.class, originalAtom);
494 reduced.addAtom(reducedAtom);
495 originalToReduced.put(originalAtom, reducedAtom);
498 int originalIndex = templateMol.indexOf(originalAtom);
499 reducedAtom.setProperty(
"DENOPTIM_ORIGINAL_ATOM_INDEX", originalIndex);
502 for (Object key : originalAtom.getProperties().keySet())
504 if (!key.equals(
"DENOPTIM_ORIGINAL_ATOM_INDEX"))
506 reducedAtom.setProperty(key, originalAtom.getProperty(key));
512 for (IBond bond : templateMol.bonds())
514 IAtom atom1 = bond.getAtom(0);
515 IAtom atom2 = bond.getAtom(1);
517 if (atomsToKeep.contains(atom1) && atomsToKeep.contains(atom2))
519 IBond newBond = bond.getBuilder().newInstance(IBond.class,
520 originalToReduced.get(atom1), originalToReduced.get(atom2), bond.getOrder());
521 reduced.addBond(newBond);
540 List<DGraph> templates,
Randomizer randomizer, Logger logger)
543 List<Vertex> fragments =
new ArrayList<Vertex>();
545 for (
DGraph template : templates)
555 List<Map<IAtom,IAtom>> atomMappings;
558 if (reducedTemplateMol == templateMol)
567 reducedTemplateMol, mol, logger);
570 atomMappings =
new ArrayList<>();
571 for (Map<IAtom,IAtom> reducedMapping : reducedAtomMappings)
573 Map<IAtom,IAtom> fullMapping =
new HashMap<>();
574 for (Map.Entry<IAtom,IAtom> entry : reducedMapping.entrySet())
576 IAtom reducedAtom = entry.getKey();
577 IAtom molAtom = entry.getValue();
580 Object indexObj = reducedAtom.getProperty(
"DENOPTIM_ORIGINAL_ATOM_INDEX");
581 if (indexObj !=
null)
583 int originalIndex = ((Number) indexObj).intValue();
584 IAtom originalAtom = templateMol.getAtom(originalIndex);
585 if (originalAtom !=
null)
587 fullMapping.put(originalAtom, molAtom);
591 if (!fullMapping.isEmpty())
593 atomMappings.add(fullMapping);
603 for (Map<IAtom,IAtom> atomMapping : atomMappings)
607 masterFrag, masterFragIAC, mol, atomMapping);
608 }
catch (Throwable e) {
610 logger.log(Level.WARNING,
"Error while exploring the template graph: " + e.getMessage());
616 List<Vertex> locfragments =
new ArrayList<Vertex>();
617 Set<Integer> doneAlready =
new HashSet<Integer>();
620 if (doneAlready.contains(idx))
626 atmsToKeep.stream().forEach(atm -> doneAlready.add(iac.indexOf(atm)));
628 Set<IAtom> atmsToRemove =
new HashSet<IAtom>();
629 for (IAtom atm : cloneOfMaster.
atoms())
631 if (!atmsToKeep.contains(atm))
633 atmsToRemove.add(atm);
638 locfragments.add(cloneOfMaster);
641 if (locfragments.size() > bestMatch)
643 bestMatch = locfragments.size();
644 fragments = locfragments;
657 Fragment masterFrag, IAtomContainer masterFragIAC, IAtomContainer mol,
658 Map<IAtom,IAtom> graphToMolMapping)
663 IAtom graphAtmSrc = graphIAC.getAtom(edge.getSrcAP().getAtomPositionNumberInMol());
664 IAtom graphAtmTrg = graphIAC.getAtom(edge.getTrgAP().getAtomPositionNumberInMol());
666 IAtom masterFragAtmSrc = masterFragIAC.getAtom(mol.indexOf(graphToMolMapping.get(graphAtmSrc)));
667 IAtom masterFragAtmTrg = masterFragIAC.getAtom(mol.indexOf(graphToMolMapping.get(graphAtmTrg)));
669 IBond bnd = masterFragIAC.getBond(masterFragAtmSrc, masterFragAtmTrg);
672 masterFragIAC.removeBond(bnd);
676 edge.getSrcAP().getAPClass(),
679 edge.getTrgAP().getAPClass(),
710 Map<String, List<MatchedBond>> matchingbonds =
717 String ruleName = rule.getName();
720 if (!matchingbonds.keySet().contains(ruleName))
725 IAtom atmA = tb.getAtmSubClass0();
726 IAtom atmB = tb.getAtmSubClass1();
729 if (!fragsMol.getConnectedAtomsList(atmA).contains(atmB))
740 IAtom centralAtm = atmA;
744 ArrayList<IAtom> candidatesForHapto =
new ArrayList<IAtom>();
745 for (
MatchedBond tbForHapto : matchingbonds.get(ruleName))
748 if (tbForHapto.getAtmSubClass0() == centralAtm)
749 candidatesForHapto.add(tbForHapto.getAtmSubClass1());
754 Set<IAtom> atmsInHapto =
new HashSet<IAtom>();
755 atmsInHapto.add(tb.getAtmSubClass1());
757 centralAtm, candidatesForHapto, fragsMol);
758 if (atmsInHapto.size() == 1)
760 logger.log(Level.WARNING,
"Unable to find more than one "
761 +
"bond involved in high-hapticity ligand! "
767 boolean isSystemIntact =
true;
768 for (IAtom ligAtm : atmsInHapto)
770 List<IAtom> nbrsOfLigAtm =
771 fragsMol.getConnectedAtomsList(ligAtm);
772 if (!nbrsOfLigAtm.contains(centralAtm))
774 isSystemIntact =
false;
786 Point3d dummyP3d =
new Point3d();
787 for (IAtom ligAtm : atmsInHapto)
790 dummyP3d.x = dummyP3d.x + ligP3d.x;
791 dummyP3d.y = dummyP3d.y + ligP3d.y;
792 dummyP3d.z = dummyP3d.z + ligP3d.z;
795 dummyP3d.x = dummyP3d.x / (double) atmsInHapto.size();
796 dummyP3d.y = dummyP3d.y / (double) atmsInHapto.size();
797 dummyP3d.z = dummyP3d.z / (double) atmsInHapto.size();
801 IAtom dummyAtm =
null;
802 for (IAtom oldDu : fragsMol.atoms())
807 Point3d oldDuP3d = oldDu.getPoint3d();
808 if (oldDuP3d.distance(dummyP3d) < 0.002)
819 dummyAtm.setPoint3d(dummyP3d);
820 fragsMol.addAtom(dummyAtm);
826 IBond.Order border = IBond.Order.valueOf(
"SINGLE");
828 for (IAtom ligAtm : atmsInHapto)
830 List<IAtom> nbrsOfDu = fragsMol.getConnectedAtomsList(
832 if (!nbrsOfDu.contains(ligAtm))
835 Bond bnd =
new Bond(dummyAtm,ligAtm,border);
836 fragsMol.addBond(bnd);
839 IBond oldBnd = fragsMol.getBond(centralAtm,ligAtm);
840 fragsMol.removeBond(oldBnd);
857 IBond bnd = fragsMol.getBond(atmA,atmB);
858 fragsMol.removeBond(bnd);
875 List<Vertex> fragments =
new ArrayList<Vertex>();
876 Set<Integer> doneAlready =
new HashSet<Integer>();
879 if (doneAlready.contains(idx))
885 atmsToKeep.stream().forEach(atm -> doneAlready.add(iac.indexOf(atm)));
887 Set<IAtom> atmsToRemove =
new HashSet<IAtom>();
888 for (IAtom atm : cloneOfMaster.
atoms())
890 if (!atmsToKeep.contains(atm))
892 atmsToRemove.add(atm);
897 fragments.add(cloneOfMaster);
918 ArrayList<IAtom> candidates, IAtomContainer mol)
920 Set<IAtom> atmsInHapto =
new HashSet<IAtom>();
921 atmsInHapto.add(seed);
922 ArrayList<IAtom> toVisitAtoms =
new ArrayList<IAtom>();
923 toVisitAtoms.add(seed);
924 ArrayList<IAtom> visitedAtoms =
new ArrayList<IAtom>();
925 while (toVisitAtoms.size()>0)
927 ArrayList<IAtom> toVisitLater =
new ArrayList<IAtom>();
928 for (IAtom atomInFocus : toVisitAtoms)
930 if (visitedAtoms.contains(atomInFocus)
931 || atomInFocus==centralAtom)
934 visitedAtoms.add(atomInFocus);
936 if (candidates.contains(atomInFocus))
938 atmsInHapto.add(atomInFocus);
939 toVisitLater.addAll(mol.getConnectedAtomsList(atomInFocus));
942 toVisitAtoms.clear();
943 toVisitAtoms.addAll(toVisitLater);
959 Set<IAtom> atmsReachableFromSeed =
new HashSet<IAtom>();
960 ArrayList<IAtom> toVisitAtoms =
new ArrayList<IAtom>();
961 toVisitAtoms.add(seed);
962 ArrayList<IAtom> visitedAtoms =
new ArrayList<IAtom>();
963 while (toVisitAtoms.size()>0)
965 ArrayList<IAtom> toVisitLater =
new ArrayList<IAtom>();
966 for (IAtom atomInFocus : toVisitAtoms)
968 if (visitedAtoms.contains(atomInFocus))
971 visitedAtoms.add(atomInFocus);
973 atmsReachableFromSeed.add(atomInFocus);
974 toVisitLater.addAll(mol.getConnectedAtomsList(atomInFocus));
976 toVisitAtoms.clear();
977 toVisitAtoms.addAll(toVisitLater);
979 return atmsReachableFromSeed;
993 IAtomContainer mol, List<CuttingRule> rules, Logger logger)
996 Map<String,String> smarts =
new HashMap<String,String>();
999 smarts.put(rule.getName(),rule.getWholeSMARTSRule());
1003 Map<String, List<MatchedBond>> bondsMatchingRules =
1004 new HashMap<String, List<MatchedBond>>();
1008 if (msq.hasProblems())
1012 logger.log(Level.WARNING,
"Problem matching SMARTS: "
1013 + msq.getMessage());
1015 return bondsMatchingRules;
1020 String ruleName = rule.getName();
1022 if (msq.getNumMatchesOfQuery(ruleName) == 0)
1028 Mappings purgedPairs = msq.getMatchesOfSMARTS(ruleName);
1031 ArrayList<MatchedBond> bondsMatched =
new ArrayList<MatchedBond>();
1032 for (
int[] pair : purgedPairs)
1036 throw new Error(
"Cutting rule: " + ruleName
1037 +
" has identified " + pair.length +
" atoms "
1038 +
"instead of 2. Modify rule to make it find a "
1039 +
"pair of atoms.");
1042 mol.getAtom(pair[1]), rule);
1046 bondsMatched.add(tb);
1049 if (!bondsMatched.isEmpty())
1050 bondsMatchingRules.put(ruleName, bondsMatched);
1053 return bondsMatchingRules;
1068 FileInputStream fis =
new FileInputStream(input);
1069 IteratingSDFReader reader =
new IteratingSDFReader(fis,
1070 DefaultChemObjectBuilder.getInstance());
1073 int maxBufferSize = 2000;
1074 ArrayList<Vertex> buffer =
new ArrayList<Vertex>(500);
1076 while (reader.hasNext())
1081 logger.log(Level.FINE,
"Processing fragment " + index);
1088 if (buffer.size() >= maxBufferSize)
1098 if (buffer.size() < maxBufferSize)
1127 List<Vertex> collector, Logger logger)
1138 if (settings.getIgnorableFragments().size() > 0)
1140 if (settings.getIgnorableFragments().stream()
1141 .anyMatch(ignorable -> ((
Fragment)frag)
1142 .isIsomorphicTo(ignorable)))
1146 logger.log(Level.FINE,
"Fragment " + fragCounter
1147 +
" is ignorable.");
1154 if (settings.getTargetFragments().size() > 0)
1156 if (!settings.getTargetFragments().stream()
1157 .anyMatch(ignorable -> ((
Fragment)frag)
1158 .isIsomorphicTo(ignorable)))
1162 logger.log(Level.FINE,
"Fragment " + fragCounter
1163 +
" doesn't match any target: rejected.");
1171 && settings.doAddDuOnLinearity())
1174 settings.getLinearAngleLimit());
1181 if (settings.doManageIsomorphicFamilies())
1183 synchronized (settings.MANAGEMWSLOTSSLOCK)
1186 settings.getMWSlotSize());
1188 File mwFileUnq = settings.getMWSlotFileNameUnqFrags(
1190 File mwFileAll = settings.getMWSlotFileNameAllFrags(
1194 Vertex unqVersion =
null;
1195 if (mwFileUnq.exists())
1197 ArrayList<Vertex> knownFrags =
1199 unqVersion = knownFrags.stream()
1200 .filter(knownFrag ->
1201 ((
Fragment)frag).isIsomorphicTo(knownFrag))
1205 if (unqVersion!=
null)
1214 int sampleSize = settings.getIsomorphsCount()
1216 if (sampleSize < settings.getIsomorphicSampleSize())
1222 settings.getIsomorphsCount().put(isoFamID,
1226 collector.add(frag);
1247 String isoFamID = settings.newIsomorphicFamilyID();
1251 settings.getIsomorphsCount().put(isoFamID, 1);
1256 collector.add(frag);
1261 collector.add(frag);
1299 for (IAtom atm : frag.
atoms())
1310 logger.log(Level.FINE,
"Removing fragment contains non-element '"
1320 Point3d ap3d = ap.getDirectionVector();
1323 for (IAtom atm : frag.
atoms())
1326 double dist = ap3d.distance(atm3d);
1329 logger.log(Level.FINE,
"Removing fragment with AP"
1341 for (IAtom atm : frag.
atoms())
1346 if (atm.getMassNumber() ==
null)
1350 int a = atm.getMassNumber();
1352 IIsotope major = Isotopes.getInstance().getMajorIsotope(symb);
1353 if (a != major.getMassNumber())
1355 logger.log(Level.FINE,
"Removing fragment containing "
1356 +
"isotope "+symb+a+
".");
1359 }
catch (Throwable t) {
1360 logger.log(Level.WARNING,
"Not able to perform Isotope"
1372 for (IAtom atm : frag.
atoms())
1377 logger.log(Level.FINE,
"Removing fragment containing '"
1390 for (Map<String,Double> criterion :
1393 for (String el : criterion.keySet())
1395 if (eaMol.containsKey(el))
1398 if (eaMol.get(el) - criterion.get(el) > 0.5)
1400 logger.log(Level.FINE,
"Removing fragment that "
1401 +
"contains too much '" + el +
"' "
1402 +
"as requested by formula"
1403 +
"-based (more-than) settings (" + el
1404 + eaMol.get(el) +
" > " + criterion +
").");
1412 for (String el : criterion.keySet())
1414 if (!eaMol.containsKey(el))
1416 logger.log(Level.FINE,
"Removing fragment that does not "
1417 +
"contain '" + el +
"' as requested by formula"
1418 +
"-based (less-than) settings.");
1422 if (eaMol.get(el) - criterion.get(el) < -0.5)
1424 logger.log(Level.FINE,
"Removing fragment that "
1425 +
"contains too little '" + el +
"' "
1426 +
"as requested by formula"
1427 +
"-based settings (" + el
1428 + eaMol.get(el) +
" < " + criterion +
").");
1442 if (apc.toString().startsWith(s))
1444 logger.log(Level.FINE,
"Removing fragment with APClass "
1454 loopOverCombinations:
1457 for (
int ip=0; ip<conditions.length; ip++)
1459 String condition = conditions[ip];
1460 boolean found =
false;
1463 if (apc.toString().startsWith(condition))
1470 continue loopOverCombinations;
1476 String allCondsAsString =
"";
1477 for (
int i=0; i<conditions.length; i++)
1478 allCondsAsString = allCondsAsString +
" " + conditions[i];
1480 logger.log(Level.FINE,
"Removing fragment with combination of "
1481 +
"APClasses matching '" + allCondsAsString +
"'.");
1489 int totHeavyAtm = 0;
1490 for (IAtom atm : frag.
atoms())
1495 if ((!symb.equals(
"H")) && (!symb.equals(
1503 logger.log(Level.FINE,
"Removing fragment with too many atoms ("
1504 + totHeavyAtm +
" < "
1512 logger.log(Level.FINE,
"Removing fragment with too few atoms ("
1513 + totHeavyAtm +
" < "
1526 logger.log(Level.WARNING,
"Problems evaluating SMARTS-based "
1527 +
"rejection criteria. " + msq.
getMessage());
1534 logger.log(Level.FINE,
"Removing fragment that matches "
1535 +
"SMARTS-based rejection criteria '" + criterion
1548 logger.log(Level.WARNING,
"Problems evaluating SMARTS-based "
1549 +
"rejection criteria. " + msq.
getMessage());
1552 boolean matchesAny =
false;
1563 logger.log(Level.FINE,
"Removing fragment that does not "
1564 +
"match any SMARTS-based retention criteria.");
1584 if (a.getImplicitHydrogenCount()==
null)
1585 a.setImplicitHydrogenCount(0);
1588 int slotNum = (int) (mw / (Double.valueOf(slotSize)));
1589 return slotNum*slotSize +
"-" + (slotNum+1)*slotSize;
1597 IAtomContainer mol = SilentChemObjectBuilder.getInstance()
1598 .newAtomContainer();
1599 Point3d apv = ap.getDirectionVector();
1603 Double.valueOf(apv.x),
1604 Double.valueOf(apv.y),
1605 Double.valueOf(apv.z))));
1611 ap.getOwner().getIAtomContainer().getAtom(
1612 ap.getAtomPositionNumber()));
1613 rcv.
addAP(0, rcvApClass,
new Point3d(
1614 Double.valueOf(aps.x),
1615 Double.valueOf(aps.y),
1616 Double.valueOf(aps.z)));
General set of constants used in DENOPTIM.
static final Object FORMULASTR
Property name used to store molecular formula as string in an atom container.
static final String ATMPROPVERTEXID
String tag of Atom property used to store the unique ID of the Vertex corresponding to the molecular ...
static final String DUMMYATMSYMBOL
Symbol of dummy atom.
static final Object ISOMORPHICFAMILYID
Property used to store the identifier of the family of isomorphic fragments that owns a fragment.
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
Container for the list of vertices and the edges that connect them.
List< Vertex > getVertexList()
List< Edge > getEdgeList()
This class represents the edge between two vertices.
Class representing a continuously connected portion of chemical object holding attachment points.
void addAP(int atomPositionNumber)
Adds an attachment point with a dummy APClass.
AttachmentPoint addAPOnAtom(IAtom srcAtm, APClass apc, Point3d vector)
Add an attachment point to the specifies atom.
List< AttachmentPoint > getAttachmentPoints()
Fragment clone()
Returns a deep copy of this fragments.
Iterable< IAtom > atoms()
IAtomContainer getIAtomContainer()
void removeAtoms(Collection< IAtom > atoms)
Removes a list of atoms and updates the list of attachment points.
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
ArrayList< APClass > getAllAPClasses()
Returns the list of all APClasses present on this vertex.
void setAsRCV(boolean isRCV)
Object getProperty(Object property)
abstract IAtomContainer getIAtomContainer()
void setProperty(Object key, Object property)
The RingClosingAttractor represent the available valence/connection that allows to close a ring.
static final HashMap< APClass, String > RCALABELPERAPCLASS
Conventional labels for attractor pseudoatom.
Utility methods for input/output.
static File writeVertexesToFile(File file, FileFormat format, List< Vertex > vertexes)
Writes vertexes to file.
static void writeSDFFile(String fileName, IAtomContainer mol)
Writes IAtomContainer to SDF file.
static File writeVertexToFile(File file, FileFormat format, Vertex vertex, boolean append)
Writes vertexes to file.
static ArrayList< Vertex > readVertexes(File file, Vertex.BBType bbt)
Reads Vertexes from any file that can contain such items.
An iterator that take IAtomContainers from a file, possibly using an available iterating reader,...
void close()
Close the memory-efficient iterator if any is open.
Tool to build build three-dimensional (3D) tree-like molecular structures from DGraph.
IAtomContainer convertGraphTo3DAtomContainer(DGraph graph)
Created a three-dimensional molecular representation from a given DGraph.
Logger getLogger()
Get the name of the program specific logger.
A cutting rule with three SMARTS queries (atom 1, bond, atom2) and options.
Parameters controlling execution of the fragmenter.
boolean doRejectWeirdIsotopes
Flag requesting to reject fragments with minor isotopes.
Map< String, Double > getRejectedFormulaLessThan()
int getMinFragHeavyAtomCount()
Set< String > getRejectedElements()
Map< String, String > getFragRetentionSMARTS()
int getMaxFragHeavyAtomCount()
Set< Map< String, Double > > getRejectedFormulaMoreThan()
Map< String, String > getFragRejectionSMARTS()
Set< String[]> getRejectedAPClassCombinations()
boolean addExplicitH
Flag requesting to add explicit H atoms.
Set< String > getRejectedAPClasses()
boolean acceptUnsetToSingeBO()
Boolean satisfiesRuleOptions
Flag indicating that we have checked the additional option from the cutting rule (otherwise this flag...
Toll to add/remove dummy atoms from linearities or multi-hapto sites.
static void addDummiesOnLinearities(Fragment frag, double angLim)
Append dummy atoms on otherwise linear arrangements of atoms.
Container of lists of atoms matching a list of SMARTS.
Map< String, Mappings > getAllMatches()
int getNumMatchesOfQuery(String query)
Utilities for molecule conversion.
static void setZeroImplicitHydrogensToAllAtoms(IAtomContainer iac)
Sets zero implicit hydrogen count to all atoms.
static int getDimensions(IAtomContainer mol)
Determines the dimensionality of the given chemical object.
static String getSymbolOrLabel(IAtom atm)
Gets either the elemental symbol (for standard atoms) of the label (for pseudo-atoms).
static List< Map< IAtom, IAtom > > findUniqueAtomMappings(IAtomContainer substructure, IAtomContainer mol, Logger logger)
Finds the maximum common substructure (MCS) between two molecules.
static void ensureNoUnsetBondOrders(IAtomContainer iac)
Sets bond order = single to all otherwise unset bonds.
static void explicitHydrogens(IAtomContainer mol)
Converts all the implicit hydrogens to explicit.
static List< IAtom > findShortestPath(IAtomContainer mol, IAtom start, IAtom end, Map< IAtom, Long > atomToVertexId)
Finds the shortest path between two atoms in a molecule using BFS.
static Point3d getPoint3d(IAtom atm)
Return the 3D coordinates, if present.
static boolean isElement(IAtom atom)
Check element symbol corresponds to real element of Periodic Table.
Tool to generate random numbers and random decisions.
The type of building block.
Identifier of the type of parameters.
FRG_PARAMS
Parameters controlling the fragmenter.