package edu.stanford.rsl.conrad.physics.materials;
import java.io.Serializable;
import java.util.ArrayList;
import edu.stanford.rsl.conrad.physics.Constants;
import edu.stanford.rsl.conrad.physics.materials.database.CompositionToAbsorptionEdgeMap;
import edu.stanford.rsl.conrad.physics.materials.database.OnlineMassAttenuationDB;
import edu.stanford.rsl.conrad.physics.materials.materialsTest.TestMassAttenuationData;
import edu.stanford.rsl.conrad.physics.materials.utils.AttenuationRetrievalMode;
import edu.stanford.rsl.conrad.physics.materials.utils.AttenuationType;
import edu.stanford.rsl.conrad.physics.materials.utils.LocalMassAttenuationCalculator;
import edu.stanford.rsl.conrad.physics.materials.utils.WeightedAtomicComposition;
/**
* <p>This class models an arbitrary material. Materials are defined by density and their characteristic attenuation of XRays of different energies.</p>
* <p> Note. A material without a defined energy dependent attenuation cannot be used in polychromatic XRay projection modeling</p>.
* @author Rotimi X Ojo
*/
public class Material implements Serializable, Cloneable{
private static final long serialVersionUID = -335499247531855579L;
private String name = "";
private double density = -1;
private transient double CTValue = 0;
private WeightedAtomicComposition comp;
public Material(){}
/**
* Initializes a material with a given density. To support polychromatic absorption, an energy dependent attenuation TreeMap must be provided.
* @param density is density of initialized material
*/
public Material(double density){
setDensity(density);
}
public Material(Material material) {
this.name = new String(material.name);
this.density = material.density;
this.CTValue = material.CTValue;
// shallow copy of composition tree!
this.comp = material.comp;
}
/**
* Update the name of the material.
* @param name is name of material
*/
public void setName(String name) {
this.name = name;
}
/**
* Retrieve the name of the material
* @return the name of the material
*/
public String getName() {
return name;
}
/**
* Retrieve the CT value of a given material in [HU]
* @return 0 if CTValue is not available
*/
public double getCTValue() {
return CTValue;
}
/**
* Retrieve the energy dependent attenuation of material
* @param energy is energy of interest in KeV
* @param attType is type of attenuation, all types of attenuation are supported.
* @return double representing the energy dependent attenuation of material sourced locally in [cm^-1].
* @see AttenuationType
* @see TestMassAttenuationData
*/
public double getAttenuation(double energy, AttenuationType attType) {
return getAttenuation(energy, attType, AttenuationRetrievalMode.LOCAL_RETRIEVAL);
}
/**
* Retrieve the energy dependent attenuation of material.
* @param energy is energy of interest in KeV
* @param attType is type of attenuation, all types of attenuation are supported.
* @param mode is retrieval mode.
* @return is type of attenuation, all types of attenuation are supported.
* @see AttenuationType
* @see AttenuationRetrievalMode
* @see TestMassAttenuationData
*/
public double getAttenuation(double energy, AttenuationType attType, AttenuationRetrievalMode mode){
if(mode.equals(AttenuationRetrievalMode.ONLINE_RETRIEVAL)){
return density * OnlineMassAttenuationDB.getMassAttenuationData(comp, energy/1000, attType);
}else{
return density * LocalMassAttenuationCalculator.getMassAttenuationData(comp, energy/1000, attType);
}
}
/**
* Update the density and CT Value of the material with given value
* @param density is density of the material
*/
public void setDensity(double density) {
this.density = density;
CTValue = Constants.computeCTValue(density);
}
/**
* Retrieves the density of the material in [g/cm^3]
* @return -1 if density is not available
*/
public double getDensity() {
return density;
}
/**
* Update the atomic composition of material by mass
* @param comp is Treemap containing the atomic composition of material by mass
*/
public void setWeightedAtomicComposition(WeightedAtomicComposition comp){
this.comp = comp;
}
/**
* Retrieve the atomic composition of material by mass
* @return null if atomic composition table is not available
*/
public WeightedAtomicComposition getWeightedAtomicComposition(){
return comp;
}
/**
* Retrieve all the absorption edges of material in MeV.
* @return an empty array if there are no absorption edge
*/
public ArrayList<Double> getAbsorptionEdges(){
return CompositionToAbsorptionEdgeMap.getAbsorptionEdges(comp);
}
/**
* Materials are hashed by their name.
* @return the hash code of the material name.
*/
public int hashCode(){
return getName().hashCode();
}
@Override
public boolean equals(Object other){
if (other instanceof Material)
return getName().equals(((Material)other).getName());
else
return false;
}
/**
* Materials are equal if they have the same name.
* @param other the other material
* @return true if name is the same.
*/
public boolean equals(Material other){
return getName().equals(other.getName());
}
@Override
public String toString(){
return name;
}
@Override
public Material clone(){
return new Material(this);
}
}
/*
* Copyright (C) 2010-2014 Rotimi X Ojo
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/