001package com.hfg.chem; 002 003import java.util.Map; 004 005import com.hfg.util.collection.CollectionUtil; 006 007//------------------------------------------------------------------------------ 008/** 009 Elemental composition and mass tracking object. 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 OrganicMatterImpl extends MatterImpl implements OrganicMatter, Cloneable 036{ 037 038 //########################################################################## 039 // PRIVATE FIELDS 040 //########################################################################## 041 042 private Double mOrganicAverageMass; 043 044 private boolean mOrganicAverageMassIsUserSet; 045 046 //########################################################################## 047 // CONSTRUCTORS 048 //########################################################################## 049 050 //-------------------------------------------------------------------------- 051 public OrganicMatterImpl() 052 { 053 super(); 054 } 055 056 //-------------------------------------------------------------------------- 057 public OrganicMatterImpl(Map<Element, Float> inMap) 058 { 059 super(inMap); 060 } 061 062 //-------------------------------------------------------------------------- 063 public OrganicMatterImpl(OrganicMatter inInitialValue) 064 { 065 super(inInitialValue); 066 067 if (inInitialValue != null) 068 { 069 setOrganicAverageMass(inInitialValue.getOrganicAverageMass()); 070 } 071 } 072 073 //########################################################################## 074 // PUBLIC METHODS 075 //########################################################################## 076 077 //-------------------------------------------------------------------------- 078 @Override 079 public boolean equals(Object inObj) 080 { 081 boolean result = false; 082 083 if (inObj != null 084 && inObj instanceof OrganicMatterImpl) 085 { 086 result = (0 == compareTo((OrganicMatterImpl) inObj)); 087 } 088 089 return result; 090 } 091 092 //-------------------------------------------------------------------------- 093 @Override 094 public OrganicMatterImpl add(Matter inValue, int inCount) 095 { 096 if (inValue != null) 097 { 098 super.add(inValue, inCount); 099 100 if (mOrganicAverageMassIsUserSet 101 || (null == inValue.getElementalComposition() 102 && ((inValue instanceof OrganicMatter 103 && ((OrganicMatter)inValue).getOrganicAverageMass() != null) 104 || inValue.getAverageMass() != null))) 105 { 106 setOrganicAverageMass((mOrganicAverageMassIsUserSet ? mOrganicAverageMass : CollectionUtil.hasValues(getElementalComposition()) ? getOrganicAverageMass() : 0.0) 107 + (inValue instanceof OrganicMatter ? 108 ((((OrganicMatter)inValue).getOrganicAverageMass() != null ? ((OrganicMatter)inValue).getOrganicAverageMass() : inValue.getAverageMass()) * inCount) : 109 inValue.getAverageMass() * inCount)); 110 } 111 } 112 113 return this; 114 } 115 116 //-------------------------------------------------------------------------- 117 @Override 118 public OrganicMatterImpl remove(Matter inValue) 119 { 120 return remove(inValue, 1); 121 } 122 123 //-------------------------------------------------------------------------- 124 @Override 125 public OrganicMatterImpl remove(Matter inValue, int inCount) 126 { 127 // This will call add() with a negative count 128 return (OrganicMatterImpl) super.remove(inValue, inCount); 129 } 130 131 //-------------------------------------------------------------------------- 132 /** 133 If the elemental composition is known, use setElementalComposition() and 134 the masses will be derived automatically; this method is for use in those 135 (hopefully) rare times when the mass is known but not the elemental composition. 136 @param inValue the mass to use as the organic average mass for this object 137 @return this OrganicMatterImpl object to enable method chaining 138 */ 139 public OrganicMatterImpl setOrganicAverageMass(Double inValue) 140 { 141 mOrganicAverageMass = inValue; 142 143 mOrganicAverageMassIsUserSet = (inValue != null && calculateOrganicMassFromElementalComposition() != mOrganicAverageMass); 144 145 return this; 146 } 147 148 //-------------------------------------------------------------------------- 149 public Double getOrganicAverageMass() 150 { 151 if (null == mOrganicAverageMass) 152 { 153 calculateMassFromElementalComposition(); 154 } 155 156 return mOrganicAverageMass; 157 } 158 159 160 //-------------------------------------------------------------------------- 161 @Override 162 public OrganicMatterImpl clone() 163 { 164 return (OrganicMatterImpl) super.clone(); 165 } 166 167 168 //-------------------------------------------------------------------------- 169 @Override 170 public void clearCalculatedProperties() 171 { 172 super.clearCalculatedProperties(); 173 if (! mOrganicAverageMassIsUserSet) mOrganicAverageMass = null; 174 } 175 176 //########################################################################## 177 // PROTECTED METHODS 178 //########################################################################## 179 180 //-------------------------------------------------------------------------- 181 @Override 182 protected void calculateMassFromElementalComposition() 183 { 184 super.calculateMassFromElementalComposition(); 185 186 if (! mOrganicAverageMassIsUserSet) 187 { 188 mOrganicAverageMass = calculateOrganicMassFromElementalComposition(); 189 } 190 } 191 192 193 //-------------------------------------------------------------------------- 194 @Override 195 protected boolean massesAreUserSet() 196 { 197 return (super.massesAreUserSet() || mOrganicAverageMassIsUserSet); 198 } 199 200 //########################################################################## 201 // PRIVATE METHODS 202 //########################################################################## 203 204 //-------------------------------------------------------------------------- 205 private double calculateOrganicMassFromElementalComposition() 206 { 207 double organicAvg = 0.0; 208 209 Map<Element, Float> elementalCompositionMap = getElementalComposition(); 210 if (elementalCompositionMap != null) 211 { 212 for (Element element : elementalCompositionMap.keySet()) 213 { 214 float count = elementalCompositionMap.get(element); 215 216 Double elementalAvgMass = element.getAverageMass(); 217 Double elementalOrgAvgMass = element.getOrganicAverageMass(); 218 219 organicAvg += count * (elementalOrgAvgMass != null ? elementalOrgAvgMass : elementalAvgMass != null ? elementalAvgMass : element.getMonoisotopicMass()); 220 } 221 222 } 223 224 return organicAvg; 225 } 226}