User 870ab5b546
04-06-2007 16:52:43
Hi,
I'm measuring the most acidic and basic pKa's of each atom in the following compound, which is already in the "canonical resonance form" (JChem 3.2.6):
When I submit this compound to the pKa calculator in Marvin 4.1.8, it correctly gives me a basic pKa of 19.2 for the anionic C atom. When I call JChem 3.2.6 for the acidic and basic pKas of the same molecule, however, it gives me a basic pKa of 29.98131480199701 for the anionic C atom. I can't figure out why I am getting the wrong answer from JChem. Can you help???
Here's the code. The first part is in this jsp page, and MolFunctions.pKapKbAtom() is in a Java file.
Here's the log output:
I'm measuring the most acidic and basic pKa's of each atom in the following compound, which is already in the "canonical resonance form" (JChem 3.2.6):
Code: |
<?xml version="1.0" ?> <MDocument> <MChemicalStruct> <molecule molID="m1"> <atomArray atomID="a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17" elementType="C C C C C C O C O C C C C C C O H" formalCharge="0 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0" x2="5.050965750132235 3.717296409083975 3.717296409083975 5.050965750132235 6.384635091180492 6.384635091180492 5.050965750132235 7.7183142130085285 7.7183142130085285 9.051993334836563 9.051993334836563 7.162519405430373 8.496198527258409 9.829877649086445 11.16355677091448 10.599877649086444 10.764975441456599" y2="4.382371934332493 3.6123549937734527 2.0723211126553718 1.3023041720963313 2.0723211126553718 3.6123549937734527 5.9223719343324905 4.382354993773452 1.3023211126553722 3.6123549937734527 2.072354993773452 5.958567862126545 6.728567862126544 5.958567862126545 6.728567862126544 4.624888740298509 8.21609363461171" /> <bondArray> <bond atomRefs2="a1 a2" order="1" /> <bond atomRefs2="a1 a6" order="1" /> <bond atomRefs2="a1 a7" order="2" /> <bond atomRefs2="a2 a3" order="1" /> <bond atomRefs2="a3 a4" order="1" /> <bond atomRefs2="a4 a5" order="1" /> <bond atomRefs2="a5 a6" order="1" /> <bond atomRefs2="a5 a9" order="2" /> <bond atomRefs2="a6 a8" order="1" /> <bond atomRefs2="a6 a12" order="1" /> <bond atomRefs2="a8 a10" order="1" /> <bond atomRefs2="a10 a11" order="2" /> <bond atomRefs2="a12 a13" order="1" /> <bond atomRefs2="a13 a14" order="1" /> <bond atomRefs2="a14 a15" order="1" /> <bond atomRefs2="a14 a16" order="2" /> <bond atomRefs2="a15 a17" order="1" /> </bondArray> </molecule> </MChemicalStruct> </MDocument> |
When I submit this compound to the pKa calculator in Marvin 4.1.8, it correctly gives me a basic pKa of 19.2 for the anionic C atom. When I call JChem 3.2.6 for the acidic and basic pKas of the same molecule, however, it gives me a basic pKa of 29.98131480199701 for the anionic C atom. I can't figure out why I am getting the wrong answer from JChem. Can you help???
Here's the code. The first part is in this jsp page, and MolFunctions.pKapKbAtom() is in a Java file.
Code: |
String substrate = request.getParameter("substrate"); Molecule origMolecule = null; Molecule molecule = null; String[] pKas; String[] pKbs; double[] molpKas = {0, 0, 0}; double[] molpKbs = {0, 0, 0}; int[] molpKaAtms = {0, 0, 0}; int[] molpKbAtms = {0, 0, 0}; int numAtoms = 0; int origNumAtoms = 0; if (substrate != null) { origMolecule = MolImporter.importMol(substrate); molecule = MolImporter.importMol(substrate); origNumAtoms = molecule.getAtomCount(); molecule = MolFunctions.stripMetals(molecule); numAtoms = molecule.getAtomCount(); pKaPlugin plugin = new pKaPlugin(); plugin.setMaxIons(8); // default 8 plugin.setBasicpKaLowerLimit(-15); plugin.setAcidicpKaUpperLimit(50); pKas = new String[numAtoms]; pKbs = new String[numAtoms]; molecule.aromatize(MoleculeGraph.AROM_BASIC); plugin.setMolecule(molecule); // new to JChem 3.2.1; makes where pKa and pKb are // stored NOT dependent on charge of atom plugin.setpKaPrefixType(pKaPlugin.DYNAMICpKaPREFIX); plugin.setModel(pKaPlugin.MODEL_LARGE); boolean runOK = plugin.run(); for (int atmIdx = 0; atmIdx < numAtoms; atmIdx++) { pKas[atmIdx] = ""; pKbs[atmIdx] = ""; MolAtom atm = molecule.getAtom(atmIdx); if (atm.getSymbol().equals("H") && atm.getCharge() == 0) continue; ArrayList<String> doneThat = new ArrayList<String>(); double[] bothpKas = MolFunctions.pKapKbAtom(molecule, atmIdx, plugin, doneThat); if (!Double.isNaN(bothpKas[0])) { System.out.println("acidic pKa for atom " + (atmIdx + 1) + ": " + bothpKas[0]); pKas[atmIdx] = Utils.truncateFloat((float) bothpKas[0], 1); } else System.out.println("no acidic pKa for atom " + (atmIdx + 1)); if (!Double.isNaN(bothpKas[1])) { System.out.println("basic pKa for atom " + (atmIdx + 1) + ": " + bothpKas[1]); pKbs[atmIdx] = Utils.truncateFloat((float) bothpKas[1], 1); } else System.out.println("no basic pKa for atom " + (atmIdx + 1)); } // for each atom in the molecule plugin.getSortedValues(pKaPlugin.ACIDIC, molpKas, molpKaAtms); plugin.getSortedValues(pKaPlugin.BASIC, molpKbs, molpKbAtms); } else { // substrate is null pKas = new String[0]; pKbs = new String[0]; } // if substrate is/is not null //---------------------------------------------------------------------- // pKapKbAtom //---------------------------------------------------------------------- // gets the smallest pKa and largest pKb of an atom in a molecule // The plugin has already calculated the pKas of the molecule before being // sent here. // doneThat stores resonance structures already examined; // prevents infinite loops in recursion. public static double[] pKapKbAtom(Molecule molecule, int atmIdx, pKaPlugin plugin, ArrayList<String> doneThat) { println("Calculating pKa and pKb of atom " + (atmIdx + 1) + "..."); MolAtom atm = molecule.getAtom(atmIdx); boolean bears_H = (atm.getImplicitHcount() + atm.getExplicitHcount() > 0); // needs to bear H to be acidic double[] pKaAcidic = (bears_H ? plugin.getpKaValues(atmIdx, pKaPlugin.ACIDIC) : null); double[] pKaBasic = plugin.getpKaValues(atmIdx, pKaPlugin.BASIC); double[] retVal = new double[2]; retVal[0] = (pKaAcidic != null ? pKaAcidic[0] : Double.NaN); retVal[1] = (pKaBasic != null ? pKaBasic[0] : Double.NaN); // if atom is C and plugin has failed to give value, guess if (atm.getSymbol().equals("C")) { if (Double.isNaN(retVal[0]) && atm.getCharge() == 0 && atm.getImplicitHcount() + atm.getExplicitHcount() > 0) { retVal[0] = getCpKa(molecule, atmIdx); println(" guessing at pKaAcidic of CH ... value is " + retVal[0]); } // C is negative, pKaBasic not calculated if (Double.isNaN(retVal[1]) && atm.getCharge() == -1) { retVal[1] = getCpKa(molecule, atmIdx); println(" guessing at pKaBasic of C(-) ... value is " + retVal[1]); } // C is negative, pKaBasic not calculated } // if it's a C atom // see if there's a resonance form with a charge < 0 on this atom ArrayList<Integer> beenThereIndices = new ArrayList<Integer>(); beenThereIndices.add(atmIdx); // prevents infinite loops in recursion doneThat.add(molecule.toFormat("mrv")); // prevents infinite loops in recursion Molecule resMol = resStructWithNegChg(molecule, atmIdx, beenThereIndices, doneThat); if (resMol != null) { println("Found a resonance form with a negative charge on " + "this atom; recursively calling pKapKbAtom() for:\n" + resMol.toFormat("mrv")); pKaPlugin newPlugin = new pKaPlugin(); newPlugin.setpKaPrefixType(pKaPlugin.DYNAMICpKaPREFIX); newPlugin.setModel(pKaPlugin.MODEL_LARGE); newPlugin.setMaxIons(8); newPlugin.setBasicpKaLowerLimit(-15); newPlugin.setAcidicpKaUpperLimit(50); resMol.calcHybridization(); boolean runOK = false; try { newPlugin.setMolecule(resMol); runOK = newPlugin.run(); double[] newpKapKb = pKapKbAtom(resMol, atmIdx, newPlugin, doneThat); println("Resonance form gave new pKa = " + newpKapKb[0] + ", new pKb = " + newpKapKb[1]); if (Double.isNaN(retVal[1]) || newpKapKb[1] > retVal[1]) { println("Changing old pKb " + retVal[1] + " to new pKb " + newpKapKb[1]); retVal[1] = newpKapKb[1]; } // if the resonance structure is more basic than the original } catch (PluginException e) { System.out.println("pKaPlugin exception for:\n" + resMol.toFormat("mrv")); } } // if there's a resonance form with a negative charge on this atom println("For atom " + (atmIdx + 1) + ", returning pKa = " + retVal[0] + ", pKb = " + retVal[1]); return retVal; } // pKapKbAtom(Molecule, int, pKaPlugin, ArrayList<String>) |
Here's the log output:
Code: |
Calculating pKa and pKb of atom 1... resStructWithNegChg: beenThere = {1} For atom 1, returning pKa = NaN, pKb = NaN stage 3, cpd C13H17O3, atom C1 has no acidic pKa, no basic pKa Calculating pKa and pKb of atom 2... resStructWithNegChg: beenThere = {2} For atom 2, returning pKa = 18.46324186445971, pKb = NaN stage 3, cpd C13H17O3, atom C2 has acidic pKa 18.46324186445971, no basic pKa Calculating pKa and pKb of atom 3... Entering getCpKa for C atom whose pKa is not calculated by JChem. getCpKa: Hybridization is sp3 guessing at pKaAcidic of CH ... value is 51.0 resStructWithNegChg: beenThere = {3} For atom 3, returning pKa = 51.0, pKb = NaN stage 3, cpd C13H17O3, atom C3 has acidic pKa 51.0, no basic pKa Calculating pKa and pKb of atom 4... resStructWithNegChg: beenThere = {4} For atom 4, returning pKa = 19.3351664642691, pKb = NaN stage 3, cpd C13H17O3, atom C4 has acidic pKa 19.3351664642691, no basic pKa Calculating pKa and pKb of atom 5... resStructWithNegChg: beenThere = {5} For atom 5, returning pKa = NaN, pKb = NaN stage 3, cpd C13H17O3, atom C5 has no acidic pKa, no basic pKa Calculating pKa and pKb of atom 6... resStructWithNegChg: beenThere = {6} For atom 6, returning pKa = NaN, pKb = NaN stage 3, cpd C13H17O3, atom C6 has no acidic pKa, no basic pKa Calculating pKa and pKb of atom 7... resStructWithNegChg: beenThere = {7} resStructWithNegChg: beenThere = {7, 1} resStructWithNegChg: beenThere = {7, 1, 1} For atom 7, returning pKa = NaN, pKb = -7.562260074973646 stage 3, cpd C13H17O3, atom O7 has no acidic pKa, basic pKa -7.562260074973646 Calculating pKa and pKb of atom 8... Entering getCpKa for C atom whose pKa is not calculated by JChem. getCpKa: Hybridization is sp3 getCpKa: allylic or propargylic guessing at pKaAcidic of CH ... value is 41.0 resStructWithNegChg: beenThere = {8} For atom 8, returning pKa = 41.0, pKb = NaN stage 3, cpd C13H17O3, atom C8 has acidic pKa 41.0, no basic pKa Calculating pKa and pKb of atom 9... resStructWithNegChg: beenThere = {9} resStructWithNegChg: beenThere = {9, 5} resStructWithNegChg: beenThere = {9, 5, 5} For atom 9, returning pKa = NaN, pKb = -8.333727472295461 stage 3, cpd C13H17O3, atom O9 has no acidic pKa, basic pKa -8.333727472295461 Calculating pKa and pKb of atom 10... Entering getCpKa for C atom whose pKa is not calculated by JChem. getCpKa: Hybridization is sp2 guessing at pKaAcidic of CH ... value is 43.0 resStructWithNegChg: beenThere = {10} For atom 10, returning pKa = 43.0, pKb = NaN stage 3, cpd C13H17O3, atom C10 has acidic pKa 43.0, no basic pKa Calculating pKa and pKb of atom 11... Entering getCpKa for C atom whose pKa is not calculated by JChem. getCpKa: Hybridization is sp2 guessing at pKaAcidic of CH ... value is 43.0 resStructWithNegChg: beenThere = {11} resStructWithNegChg: beenThere = {11, 10} For atom 11, returning pKa = 43.0, pKb = NaN stage 3, cpd C13H17O3, atom C11 has acidic pKa 43.0, no basic pKa Calculating pKa and pKb of atom 12... Entering getCpKa for C atom whose pKa is not calculated by JChem. getCpKa: Hybridization is sp3 guessing at pKaAcidic of CH ... value is 51.0 resStructWithNegChg: beenThere = {12} For atom 12, returning pKa = 51.0, pKb = NaN stage 3, cpd C13H17O3, atom C12 has acidic pKa 51.0, no basic pKa Calculating pKa and pKb of atom 13... resStructWithNegChg: beenThere = {13} For atom 13, returning pKa = NaN, pKb = 29.98131480199701 stage 3, cpd C13H17O3, atom C13 has no acidic pKa, basic pKa 29.98131480199701 Calculating pKa and pKb of atom 14... resStructWithNegChg: beenThere = {14} For atom 14, returning pKa = NaN, pKb = NaN stage 3, cpd C13H17O3, atom C14 has no acidic pKa, no basic pKa Calculating pKa and pKb of atom 15... resStructWithNegChg: beenThere = {15} For atom 15, returning pKa = 26.173321502035975, pKb = NaN stage 3, cpd C13H17O3, atom C15 has acidic pKa 26.173321502035975, no basic pKa Calculating pKa and pKb of atom 16... resStructWithNegChg: beenThere = {16} Found a resonance form: <?xml version="1.0" ?> <MDocument> <MChemicalStruct> <molecule molID="m1"> <atomArray atomID="a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17" elementType="C C C C C C O C O C C C C C C O H" formalCharge="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0" x2="5.050965750132235 3.717296409083975 3.717296409083975 5.050965750132235 6.384635091180492 6.384635091180492 5.050965750132235 7.7183142130085285 7.7183142130085285 9.051993334836563 9.051993334836563 7.162519405430373 8.496198527258409 9.829877649086445 11.16355677091448 10.599877649086444 10.764975441456599" y2="4.382371934332493 3.6123549937734527 2.0723211126553718 1.3023041720963313 2.0723211126553718 3.6123549937734527 5.9223719343324905 4.382354993773452 1.3023211126553722 3.6123549937734527 2.072354993773452 5.958567862126545 6.728567862126544 5.958567862126545 6.728567862126544 4.624888740298509 8.21609363461171" /> <bondArray> <bond atomRefs2="a1 a2" order="1" /> <bond atomRefs2="a1 a6" order="1" /> <bond atomRefs2="a1 a7" order="2" /> <bond atomRefs2="a2 a3" order="1" /> <bond atomRefs2="a3 a4" order="1" /> <bond atomRefs2="a4 a5" order="1" /> <bond atomRefs2="a5 a6" order="1" /> <bond atomRefs2="a5 a9" order="2" /> <bond atomRefs2="a6 a8" order="1" /> <bond atomRefs2="a6 a12" order="1" /> <bond atomRefs2="a8 a10" order="1" /> <bond atomRefs2="a10 a11" order="2" /> <bond atomRefs2="a12 a13" order="1" /> <bond atomRefs2="a13 a14" order="2" /> <bond atomRefs2="a14 a15" order="1" /> <bond atomRefs2="a14 a16" order="1" /> <bond atomRefs2="a15 a17" order="1" /> </bondArray> </molecule> </MChemicalStruct> </MDocument> Checking against 1 resonance structures whether resonance structure has already been found and checked haven't already looked at this resonance structure Found a resonance form with a negative charge on this atom; recursively calling pKapKbAtom() for: <?xml version="1.0" ?> <MDocument> <MChemicalStruct> <molecule molID="m1"> <atomArray atomID="a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17" elementType="C C C C C C O C O C C C C C C O H" formalCharge="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0" x2="5.050965750132235 3.717296409083975 3.717296409083975 5.050965750132235 6.384635091180492 6.384635091180492 5.050965750132235 7.7183142130085285 7.7183142130085285 9.051993334836563 9.051993334836563 7.162519405430373 8.496198527258409 9.829877649086445 11.16355677091448 10.599877649086444 10.764975441456599" y2="4.382371934332493 3.6123549937734527 2.0723211126553718 1.3023041720963313 2.0723211126553718 3.6123549937734527 5.9223719343324905 4.382354993773452 1.3023211126553722 3.6123549937734527 2.072354993773452 5.958567862126545 6.728567862126544 5.958567862126545 6.728567862126544 4.624888740298509 8.21609363461171" /> <bondArray> <bond atomRefs2="a1 a2" order="1" /> <bond atomRefs2="a1 a6" order="1" /> <bond atomRefs2="a1 a7" order="2" /> <bond atomRefs2="a2 a3" order="1" /> <bond atomRefs2="a3 a4" order="1" /> <bond atomRefs2="a4 a5" order="1" /> <bond atomRefs2="a5 a6" order="1" /> <bond atomRefs2="a5 a9" order="2" /> <bond atomRefs2="a6 a8" order="1" /> <bond atomRefs2="a6 a12" order="1" /> <bond atomRefs2="a8 a10" order="1" /> <bond atomRefs2="a10 a11" order="2" /> <bond atomRefs2="a12 a13" order="1" /> <bond atomRefs2="a13 a14" order="2" /> <bond atomRefs2="a14 a15" order="1" /> <bond atomRefs2="a14 a16" order="1" /> <bond atomRefs2="a15 a17" order="1" /> </bondArray> </molecule> </MChemicalStruct> </MDocument> Calculating pKa and pKb of atom 16... resStructWithNegChg: beenThere = {16} For atom 16, returning pKa = NaN, pKb = 10.51728653351482 Resonance form gave new pKa = NaN, new pKb = 10.51728653351482 Changing old pKb -6.996512990109083 to new pKb 10.51728653351482 For atom 16, returning pKa = NaN, pKb = 10.51728653351482 stage 3, cpd C13H17O3, atom O16 has no acidic pKa, basic pKa 10.51728653351482 in stage 3, cpd C13H17O3 has molMostBasic = 29.98131480199701 and molMostAcidic = 18.46324186445971 |