001package com.hfg.chem; 002 003import com.hfg.util.CompareUtil; 004import com.hfg.xml.XMLNode; 005import com.hfg.xml.XMLTag; 006 007//------------------------------------------------------------------------------ 008/** 009 Ionizable chemical group. 010 <div> 011 @author J. Alex Taylor, hairyfatguy.com 012 </div> 013 */ 014//------------------------------------------------------------------------------ 015// com.hfg XML/HTML Coding Library 016// 017// This library is free software; you can redistribute it and/or 018// modify it under the terms of the GNU Lesser General Public 019// License as published by the Free Software Foundation; either 020// version 2.1 of the License, or (at your option) any later version. 021// 022// This library is distributed in the hope that it will be useful, 023// but WITHOUT ANY WARRANTY; without even the implied warranty of 024// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 025// Lesser General Public License for more details. 026// 027// You should have received a copy of the GNU Lesser General Public 028// License along with this library; if not, write to the Free Software 029// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 030// 031// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 032// jataylor@hairyfatguy.com 033//------------------------------------------------------------------------------ 034 035public class IonizableGroup implements Comparable<IonizableGroup> 036{ 037 038 public static final String IONIZABLE_GROUP_TAG = "IonizableGrp"; 039 public static final String PROTONATED_FORM_ATT = "protonatedForm"; 040 public static final String KA_ATT = "ka"; 041 042 //########################################################################## 043 // PRIVATE FIELDS 044 //########################################################################## 045 046 private Charge mProtonatedForm; 047 private double mKa; 048 049 //########################################################################## 050 // CONSTRUCTORS 051 //########################################################################## 052 053 //-------------------------------------------------------------------------- 054 public IonizableGroup(double inKa, Charge inProtonatedForm) 055 { 056 if (inKa > 1 057 || inKa < 0) 058 { 059 throw new RuntimeException("Illegal Ka value: " + inKa + "! The Ka cannot be > 1 or < 0! (Be sure the value entered is not the pKa.)"); 060 } 061 062 mKa = inKa; 063 064 if (null == inProtonatedForm) 065 { 066 throw new RuntimeException("The protonated form cannot be null!"); 067 } 068 else if (inProtonatedForm == Charge.NEGATIVE) 069 { 070 throw new RuntimeException("The protonated form cannot be negative!"); 071 } 072 073 mProtonatedForm = inProtonatedForm; 074 } 075 076 077 //-------------------------------------------------------------------------- 078 public IonizableGroup(XMLNode inXML) 079 { 080 if (! inXML.getTagName().equals(IONIZABLE_GROUP_TAG)) 081 { 082 throw new RuntimeException("Cannot construct an " + this.getClass().getSimpleName() + " from a " + inXML.getTagName() + " tag!"); 083 } 084 085 mKa = Double.parseDouble(inXML.getAttributeValue(KA_ATT)); 086 mProtonatedForm = Charge.valueOf(inXML.getAttributeValue(PROTONATED_FORM_ATT)); 087 } 088 089 //########################################################################## 090 // PUBLIC METHODS 091 //########################################################################## 092 093 //-------------------------------------------------------------------------- 094 @Override 095 public int hashCode() 096 { 097 return new Float(getKa()).hashCode() + 31 * getProtonatedForm().hashCode(); 098 } 099 100 //-------------------------------------------------------------------------- 101 @Override 102 public boolean equals(Object inObj2) 103 { 104 boolean result = false; 105 106 if (inObj2 != null 107 && inObj2 instanceof IonizableGroup) 108 { 109 result = (0 == compareTo((IonizableGroup) inObj2)); 110 } 111 112 return result; 113 } 114 115 //-------------------------------------------------------------------------- 116 @Override 117 public int compareTo(IonizableGroup inObj2) 118 { 119 int result = -1; 120 121 if (inObj2 != null) 122 { 123 result = 0; 124 125 if (this != inObj2) 126 { 127 result = CompareUtil.compare(getKa(), inObj2.getKa()); 128 129 if (0 == result) 130 { 131 result = CompareUtil.compare(getProtonatedForm(), inObj2.getProtonatedForm()); 132 } 133 } 134 } 135 136 return result; 137 } 138 139 //-------------------------------------------------------------------------- 140 public Charge getProtonatedForm() 141 { 142 return mProtonatedForm; 143 } 144 145 //-------------------------------------------------------------------------- 146 public float getpKa() 147 { 148 return (float) - Math.log10(mKa); 149 } 150 151 //-------------------------------------------------------------------------- 152 public double getKa() 153 { 154 return mKa; 155 } 156 157 //-------------------------------------------------------------------------- 158 public double getCharge(int inCount, double inConcOfHIons) 159 { 160 double value = 0; 161 162 if (inCount > 0) 163 { 164 if (getProtonatedForm() == Charge.POSITIVE) 165 { 166 value = inCount * ((inConcOfHIons / (inConcOfHIons + getKa()))); 167 } 168 else if (getProtonatedForm() == Charge.NEUTRAL) 169 { 170 value = -1 * inCount * (1 - (inConcOfHIons / (inConcOfHIons + getKa()))); 171 } 172 } 173 174 return value; 175 } 176 177 //-------------------------------------------------------------------------- 178 @Override 179 public String toString() 180 { 181 return String.format("%.2E (%s)", mKa, mProtonatedForm.toString()); 182 } 183 184 //-------------------------------------------------------------------------- 185 public XMLNode toXMLNode() 186 { 187 XMLNode node = new XMLTag(IONIZABLE_GROUP_TAG); 188 node.setAttribute(KA_ATT, mKa + ""); 189 node.setAttribute(PROTONATED_FORM_ATT, mProtonatedForm.toString()); 190 191 return node; 192 } 193}