gVirtualXRay  2.0.10
VirtualX-RayImagingLibraryonGPU
TissueMaterial.inl
Go to the documentation of this file.
1 /*
2 
3 Copyright (c) 2013-2023, Dr Franck P. Vidal, Bangor University, All rights reserved.
4 Copyright (c) 2023-present, Prof Franck P. Vidal (franck.vidal@stfc.ac.uk),
5 UK Research and Innovation, All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14 this list of conditions and the following disclaimer in the documentation and/or
15 other materials provided with the distribution.
16 
17 3. Neither the name of the Bangor University nor the names of its contributors
18 may be used to endorse or promote products derived from this software without
19 specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 
32 */
33 
34 
67 //******************************************************************************
68 // Include
69 //******************************************************************************
70 #include <cstring>
71 
72 #ifndef __ConstantValues_h
74 #endif
75 
76 
77 //******************************************************************************
78 // namespace
79 //******************************************************************************
80 namespace gVirtualXRay {
81 
82 
83 //------------------------------------------------------
84 inline TissueMaterial::TissueMaterial(short aMinHUValue,
85  short aMaxHUValue,
86  double H,
87  double C,
88  double N,
89  double O,
90  double Na,
91  double Mg,
92  double P,
93  double S,
94  double Cl,
95  double Ar,
96  double K,
97  double Ca,
98  double Ti,
99  double Cu,
100  double Zn,
101  double Ag,
102  double Sn,
103  double Fe,
104  double I):
105 //------------------------------------------------------
106  m_min_HU_value(aMinHUValue),
107  m_max_HU_value(aMaxHUValue)
108 //------------------------------------------------------
109 {
110  if (m_max_HU_value < m_min_HU_value)
111  {
112  throw Exception(__FILE__, __FUNCTION__, __LINE__, "The min HU value is greater than the max HU value. This is not possible.");
113  }
114 
115  std::map<int, double> weight_set;
116  weight_set[Z_H] = H;
117  weight_set[Z_C] = C;
118  weight_set[Z_N] = N;
119  weight_set[Z_O] = O;
120  weight_set[Z_Na] = Na;
121  weight_set[Z_Mg] = Mg;
122  weight_set[Z_P] = P;
123  weight_set[Z_S] = S;
124  weight_set[Z_Cl] = Cl;
125  weight_set[Z_Ar] = Ar;
126  weight_set[Z_K] = K;
127  weight_set[Z_Ca] = Ca;
128  weight_set[Z_Ti] = Ti;
129  weight_set[Z_Cu] = Cu;
130  weight_set[Z_Zn] = Zn;
131  weight_set[Z_Ag] = Ag;
132  weight_set[Z_Sn] = Sn;
133  weight_set[Z_Fe] = Fe;
134  weight_set[Z_I] = I;
135 
136  m_mixture.setMixture(weight_set);
137 }
138 
139 
140 //---------------------------------------------------------------------
142 //---------------------------------------------------------------------
143  m_min_HU_value(aMaterial.m_min_HU_value),
144  m_max_HU_value(aMaterial.m_max_HU_value),
145  m_mixture(aMaterial.m_mixture)
146 //---------------------------------------------------------------------
147 {
148 }
149 
150 
151 //---------------------------------
153 //---------------------------------
154 {
155  m_min_HU_value = 0;
156  m_max_HU_value = 0;
157 
158  m_mixture.clear();
159 }
160 
161 
162 //----------------------------------------------------------------------
163 inline const std::map<int, double>& TissueMaterial::getWeightSet() const
164 //----------------------------------------------------------------------
165 {
166  return m_mixture.getWeightSet();
167 }
168 
169 
170 //------------------------------------------------
171 inline short TissueMaterial::getMinHUValue() const
172 //------------------------------------------------
173 {
174  return (m_min_HU_value);
175 }
176 
177 
178 //------------------------------------------------
179 inline short TissueMaterial::getMaxHUValue() const
180 //------------------------------------------------
181 {
182  return (m_max_HU_value);
183 }
184 
185 
186 //-----------------------------------------------
187 inline double TissueMaterial::getMolarMass() const
188 //-----------------------------------------------
189 {
190  return (m_mixture.getMolarMass());
191 }
192 
193 
194 //-----------------------------------------------------
195 inline void TissueMaterial::setDensity(double aDensity)
196 //-----------------------------------------------------
197 {
198  m_mixture.setDensity(aDensity);
199 }
200 
201 
202 //--------------------------------------------------------------------------
203 inline double TissueMaterial::getMassAttenuationTotal(double anEnergy) const
204 //--------------------------------------------------------------------------
205 {
206  return (m_mixture.getMassAttenuationTotal(anEnergy));
207 }
208 
209 
210 //-----------------------------------------------------------------------------
211 inline double TissueMaterial::getLinearAttenuationTotal(short aHounsfieldValue,
212  double anEnergy) const
213 //-----------------------------------------------------------------------------
214 {
215  return (m_mixture.getMassAttenuationTotal(anEnergy) *
216  (getDensity(aHounsfieldValue)));
217 }
218 
219 
220 //---------------------------------------------------------
221 inline double TissueMaterial::getMu(short aHounsfieldValue,
222  double anEnergy) const
223 //---------------------------------------------------------
224 {
225  return (getLinearAttenuationTotal(aHounsfieldValue, anEnergy));
226 }
227 
228 
229 
230 //----------------------------------------------------------------------------
231 inline double TissueMaterial::getLinearAttenuationTotal(double anEnergy) const
232 //----------------------------------------------------------------------------
233 {
234  double density(m_mixture.getDensity());
235 
236  if (density < 0.0)
237  {
238  throw Exception(__FILE__, __FUNCTION__, __LINE__, "The density of the mixture has not been initialised. It is therefore impossible to compute the linear attenuation coefficient.");
239  }
240 
241  return (m_mixture.getMassAttenuationTotal(anEnergy) * density);
242 }
243 
244 
245 //---------------------------------------------------------
246 inline double TissueMaterial::getMu(double anEnergy) const
247 //---------------------------------------------------------
248 {
249  return (getLinearAttenuationTotal(anEnergy));
250 }
251 
252 
253 //------------------------------------------------
254 inline double TissueMaterial::getS(double x) const
255 //------------------------------------------------
256 {
257  throw Exception(__FILE__, __FUNCTION__, __LINE__, "Not implemented.");
258 }
259 
260 
261 //-------------------------------------------------------------------------------
263 //-------------------------------------------------------------------------------
264 {
265  // Prevent self-assignment
266  if (this != &aMaterial)
267  {
268  m_min_HU_value = aMaterial.m_min_HU_value;
269  m_max_HU_value = aMaterial.m_max_HU_value;
270  m_mixture = aMaterial.m_mixture;
271  }
272 
273  return (*this);
274 }
275 
276 
277 //---------------------------------------------------------------------------
278 inline bool TissueMaterial::operator==(const TissueMaterial& aMaterial) const
279 //---------------------------------------------------------------------------
280 {
281  if (m_min_HU_value != aMaterial.m_min_HU_value) return false;
282  if (m_max_HU_value != aMaterial.m_max_HU_value) return false;
283  if (m_mixture != aMaterial.m_mixture) return false;
284 
285  return (true);
286 }
287 
288 
289 //---------------------------------------------------------------------------
290 inline bool TissueMaterial::operator!=(const TissueMaterial& aMaterial) const
291 //---------------------------------------------------------------------------
292 {
293  return (!(operator==(aMaterial)));
294 }
295 
296 
297 //-----------------------------------------------------------------------
298 inline std::ostream & operator << (std::ostream& anOutputSream,
299  const TissueMaterial& aTissueMaterial)
300 //-----------------------------------------------------------------------
301 {
302  anOutputSream << aTissueMaterial.m_min_HU_value << "\t";
303  anOutputSream << aTissueMaterial.m_max_HU_value << "\t";
304 
305  for (std::map<int, double>::const_iterator ite = aTissueMaterial.getWeightSet().begin();
306  ite != aTissueMaterial.getWeightSet().end();
307  ++ite)
308  {
309  anOutputSream << ite->second << "\t";
310  }
311 
312  return (anOutputSream);
313 }
314 
315 
316 //-----------------------------------------------------------------
317 inline std::istream & operator >> (std::istream& anInputSream,
318  TissueMaterial& aTissueMaterial)
319 //-----------------------------------------------------------------
320 {
321  std::map<int, double> weight_set;
322 
323  anInputSream >> aTissueMaterial.m_min_HU_value;
324  anInputSream >> aTissueMaterial.m_max_HU_value;
325  anInputSream >> weight_set[Z_H];
326  anInputSream >> weight_set[Z_C];
327  anInputSream >> weight_set[Z_N];
328  anInputSream >> weight_set[Z_O];
329  anInputSream >> weight_set[Z_Na];
330  anInputSream >> weight_set[Z_Mg];
331  anInputSream >> weight_set[Z_P];
332  anInputSream >> weight_set[Z_S];
333  anInputSream >> weight_set[Z_Cl];
334  anInputSream >> weight_set[Z_Ar];
335  anInputSream >> weight_set[Z_K];
336  anInputSream >> weight_set[Z_Ca];
337  anInputSream >> weight_set[Z_Ti];
338  anInputSream >> weight_set[Z_Cu];
339  anInputSream >> weight_set[Z_Zn];
340  anInputSream >> weight_set[Z_Ag];
341  anInputSream >> weight_set[Z_Sn];
342  anInputSream >> weight_set[Z_Fe];
343  anInputSream >> weight_set[Z_I];
344 
345  aTissueMaterial.setMixture(weight_set);
346 
347  return (anInputSream);
348 }
349 
350 
351 } // namespace gVirtualXRay/
const unsigned short Z_S
Sulfur atomic number.
const unsigned short Z_H
Hydrogen atomic number.
double getMu(short aHounsfieldValue, double anEnergy) const
const unsigned short Z_Cl
Chlorine atomic number.
TissueMaterial(short aMinHUValue=0, short aMaxHUValue=0, double H=0, double C=0, double N=0, double O=0, double Na=0, double Mg=0, double P=0, double S=0, double Cl=0, double Ar=0, double K=0, double Ca=0, double Ti=0, double Cu=0, double Zn=0, double Ag=0, double Sn=0, double Fe=0, double I=0)
Default Constructor.
short getMinHUValue() const
Accessor on the minimum HU.
const unsigned short Z_Zn
Zinc atomic number.
double getMolarMass() const
Accessor on the molar mass of the material.
Definition: Mixture.inl:209
double getS(double x) const
double getMolarMass() const
Accessor on the molar mass of the material.
double getLinearAttenuationTotal(short aHounsfieldValue, double anEnergy) const
short getMaxHUValue() const
Accessor on the maximum HU.
Exception is a class to handle exceptions.
Definition: Exception.h:109
const unsigned short Z_N
Nitrogen atomic number.
void clear()
Remove all the atomic elements from the material.
std::istream & operator>>(std::istream &anInputSream, gVirtualXRay::AtomicElement &anElement)
operator >>
TissueMaterial & operator=(const TissueMaterial &aMaterial)
Copy operator.
const unsigned short Z_Sn
Tin atomic number.
const std::map< int, double > & getWeightSet() const
Accessor on the weight of each atomic element.
bool operator!=(const TissueMaterial &aMaterial) const
Operator !=.
const unsigned short Z_Cu
Copper atomic number.
const unsigned short Z_Ti
Titanium atomic number.
void setMixture(const std::map< int, double > &aWeightSet)
const unsigned short Z_P
Phosphorus atomic number.
void setDensity(double aDensity)
Set the density for the mixture regardless of the HU value.
const unsigned short Z_I
Iodine atomic number.
double getMassAttenuationTotal(double anEnergy) const
const unsigned short Z_Mg
Magnesium atomic number.
TissueMaterial is a class to manage a material.
const unsigned short Z_Ar
Argon atomic number.
std::ostream & operator<<(std::ostream &anOutputSream, const gVirtualXRay::AtomicElement &anElement)
operator <<
const unsigned short Z_Ca
Calcium atomic number.
void setMixture(const std::map< int, double > &aWeightSet)
Definition: Mixture.inl:145
const unsigned short Z_Fe
Iron atomic number.
const unsigned short Z_O
Oxygen atomic number.
const unsigned short Z_K
Potassium atomic number.
bool operator==(const TissueMaterial &aMaterial) const
Operator ==.
Constant values, such as the Z number of different atoms, etc.
const std::map< int, double > & getWeightSet() const
Definition: Mixture.inl:279
const unsigned short Z_C
Carbon atomic number.
const unsigned short Z_Ag
Silver atomic number.
void setDensity(double aDensity)
Definition: Mixture.inl:217
const unsigned short Z_Na
Sodium atomic number.