public IAtomContainer cyclopentylcyclopentane() { IAtom[] atoms = new IAtom[] { new Atom("C"), new Atom("C"), new Atom("C"), new Atom("C"), new Atom("C"), new Atom("C"), new Atom("C"), new Atom("C"), new Atom("C"), new Atom("C"), }; IBond[] bonds = new IBond[] { new Bond(atoms[0], atoms[1], SINGLE), new Bond(atoms[0], atoms[4], SINGLE), new Bond(atoms[1], atoms[2], SINGLE), new Bond(atoms[2], atoms[3], SINGLE), new Bond(atoms[3], atoms[4], SINGLE), new Bond(atoms[5], atoms[6], SINGLE), new Bond(atoms[5], atoms[9], SINGLE), new Bond(atoms[6], atoms[7], SINGLE), new Bond(atoms[7], atoms[8], SINGLE), new Bond(atoms[8], atoms[9], SINGLE), new Bond(atoms[8], atoms[0], SINGLE), }; IAtomContainer mol = new AtomContainer(0, 0, 0, 0); mol.setAtoms(atoms); mol.setBonds(bonds); return mol; }
@Test public void testTraversal_Chain() { IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance(); IAtom[] atoms = new IAtom[] { builder.newInstance(IAtom.class, "C"), builder.newInstance(IAtom.class, "C"), builder.newInstance(IAtom.class, "C"), builder.newInstance(IAtom.class, "C"), builder.newInstance(IAtom.class, "C"), builder.newInstance(IAtom.class, "C") }; IBond[] bonds = new IBond[] { builder.newInstance(IBond.class, atoms[0], atoms[1]), builder.newInstance(IBond.class, atoms[1], atoms[2]), builder.newInstance(IBond.class, atoms[2], atoms[3]), builder.newInstance(IBond.class, atoms[3], atoms[4]), builder.newInstance(IBond.class, atoms[4], atoms[5]) }; IAtomContainer m = builder.newInstance(IAtomContainer.class, 0, 0, 0, 0); m.setAtoms(atoms); m.setBonds(bonds); List<IBond> accumulator = new ArrayList<IBond>(); // traverse from one end FragmentUtils.traverse(m, atoms[0], accumulator); assertThat(accumulator.size(), is(5)); assertThat(accumulator.get(0), is(bonds[0])); assertThat(accumulator.get(1), is(bonds[1])); assertThat(accumulator.get(2), is(bonds[2])); assertThat(accumulator.get(3), is(bonds[3])); assertThat(accumulator.get(4), is(bonds[4])); // traverse from the middle accumulator.clear(); FragmentUtils.traverse(m, atoms[3], accumulator); assertThat(accumulator.size(), is(5)); assertThat(accumulator.get(0), is(bonds[2])); assertThat(accumulator.get(1), is(bonds[1])); assertThat(accumulator.get(2), is(bonds[0])); assertThat(accumulator.get(3), is(bonds[3])); assertThat(accumulator.get(4), is(bonds[4])); }
private IAtomContainer makeAtomContainerFromFormula() { IAtomContainer atomContainer = this.builder.newAtomContainer(); ArrayList<IAtom> atoms = new ArrayList<IAtom>(); for (IIsotope isotope : formula.isotopes()) { for (int i = 0; i < formula.getIsotopeCount(isotope); i++) { atoms.add(this.builder.newAtom(isotope)); System.out.println("added " + isotope.getSymbol()); } } // sort by symbol lexicographic order Collections.sort( atoms, new Comparator<IAtom>() { public int compare(IAtom o1, IAtom o2) { return o1.getSymbol().compareTo(o2.getSymbol()); } }); atomContainer.setAtoms(atoms.toArray(new IAtom[] {})); return atomContainer; }
/** * Clones this AtomContainer object and its content. * * @return The cloned object * @see #shallowCopy */ public IAtomContainer clone() throws CloneNotSupportedException { // this is pretty wasteful as we need to delete most the data // we can't simply create an empty instance as the sub classes (e.g. AminoAcid) // would have a ClassCastException when they invoke clone IAtomContainer clone = (IAtomContainer) super.clone(); // remove existing elements - we need to set the stereo elements list as list.clone() doesn't // work as expected and will also remove all elements from the original clone.setStereoElements(new ArrayList<IStereoElement>(stereoElements.size())); clone.removeAllElements(); // create a mapping of the original atoms/bonds to the cloned atoms/bonds // we need this mapping to correctly clone bonds, single/paired electrons // and stereo elements // - the expected size stop the map be resized - method from Google Guava Map<IAtom, IAtom> atomMap = new HashMap<IAtom, IAtom>(atomCount >= 3 ? atomCount + atomCount / 3 : atomCount + 1); Map<IBond, IBond> bondMap = new HashMap<IBond, IBond>(bondCount >= 3 ? bondCount + bondCount / 3 : bondCount + 1); // clone atoms IAtom[] atoms = new IAtom[this.atomCount]; for (int i = 0; i < atoms.length; i++) { atoms[i] = (IAtom) this.atoms[i].clone(); atomMap.put(this.atoms[i], atoms[i]); } clone.setAtoms(atoms); // clone bonds using a the mappings from the original to the clone IBond[] bonds = new IBond[this.bondCount]; for (int i = 0; i < bonds.length; i++) { IBond original = this.bonds[i]; IBond bond = (IBond) original.clone(); int n = bond.getAtomCount(); IAtom[] members = new IAtom[n]; for (int j = 0; j < n; j++) { members[j] = atomMap.get(original.getAtom(j)); } bond.setAtoms(members); bondMap.put(this.bonds[i], bond); bonds[i] = bond; } clone.setBonds(bonds); // clone lone pairs (we can't use an array to buffer as there is no setLonePairs()) for (int i = 0; i < lonePairCount; i++) { ILonePair original = this.lonePairs[i]; ILonePair pair = (ILonePair) original.clone(); if (pair.getAtom() != null) pair.setAtom(atomMap.get(original.getAtom())); clone.addLonePair(pair); } // clone single electrons (we can't use an array to buffer as there is no setSingleElectrons()) for (int i = 0; i < singleElectronCount; i++) { ISingleElectron original = this.singleElectrons[i]; ISingleElectron electron = (ISingleElectron) original.clone(); if (electron.getAtom() != null) electron.setAtom(atomMap.get(original.getAtom())); clone.addSingleElectron(electron); } // map each stereo element to a new instance in the clone for (IStereoElement element : stereoElements) { clone.addStereoElement(element.map(atomMap, bondMap)); } return clone; }
/** * Convert the input into a pcore molecule. * * @param input the compound being converted from * @return pcore molecule * @throws CDKException match failed */ private IAtomContainer getPharmacophoreMolecule(IAtomContainer input) throws CDKException { // XXX: prepare query, to be moved prepareInput(input); IAtomContainer pharmacophoreMolecule = input.getBuilder().newInstance(IAtomContainer.class, 0, 0, 0, 0); final Set<String> matched = new HashSet<>(); final Set<PharmacophoreAtom> uniqueAtoms = new LinkedHashSet<>(); logger.debug("Converting [" + input.getProperty(CDKConstants.TITLE) + "] to a pcore molecule"); // lets loop over each pcore query atom for (IAtom atom : pharmacophoreQuery.atoms()) { final PharmacophoreQueryAtom qatom = (PharmacophoreQueryAtom) atom; final String smarts = qatom.getSmarts(); // a pcore query might have multiple instances of a given pcore atom (say // 2 hydrophobic groups separated by X unit). In such a case we want to find // the atoms matching the pgroup SMARTS just once, rather than redoing the // matching for each instance of the pcore query atom. if (!matched.add(qatom.getSymbol())) continue; // see if the smarts for this pcore query atom gets any matches // in our query molecule. If so, then collect each set of // matching atoms and for each set make a new pcore atom and // add it to the pcore atom container object int count = 0; for (final IQueryAtomContainer query : qatom.getCompiledSmarts()) { // create the lazy mappings iterator final Mappings mappings = Pattern.findSubstructure(query).matchAll(input).uniqueAtoms(); for (final int[] mapping : mappings) { uniqueAtoms.add(newPCoreAtom(input, qatom, smarts, mapping)); count++; } } logger.debug("\tFound " + count + " unique matches for " + smarts); } pharmacophoreMolecule.setAtoms(uniqueAtoms.toArray(new IAtom[uniqueAtoms.size()])); // now that we have added all the pcore atoms to the container // we need to join all atoms with pcore bonds (i.e. distance constraints) if (hasDistanceConstraints(pharmacophoreQuery)) { int npatom = pharmacophoreMolecule.getAtomCount(); for (int i = 0; i < npatom - 1; i++) { for (int j = i + 1; j < npatom; j++) { PharmacophoreAtom atom1 = (PharmacophoreAtom) pharmacophoreMolecule.getAtom(i); PharmacophoreAtom atom2 = (PharmacophoreAtom) pharmacophoreMolecule.getAtom(j); PharmacophoreBond bond = new PharmacophoreBond(atom1, atom2); pharmacophoreMolecule.addBond(bond); } } } // if we have angle constraints, generate only the valid // possible angle relationships, rather than all possible if (hasAngleConstraints(pharmacophoreQuery)) { int nangleDefs = 0; for (IBond bond : pharmacophoreQuery.bonds()) { if (!(bond instanceof PharmacophoreQueryAngleBond)) continue; IAtom startQAtom = bond.getAtom(0); IAtom middleQAtom = bond.getAtom(1); IAtom endQAtom = bond.getAtom(2); // make a list of the patoms in the target that match // each type of angle atom List<IAtom> startl = new ArrayList<IAtom>(); List<IAtom> middlel = new ArrayList<IAtom>(); List<IAtom> endl = new ArrayList<IAtom>(); for (IAtom tatom : pharmacophoreMolecule.atoms()) { if (tatom.getSymbol().equals(startQAtom.getSymbol())) startl.add(tatom); if (tatom.getSymbol().equals(middleQAtom.getSymbol())) middlel.add(tatom); if (tatom.getSymbol().equals(endQAtom.getSymbol())) endl.add(tatom); } // now we form the relevant angles, but we will // have reversed repeats List<IAtom[]> tmpl = new ArrayList<IAtom[]>(); for (IAtom middle : middlel) { for (IAtom start : startl) { if (middle.equals(start)) continue; for (IAtom end : endl) { if (start.equals(end) || middle.equals(end)) continue; tmpl.add(new IAtom[] {start, middle, end}); } } } // now clean up reversed repeats List<IAtom[]> unique = new ArrayList<IAtom[]>(); for (int i = 0; i < tmpl.size(); i++) { IAtom[] seq1 = tmpl.get(i); boolean isRepeat = false; for (int j = 0; j < unique.size(); j++) { if (i == j) continue; IAtom[] seq2 = unique.get(j); if (seq1[1] == seq2[1] && seq1[0] == seq2[2] && seq1[2] == seq2[0]) { isRepeat = true; } } if (!isRepeat) unique.add(seq1); } // finally we can add the unique angle to the target for (IAtom[] seq : unique) { PharmacophoreAngleBond pbond = new PharmacophoreAngleBond( (PharmacophoreAtom) seq[0], (PharmacophoreAtom) seq[1], (PharmacophoreAtom) seq[2]); pharmacophoreMolecule.addBond(pbond); nangleDefs++; } } logger.debug("Added " + nangleDefs + " defs to the target pcore molecule"); } return pharmacophoreMolecule; }