Skip to content

Commit b5aa916

Browse files
author
Arthur Glowacki
committed
Refactor to use enum for electron shell. Added ROI fit per electron shell
1 parent fcb1e29 commit b5aa916

18 files changed

Lines changed: 229 additions & 107 deletions

src/core/process_whole.h

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ POSSIBILITY OF SUCH DAMAGE.
6060
#include <limits>
6161
#include <sstream>
6262
#include <fstream>
63+
#include <typeinfo>
6364

6465
#include <stdlib.h>
6566

@@ -158,6 +159,43 @@ DLL_EXPORT data_struct::Fit_Count_Dict<T_real>* generate_fit_count_dict(const Fi
158159
return element_fit_counts_dict;
159160
}
160161

162+
// ----------------------------------------------------------------------------
163+
164+
template<typename T_real>
165+
DLL_EXPORT data_struct::Fit_Count_Dict<T_real>* generate_fit_count_by_shell_dict(const Fit_Element_Map_Dict<T_real>* elements_to_fit, size_t height, size_t width, bool alloc_iter_count)
166+
{
167+
data_struct::Fit_Count_Dict<T_real>* element_fit_counts_dict = new data_struct::Fit_Count_Dict<T_real>();
168+
for (auto& e_itr : *elements_to_fit)
169+
{
170+
for (auto& s_itr : e_itr.second->generate_roi_centers_per_shell())
171+
{
172+
element_fit_counts_dict->emplace(std::pair<std::string, data_struct::ArrayXXr<T_real> >(e_itr.first + "_" + s_itr.first, data_struct::ArrayXXr<T_real>()));
173+
element_fit_counts_dict->at(e_itr.first + "_" + s_itr.first).resize(height, width);
174+
}
175+
}
176+
177+
if (alloc_iter_count)
178+
{
179+
//Allocate memeory to save number of fit iterations
180+
element_fit_counts_dict->emplace(std::pair<std::string, data_struct::ArrayXXr<T_real> >(STR_NUM_ITR, data_struct::ArrayXXr<T_real>()));
181+
element_fit_counts_dict->at(STR_NUM_ITR).resize(height, width);
182+
element_fit_counts_dict->emplace(std::pair<std::string, data_struct::ArrayXXr<T_real> >(STR_RESIDUAL, data_struct::ArrayXXr<T_real>()));
183+
element_fit_counts_dict->at(STR_RESIDUAL).resize(height, width);
184+
}
185+
186+
// TOTAL_FLUORESCENCE_YIELD
187+
element_fit_counts_dict->emplace(std::pair<std::string, data_struct::ArrayXXr<T_real> >(STR_TOTAL_FLUORESCENCE_YIELD, data_struct::ArrayXXr<T_real>()));
188+
element_fit_counts_dict->at(STR_TOTAL_FLUORESCENCE_YIELD).resize(height, width);
189+
190+
//SUM_ELASTIC_INELASTIC
191+
element_fit_counts_dict->emplace(std::pair<std::string, data_struct::ArrayXXr<T_real> >(STR_SUM_ELASTIC_INELASTIC_AMP, data_struct::ArrayXXr<T_real>()));
192+
element_fit_counts_dict->at(STR_SUM_ELASTIC_INELASTIC_AMP).resize(height, width);
193+
194+
195+
return element_fit_counts_dict;
196+
}
197+
198+
161199
// ----------------------------------------------------------------------------
162200

163201
template<typename T_real>
@@ -236,7 +274,7 @@ DLL_EXPORT void proc_spectra(data_struct::Spectra_Volume<T_real>* spectra_volume
236274
fitting::models::Range energy_range = data_struct::get_energy_range(spectra_volume->samples_size(), &(detector->fit_params_override_dict.fit_params));
237275

238276
std::chrono::time_point<std::chrono::system_clock> start, end;
239-
277+
240278
for (auto& itr : detector->fit_routines)
241279
{
242280
fitting::routines::Base_Fit_Routine<T_real>* fit_routine = itr.second;
@@ -253,8 +291,17 @@ DLL_EXPORT void proc_spectra(data_struct::Spectra_Volume<T_real>* spectra_volume
253291
//Fit job queue
254292
std::queue<std::future<bool> >* fit_job_queue = new std::queue<std::future<bool> >();
255293

294+
data_struct::Fit_Count_Dict<T_real>* element_fit_count_dict = nullptr;
256295
//Allocate memeory to save fit counts
257-
data_struct::Fit_Count_Dict<T_real>* element_fit_count_dict = generate_fit_count_dict(&override_params->elements_to_fit, spectra_volume->rows(), spectra_volume->cols(), true);
296+
if (typeid(*fit_routine) == typeid(fitting::routines::ROI_Fit_Routine<T_real>) && scan_type == STR_SCAN_TYPE_POLAR_XANES)
297+
{
298+
((fitting::routines::ROI_Fit_Routine<T_real> *)fit_routine)->set_fit_separate_shells(true);
299+
element_fit_count_dict = generate_fit_count_by_shell_dict(&override_params->elements_to_fit, spectra_volume->rows(), spectra_volume->cols(), true);
300+
}
301+
else
302+
{
303+
element_fit_count_dict = generate_fit_count_dict(&override_params->elements_to_fit, spectra_volume->rows(), spectra_volume->cols(), true);
304+
}
258305

259306
for (size_t i = 0; i < spectra_volume->rows(); i++)
260307
{

src/data_struct/detector.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ void Detector<T_real>::append_element(Fitting_Routines routine, std::string quan
111111
Element_Info<T_real>* element = Element_Info_Map<T_real>::inst()->get_element(name);
112112
if (element != nullptr)
113113
{
114-
Electron_Shell shell = get_shell_by_name(name);
114+
data_struct::Electron_Shell shell = get_shell_by_name(name);
115115
fitting_quant_map.at(routine).update_weight_if_greater(shell, element->number, weight);
116116

117117
if (fitting_quant_map.at(routine).quant_scaler_map.count(quant_scaler) > 0)
@@ -161,11 +161,11 @@ void Detector<T_real>::update_element_quants(Fitting_Routines routine,
161161
if (eq_itr.weight > 0.0)
162162
{
163163
std::string name = eq_itr.name;
164-
if (shell_itr == Electron_Shell::L_SHELL)
164+
if (shell_itr == data_struct::Electron_Shell::L_SHELL)
165165
{
166166
name += "_L";
167167
}
168-
if (shell_itr == Electron_Shell::M_SHELL)
168+
if (shell_itr == data_struct::Electron_Shell::M_SHELL)
169169
{
170170
name += "_M";
171171
}

src/data_struct/element_info.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,37 @@ POSSIBILITY OF SUCH DAMAGE.
5252

5353
namespace data_struct
5454
{
55+
5556

5657
// ----------------------------------------------------------------------------
5758

59+
Electron_Shell get_shell_by_name(std::string element_name)
60+
{
61+
int idx = element_name.find_last_of("_") + 1;
62+
std::string shell_type = element_name.substr(idx);
63+
if (idx == 0)
64+
{
65+
return data_struct::Electron_Shell::K_SHELL;
66+
}
67+
else
68+
{
69+
if (shell_type == "L")
70+
{
71+
return data_struct::Electron_Shell::L_SHELL;
72+
}
73+
if (shell_type == "M")
74+
{
75+
return data_struct::Electron_Shell::M_SHELL;
76+
}
77+
}
78+
79+
80+
return data_struct::Electron_Shell::K_SHELL;
81+
}
82+
83+
// ----------------------------------------------------------------------------
84+
// ----------------------------------------------------------------------------
85+
5886
template<typename T_real>
5987
Element_Info<T_real>::Element_Info()
6088
{

src/data_struct/element_info.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ POSSIBILITY OF SUCH DAMAGE.
5959
namespace data_struct
6060
{
6161

62+
enum class Electron_Shell { K_SHELL, L_SHELL, M_SHELL, N_SHELL, O_SHELL, P_SHELL, Q_SHELL };
63+
64+
const static std::map<Electron_Shell, std::string> Shell_To_String = { {Electron_Shell::K_SHELL, "K"},
65+
{Electron_Shell::L_SHELL, "L"} ,
66+
{Electron_Shell::M_SHELL, "M"} ,
67+
{Electron_Shell::N_SHELL, "N"} ,
68+
{Electron_Shell::O_SHELL, "O"} ,
69+
{Electron_Shell::P_SHELL, "P"},
70+
{Electron_Shell::Q_SHELL, "Q"} };
71+
72+
73+
DLL_EXPORT Electron_Shell get_shell_by_name(std::string element_name);
74+
6275
template<typename T_real>
6376
struct DLL_EXPORT Element_Info
6477
{

src/data_struct/fit_element_map.cpp

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,23 +76,35 @@ Fit_Element_Map<T_real>::Fit_Element_Map(std::string name, Element_Info<T_real>*
7676
int idx = _full_name.find_last_of("_") + 1;
7777
if(idx == 0)
7878
{
79-
_shell_type = "K";
79+
_shell_type = Electron_Shell::K_SHELL;
8080
}
8181
else
8282
{
83-
_shell_type = _full_name.substr(idx);
83+
std::string str_shell = _full_name.substr(idx);
84+
if (str_shell == "L")
85+
{
86+
_shell_type = Electron_Shell::L_SHELL;
87+
}
88+
else if (str_shell == "L")
89+
{
90+
_shell_type = Electron_Shell::L_SHELL;
91+
}
92+
else //default to K shell
93+
{
94+
_shell_type = Electron_Shell::K_SHELL;
95+
}
8496
}
8597

8698

87-
if (_shell_type == "K") // K line
99+
if (_shell_type == Electron_Shell::K_SHELL) // K line
88100
{
89101
num_ratios = 4;
90102
}
91-
else if (_shell_type == "L")
103+
else if (_shell_type == Electron_Shell::L_SHELL)
92104
{
93105
num_ratios = 12;
94106
}
95-
else if (_shell_type == "M")
107+
else if (_shell_type == Electron_Shell::M_SHELL)
96108
{
97109
num_ratios = 4;
98110
}
@@ -131,7 +143,7 @@ void Fit_Element_Map<T_real>::init_energy_ratio_for_detector_element(const Eleme
131143

132144
_energy_ratios.clear();
133145

134-
if (_shell_type == "K") // K line
146+
if (_shell_type == Electron_Shell::K_SHELL) // K line
135147
{
136148
if(_pileup_element_info != nullptr) // pileup's
137149
{
@@ -163,7 +175,7 @@ void Fit_Element_Map<T_real>::init_energy_ratio_for_detector_element(const Eleme
163175

164176

165177
}
166-
else if (_shell_type == "L")
178+
else if (_shell_type == Electron_Shell::L_SHELL)
167179
{
168180
_center = _element_info->xrf["la1"];
169181
if (false == disable_La)
@@ -182,7 +194,7 @@ void Fit_Element_Map<T_real>::init_energy_ratio_for_detector_element(const Eleme
182194
generate_energy_ratio(_element_info->xrf["ll"], (_element_info->xrf_abs_yield["ll"] / _element_info->xrf_abs_yield["la1"]) * _energy_ratio_custom_multipliers[10], Element_Param_Type::Ll_Line, detector_element);
183195
generate_energy_ratio(_element_info->xrf["ln"], (_element_info->xrf_abs_yield["ln"] / _element_info->xrf_abs_yield["la1"]) * _energy_ratio_custom_multipliers[11], Element_Param_Type::Ln_Line, detector_element);
184196
}
185-
else if (_shell_type == "M")
197+
else if (_shell_type == Electron_Shell::M_SHELL)
186198
{
187199
// M5 - N7
188200
T_real ratio = 1.0;
@@ -357,7 +369,7 @@ bool Fit_Element_Map<T_real>::check_binding_energy(T_real incident_energy, int e
357369
{
358370
if( _pileup_element_info != nullptr)
359371
{
360-
if (_shell_type == "K")
372+
if (_shell_type == Electron_Shell::K_SHELL)
361373
{
362374
if (_center < incident_energy)
363375
{
@@ -367,14 +379,14 @@ bool Fit_Element_Map<T_real>::check_binding_energy(T_real incident_energy, int e
367379
}
368380
else
369381
{
370-
if (_shell_type == "K")
382+
if (_shell_type == Electron_Shell::K_SHELL)
371383
{
372384
if (_element_info->bindingE["K"] < incident_energy)
373385
{
374386
return true;
375387
}
376388
}
377-
else if (_shell_type == "L")
389+
else if (_shell_type == Electron_Shell::L_SHELL)
378390
{
379391
switch (energy_ratio_idx)
380392
{
@@ -409,7 +421,7 @@ bool Fit_Element_Map<T_real>::check_binding_energy(T_real incident_energy, int e
409421
break;
410422
}
411423
}
412-
else if (_shell_type == "M")
424+
else if (_shell_type == Electron_Shell::M_SHELL)
413425
{
414426
if (_element_info->bindingE["M1"] < incident_energy)
415427
{
@@ -425,6 +437,43 @@ bool Fit_Element_Map<T_real>::check_binding_energy(T_real incident_energy, int e
425437
return false;
426438
}
427439

440+
//-----------------------------------------------------------------------------
441+
442+
template<typename T_real>
443+
std::unordered_map<std::string, T_real> Fit_Element_Map<T_real>::generate_roi_centers_per_shell()
444+
{
445+
std::unordered_map<std::string, T_real> map;
446+
if (_shell_type == Electron_Shell::K_SHELL)
447+
{
448+
map["ka1"] = _element_info->xrf["ka1"];
449+
map["ka2"] = _element_info->xrf["ka2"];
450+
map["kb1"] = _element_info->xrf["kb1"];
451+
map["kb2"] = _element_info->xrf["kb2"];
452+
}
453+
else if (_shell_type == Electron_Shell::L_SHELL)
454+
{
455+
map["la2"] = _element_info->xrf["la2"];
456+
map["lb1"] = _element_info->xrf["lb1"];
457+
map["lb2"] = _element_info->xrf["lb2"];
458+
map["lb3"] = _element_info->xrf["lb3"];
459+
map["lb4"] = _element_info->xrf["lb4"];
460+
map["lg1"] = _element_info->xrf["lg1"];
461+
map["lg2"] = _element_info->xrf["lg2"];
462+
map["lg3"] = _element_info->xrf["lg3"];
463+
map["lg4"] = _element_info->xrf["lg4"];
464+
map["ll"] = _element_info->xrf["ll"];
465+
map["ln"] = _element_info->xrf["ln"];
466+
}
467+
else if (_shell_type == Electron_Shell::M_SHELL)
468+
{
469+
map["ma1"] = _element_info->xrf["ma1"];
470+
map["ma2"] = _element_info->xrf["ma2"];
471+
map["mb"] = _element_info->xrf["mb"];
472+
map["mg"] = _element_info->xrf["mg"];
473+
}
474+
return map;
475+
}
476+
428477
//-----------------------------------------------------------------------------
429478
//-----------------------------------------------------------------------------
430479

src/data_struct/fit_element_map.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ class DLL_EXPORT Fit_Element_Map
189189

190190
const Element_Info<T_real>* pileup_element() const { return _pileup_element_info; }
191191

192-
const std::string& shell_type_as_string() const { return _shell_type; }
192+
Electron_Shell shell_type() const { return _shell_type; }
193+
194+
std::unordered_map<std::string, T_real> generate_roi_centers_per_shell();
193195

194196
bool check_binding_energy(T_real incident_energy, int energy_ratio_idx) const;
195197
protected:
@@ -203,7 +205,7 @@ class DLL_EXPORT Fit_Element_Map
203205
std::vector<Element_Energy_Ratio<T_real>> _energy_ratios;
204206
std::vector<T_real> _energy_ratio_custom_multipliers;
205207

206-
std::string _shell_type;
208+
Electron_Shell _shell_type;
207209

208210
T_real _center;
209211
T_real _width;

src/data_struct/quantification_standard.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ namespace data_struct
6464

6565
using namespace quantification::models;
6666

67-
const static std::vector<Electron_Shell> Shells_Quant_List({ Electron_Shell::K_SHELL, Electron_Shell::L_SHELL, Electron_Shell::M_SHELL });
67+
const static std::vector<data_struct::Electron_Shell> Shells_Quant_List({ data_struct::Electron_Shell::K_SHELL, data_struct::Electron_Shell::L_SHELL, data_struct::Electron_Shell::M_SHELL });
6868

6969
//-----------------------------------------------------------------------------
7070
//-----------------------------------------------------------------------------
@@ -84,7 +84,7 @@ struct DLL_EXPORT Quantification_Scaler_Struct
8484
curve_quant_map[itr] = e_quants;
8585
}
8686
}
87-
std::unordered_map<Electron_Shell, std::vector<Element_Quant<T_real>> > curve_quant_map;
87+
std::unordered_map<data_struct::Electron_Shell, std::vector<Element_Quant<T_real>> > curve_quant_map;
8888
};
8989

9090
TEMPLATE_STRUCT_DLL_EXPORT Quantification_Scaler_Struct<float>;
@@ -116,15 +116,15 @@ struct DLL_EXPORT Fitting_Quantification_Struct
116116
}
117117
}
118118

119-
void update_weight(Electron_Shell shell, unsigned int Z, T_real weight)
119+
void update_weight(data_struct::Electron_Shell shell, unsigned int Z, T_real weight)
120120
{
121121
for (auto& itr : quant_scaler_map)
122122
{
123123
itr.second.curve_quant_map.at(shell).at(Z - 1).weight = weight;
124124
}
125125
}
126126

127-
void update_weight_if_greater(Electron_Shell shell, unsigned int Z, T_real weight)
127+
void update_weight_if_greater(data_struct::Electron_Shell shell, unsigned int Z, T_real weight)
128128
{
129129
for (auto& itr : quant_scaler_map)
130130
{

src/fitting/routines/roi_fit_routine.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ optimizers::OPTIMIZER_OUTCOME ROI_Fit_Routine<T_real>::fit_spectra(const models:
9090
Fit_Element_Map<T_real>* element = e_itr.second;
9191
if (element != nullptr)
9292
{
93-
if(_separate_lines == false)
93+
if(_separate_shells == false)
9494
{
9595
left_roi = static_cast<unsigned int>(std::round(((element->center() - element->width()) - energy_offset) / energy_slope));
9696
right_roi = static_cast<unsigned int>(std::round(((element->center() + element->width()) - energy_offset) / energy_slope));
@@ -109,7 +109,23 @@ optimizers::OPTIMIZER_OUTCOME ROI_Fit_Routine<T_real>::fit_spectra(const models:
109109
}
110110
else
111111
{
112-
112+
for (auto& s_itr : element->generate_roi_centers_per_shell())
113+
{
114+
left_roi = static_cast<unsigned int>(std::round(((s_itr.second - element->width()) - energy_offset) / energy_slope));
115+
right_roi = static_cast<unsigned int>(std::round(((s_itr.second + element->width()) - energy_offset) / energy_slope));
116+
117+
if (right_roi >= n_mca_channels)
118+
{
119+
right_roi = n_mca_channels - 2;
120+
}
121+
if (left_roi > right_roi)
122+
{
123+
left_roi = right_roi - 1;
124+
}
125+
126+
size_t spec_size = (right_roi - left_roi) + 1;
127+
out_counts[e_itr.first+"_"+s_itr.first] = spectra->segment(left_roi, spec_size).sum();
128+
}
113129
}
114130
}
115131
}

0 commit comments

Comments
 (0)