/** * Sets the bond energy. * * @param mol the mol * @param bondEnergy the bond energy * * @return the i atom container */ private IAtomContainer setBondEnergy(IAtomContainer origMol, IAtomContainer mol, Double bondEnergy) { var props = mol.getProperties(); var bondEnergyOrig = (String)origMol.getProperty("BondEnergy"); if (bondEnergyOrig != null) { var sumEnergy = Convert.ToDouble(bondEnergyOrig, CultureInfo.InvariantCulture) + bondEnergy; props.put("BondEnergy", sumEnergy.ToString(CultureInfo.InvariantCulture)); } else { props.put("BondEnergy", bondEnergy.ToString(CultureInfo.InvariantCulture)); } mol.setProperties(props); return mol; }
private IMolecule createMolecule(IAtomContainer atomContainer, String bondEnergy, int treeDepth) { IMolecule molecule = new Molecule(atomContainer); molecule.setProperties(atomContainer.getProperties()); molecule.setProperty("BondEnergy", bondEnergy); molecule.setProperty("TreeDepth", treeDepth.toString()); return molecule; }
private IEnumerable<IAtomContainer> splitMolecule(IAtomContainer atomContainer, IBond bond, IDictionary<IAtom, IList<IBond>> atomBonds) { //if this bond is in a ring we have to split another bond in this ring where at least one //bond is in between. Otherwise we wont have two fragments. Else normal split. var ret = new List<IAtomContainer>(); //get bond energy for splitting this bond var currentBondEnergy = BondEnergies.Lookup(bond); //bond is in a ring....so we have to split up another bond to break it var rings = allRings.getRings(bond); if (rings.getAtomContainerCount() != 0) { foreach (var bondInRing in rings.getAtomContainer(0).bonds().ToWindowsEnumerable<IBond>()) { //if the bonds are the same...this wont split up the ring if (bondInRing == bond) { continue; } //check for already tried bonds var check = new BondPair(bond, bondInRing); if (knownBonds.Contains(check)) { continue; } knownBonds.Add(new BondPair(bond, bondInRing)); var set = new List<IAtomContainer>(); var bondListList = new List<List<IBond>>(); var fragWeightList = new List<Double>(); foreach (var currentAtom in bond.atoms().ToWindowsEnumerable<IAtom>()) { //List with bonds in Ring var partRing = new List<IBond>(); //reset the weight because it is computed inside the traverse currentFragWeight = 0.0; //initialize new atom list atomList = new List<IAtom>(); //clone current atom because a single electron is being added...homolytic cleavage partRing = traverse(atomBonds, currentAtom, partRing, bond, bondInRing); bondListList.Add(partRing); fragWeightList.Add(currentFragWeight); var temp = makeAtomContainer(currentAtom, partRing); //set the properties again! var properties = atomContainer.getProperties(); temp.setProperties(properties); //********************************************************* //BOND ENERGY CALCULATION //calculate bond energy var currentBondEnergyRing = BondEnergies.Lookup(bondInRing); //********************************************************* //now set property temp = setBondEnergy(temp, (currentBondEnergyRing + currentBondEnergy)); set.Add(temp); } //now maybe add the fragments to the list for (var j = 0; j < set.Count; j++) { //Render.Draw(set.getAtomContainer(j), ""); if (set[j].getAtomCount() > 0 && set[j].getBondCount() > 0 && set[j].getAtomCount() != atomContainer.getAtomCount()) { //now check the current mass var fragMass = getFragmentMass(set[j], fragWeightList[j]); //check the weight of the current fragment if (!isHeavyEnough(fragMass)) { continue; } //returns true if isomorph //set the current sum formula var fragmentFormula = MolecularFormulaTools.GetMolecularFormula(set[j]); var currentSumFormula = MolecularFormulaTools.GetString(fragmentFormula); if (isIdentical(set[j], currentSumFormula)) { continue; } //add the fragment to the return list ret.Add(set[j]); } } } } else { var set = new List<IAtomContainer>(); var bondListList = new List<List<IBond>>(); var fragWeightList = new List<Double>(); //get the atoms from the splitting bond --> create 2 fragments foreach (var currentAtom in bond.atoms().ToWindowsEnumerable<IAtom>()) { var part = new List<IBond>(); //reset the weight because it is computed inside the traverse currentFragWeight = 0.0; //initialize new atom list atomList = new List<IAtom>(); part = traverse(atomBonds, currentAtom, part, bond); bondListList.Add(part); //create Atomcontainer out of bondList var temp = makeAtomContainer(currentAtom, part); //set the properties again! var properties = atomContainer.getProperties(); temp.setProperties(properties); //now calculate the correct weight subtrating the possible neutral loss mass fragWeightList.Add(currentFragWeight); //now set property: BondEnergy! temp = setBondEnergy(temp, currentBondEnergy); set.Add(temp); } //at most 2 new molecules for (var i = 0; i < set.Count; i++) { if (set[i].getAtomCount() > 0 && set[i].getBondCount() > 0 && set[i].getAtomCount() != atomContainer.getAtomCount()) { //now check the current mass var fragMass = getFragmentMass(set[i], fragWeightList[i]); //check the weight of the current fragment if (!isHeavyEnough(fragMass)) { continue; } //set the current sum formula var fragmentFormula = MolecularFormulaTools.GetMolecularFormula(set[i]); var currentSumFormula = MolecularFormulaTools.GetString(fragmentFormula); //returns true if isomorph (fast isomorph check) if (isIdentical(set[i], currentSumFormula)) { continue; } ret.Add(set[i]); } } } return ret; }
/** * Check for the other atoms nearby in the fragment. * * @param candidateOxygen * the candidate oxygen atom * @param frag * the frag * @param proton * the proton * * @return true, if successful * @throws CloneNotSupportedException * @throws CDKException */ private IAtomContainer checkForCompleteNeutralLoss(IAtomContainer frag, IAtom candidateAtom, double neutralLossMass) { IAtomContainer ret = new AtomContainer(); // create a copy from the original fragment var part = new List<IBond>(); part = traverse(frag, candidateAtom, part); var fragCopy = makeAtomContainer(candidateAtom, part); // set properties again var properties = frag.getProperties(); fragCopy.setProperties(properties); // now get the other atoms from the neutral loss var atomsToFind = new List<string>(); var addHydrogen = false; // one hydrogen is lost with the neutral loss if (neutralLoss[neutralLossMass].HydrogenDifference == -1) { foreach (var isotope in neutralLoss[neutralLossMass].ElementalComposition.isotopes().ToWindowsEnumerable<IIsotope>()) { var c = neutralLoss[neutralLossMass].ElementalComposition.getIsotopeCount(isotope); for (var i = 0; i < c; i++) { atomsToFind.Add(isotope.getSymbol()); } } } else { foreach (var isotope in neutralLoss[neutralLossMass].TopoFragment.isotopes().ToWindowsEnumerable<IIsotope>()) { var c = neutralLoss[neutralLossMass].ElementalComposition.getIsotopeCount(isotope); for (var i = 0; i < c; i++) { atomsToFind.Add(isotope.getSymbol()); } addHydrogen = true; } } // at most 2 bonds between the oxygen and other atoms (at most 1 H and 2 // C) var count = neutralLoss[neutralLossMass].Distance; // list storing all atoms to be removed later on if complete neutral // loss was found var foundAtoms = new List<IAtom>(); // list storing all bonds to remove var foundBonds = new List<IBond>(); // list storing all bonds already checked var checkedBonds = new List<IBond>(); // list storing all checked atoms var checkedAtoms = new List<IAtom>(); // queue storing all bonds to check for a particular distance var bondQueue = new List<IBond>(); // List storing all bonds to be checked for the next distance var bondsFurther = new List<IBond>(); // get all bonds from this atom distance = 1 var bondList = fragCopy.getConnectedBondsList(candidateAtom); foreach (var bond in bondList.ToWindowsEnumerable<IBond>()) { if (bond != null) { bondQueue.Add(bond); } } var hydrogenStartAtom = neutralLoss[neutralLossMass].HydrogenOnStartAtom; var firstBonds = true; while (count > 0) { IBond currentBond = null; if (bondQueue.Count > 0) { currentBond = bondQueue[bondQueue.Count - 1]; bondQueue.RemoveAt(bondQueue.Count - 1); } // check for already tried bonds if (checkedBonds.Contains(currentBond) && currentBond != null) { continue; } else if (currentBond != null) { checkedBonds.Add(currentBond); } if (currentBond != null) { foreach (var atom in currentBond.atoms().ToWindowsEnumerable<IAtom>()) { // check for already tried atoms if (checkedAtoms.Contains(atom)) { continue; } else { checkedAtoms.Add(atom); } if (firstBonds && atom.getSymbol().Equals("H")) { hydrogenStartAtom--; } // thats the starting atom if (atom.getSymbol().Equals(candidateAtom.getSymbol())) { var removed = atomsToFind.Remove(candidateAtom.getSymbol()); if (removed) { foundAtoms.Add(atom); // remove bond if (!foundBonds.Contains(currentBond)) { foundBonds.Add(currentBond); } } // this bond has to be removed else if (!foundBonds.Contains(currentBond) && atomsToFind.Contains(atom.getSymbol())) { foundBonds.Add(currentBond); } continue; } // found atom...remove it from the atoms to find list // do not remove atoms from ring if (atomsToFind.Contains(atom.getSymbol()) && !allRings.contains(atom) && atomsToFind.Count > 0) { var removed = atomsToFind.Remove(atom.getSymbol()); if (removed) { foundAtoms.Add(atom); } else { continue; } if (!foundBonds.Contains(currentBond)) { foundBonds.Add(currentBond); } continue; } // only walk along C-Atoms! if (!atom.getSymbol().Equals("C")) { continue; } // get new bonds var bondsToAddTemp = fragCopy.getConnectedBondsList(atom); foreach (var bond in bondsToAddTemp.ToWindowsEnumerable<IBond>()) { if (bond != null) { bondsFurther.Add(bond); } } } } // break condition if (currentBond == null && bondQueue.Count == 0 && bondsFurther.Count == 0) { break; } // now check if the queue is empty...checked all bonds in this // distance if (bondQueue.Count == 0) { count--; // set new queue data foreach (var bond in bondsFurther) { if (bond != null) { bondQueue.Add(bond); } } // reinitialize bondsFurther = new List<IBond>(); // the initially connected bonds are all checked! firstBonds = false; } } // found complete neutral loss if (atomsToFind.Count == 0) { foreach (var atom in foundAtoms) { fragCopy.removeAtomAndConnectedElectronContainers(atom); } // TODO add hydrogen somewhere if (addHydrogen) { var props = fragCopy.getProperties(); props.put("hydrogenAddFromNL", "1"); fragCopy.setProperties(props); } // add fragment to return if enough H were connected and fragment is // still connected if (hydrogenStartAtom <= 0) { ret.add(fragCopy); } } return ret; }