package edu.stanford.rsl.conrad.physics.materials; import java.util.Iterator; import java.util.TreeMap; import edu.stanford.rsl.conrad.physics.materials.database.MaterialsDB; /** * <p>This class stores the weighted atomic composition of a material. * <br/>The weighted atomic composition of a material is a key-sorted map containing its constituting elements(keys) and their contribution by weight.</p> * <p>H2O is stored as:</p> * <p><H , 2 * atomic weight of hydrogen><br/> * <O , 1 * atomic weight of oxygen></p> * * @author Rotimi .X. Ojo * */ public class WeightedAtomicComposition { private TreeMap<String, Double> composition = new TreeMap<String, Double>(); public WeightedAtomicComposition(){} public WeightedAtomicComposition(String formula){ add(formula, 1); } public WeightedAtomicComposition(String formula, double proportion){ add(formula, proportion); } /** * Add an element to table. * @param formula is formula of element * @param proportion is atomic contribution by weight. For a compound, proportion = number of atoms * atomic weight; */ public void add(String formula, double proportion){ int lastIndex = 0; for(int i = 1; i < formula.length(); i++){ String curr = formula.substring(i,i+1); if(curr.toUpperCase().equals(curr) && !curr.matches("\\p{Digit}+")){ addTokenToMap(formula.substring(lastIndex, i), proportion); lastIndex = i; } } addTokenToMap(formula.substring(lastIndex).trim(), proportion); } /** * <p>To be used if there exists only one instance of element in formula. This method by rebuildDatabase for bootstrapping.</div> * <br>Users are encouraged to use the add method.</p> * @param formula is formula of element * @param weight is atomic weight of element */ public void addUniqueElement(String formula, double weight){ composition.put(formula.trim(), weight); } private void addTokenToMap(String token, double proportion) { int stop = indexOfDigit(token); String element = token; double weight = 0; if(stop == -1){ weight = ((Element)MaterialsDB.getMaterial(token)).getAtomicWeight()*proportion; }else{ element = token.substring(0, stop).trim(); weight = Double.valueOf(token.substring(stop))*((Element)MaterialsDB.getMaterial(element)).getAtomicWeight()*proportion; } if (composition.containsKey(element)) { weight += composition.get(element); } composition.put(element, weight); } private int indexOfDigit(String token) { for(int i = 0; i < token.length(); i++){ String Char = token.charAt(i)+""; if(Char.matches("\\p{Digit}+")){ return i; } } return -1; } public void setCompositionTable(TreeMap<String, Double> composition) { this.composition = composition; } public TreeMap<String, Double> getCompositionTable() { return composition; } public int size() { return composition.size(); } public Iterator<Double> valuesIterator() { return composition.values().iterator(); } public Iterator<String> keysIterator(){ return composition.keySet().iterator(); } } /* * Copyright (C) 2010-2014 Rotimi X Ojo * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */