33 included_in_analysis_(true),
58 : map<
string, double>(other),
60 included_in_analysis_(other.included_in_analysis_),
61 marked_elements_(other.marked_elements_)
100 map<string, double>::operator=(other);
146 const map<string, element_information>* element_info)
const
149 if (element_info ==
nullptr) {
160 for (
const auto& element_entry : *
this) {
161 const string& element_name = element_entry.first;
162 const double concentration = element_entry.second;
165 auto info_iter = element_info->find(element_name);
166 if (info_iter == element_info->end()) {
179 if (should_include) {
181 filtered_profile[element_name] = concentration;
191 return filtered_profile;
241 bool exclude_elements,
242 bool apply_corrections,
243 const vector<double>& reference_om_size,
245 const map<string, element_information>* element_info)
const
251 if (apply_corrections) {
252 if (regression_models ==
nullptr) {
254 std::cerr <<
"Warning: apply_corrections=true but regression_models is null. "
255 <<
"Skipping corrections." << std::endl;
267 if (exclude_elements) {
268 if (element_info ==
nullptr) {
270 std::cerr <<
"Warning: exclude_elements=true but element_info is null. "
271 <<
"Skipping filtering." << std::endl;
331 const map<string, element_information>* element_info,
332 bool include_isotopes)
const
335 if (element_info ==
nullptr) {
338 std::cerr <<
"Error: ExtractChemicalElements called with null element_info. "
339 <<
"Returning empty profile." << std::endl;
346 for (
const auto& [element_name, concentration] : *
this) {
349 auto info_iter = element_info->find(element_name);
350 if (info_iter == element_info->end()) {
360 bool should_include =
false;
364 should_include =
true;
368 should_include = include_isotopes;
372 if (should_include) {
373 extracted_profile[element_name] = concentration;
377 return extracted_profile;
422 const vector<string>& element_names)
const
430 for (
const string& element_name : element_names) {
432 auto it = find(element_name);
435 extracted_profile[element_name] = it->second;
440 return extracted_profile;
452 auto it = find(element_name);
454 throw std::out_of_range(
455 "Element '" + element_name +
"' does not exist in profile"
486 auto it = find(element_name);
509 if (find(element_name) == end()) {
527 if (find(element_name) == end()) {
554 if (find(element_name) != end()) {
558 (*this)[element_name] = value;
577 vector<double> values;
578 values.reserve(size());
580 for (
const auto& [element_name, concentration] : *
this) {
581 values.push_back(concentration);
603 for (
const auto& [element_name, concentration] : *
this) {
604 output += element_name +
":" + aquiutils::numbertostring(concentration) +
"\n";
634 QTableWidget* table =
new QTableWidget();
635 table->setEditTriggers(QAbstractItemView::NoEditTriggers);
636 table->setColumnCount(1);
637 table->setRowCount(size());
640 QStringList element_names;
643 for (
const auto& [element_name, concentration] : *
this) {
644 element_names << QString::fromStdString(element_name);
645 table->setItem(row, 0,
new QTableWidgetItem(QString::number(concentration)));
650 table->item(row, 0)->setForeground(QColor(Qt::red));
657 table->setHorizontalHeaderLabels(headers);
658 table->setVerticalHeaderLabels(element_names);
676 QJsonObject json_object;
677 QJsonObject element_contents;
681 for (
const auto& [element_name, concentration] : *
this) {
682 element_contents[QString::fromStdString(element_name)] = concentration;
685 json_object[
"Element Contents"] = element_contents;
711 if (json_object.contains(
"Include")) {
715 QJsonObject contents = json_object[
"Element Contents"].toObject();
716 for (
const QString& key : contents.keys()) {
717 (*this)[key.toStdString()] = contents[key].toDouble();
722 for (
const QString& key : json_object.keys()) {
723 (*this)[key.toStdString()] = json_object[key].toDouble();
727 if (json_object.contains(
"XAxisLabel")) {
731 if (json_object.contains(
"YAxisLabel")) {
757 for (
const QString& line : string_list) {
758 QStringList parts = line.split(
":");
759 if (parts.size() > 1) {
780 file->write(QString::fromStdString(
ToString()).toUtf8());
799 double max_value = -1e12;
800 for (
const auto& [element_name, concentration] : *
this) {
801 if (concentration > max_value) {
802 max_value = concentration;
824 double min_value = 1e12;
825 for (
const auto& [element_name, concentration] : *
this) {
826 if (concentration < min_value) {
827 min_value = concentration;
841 vector<string> names;
842 names.reserve(size());
844 for (
const auto& [element_name, concentration] : *
this) {
845 names.push_back(element_name);
859 return (find(element_name) != end());
879 const vector<double>& reference_om_size,
881 const map<string, element_information>* element_info)
const
885 for (
const auto& [element_name, concentration] : *
this) {
895 corrected_profile[element_name] = concentration;
898 if (regression_models->count(element_name) == 0) {
903 const auto& var_names =
mlr->GetIndependentVariableNames();
904 const auto& coefficients =
mlr->CoefficientsIntercept();
908 if (
mlr->Effective(0) && var_names[0] != element_name) {
909 double reference = reference_om_size[0];
910 double measured = this->at(var_names[0]);
913 corrected_profile[element_name] += (reference - measured) * coefficients[1];
916 corrected_profile[element_name] *= pow(reference / measured, coefficients[1]);
921 if (var_names.size() > 1 &&
mlr->Effective(1) && var_names[1] != element_name) {
922 double reference = reference_om_size[1];
923 double measured = this->at(var_names[1]);
926 corrected_profile[element_name] += (reference - measured) * coefficients[2];
929 corrected_profile[element_name] *= pow(reference / measured, coefficients[2]);
934 if (corrected_profile[element_name] < 0 &&
936 std::cerr <<
"Warning: Corrected value for " << element_name
937 <<
" is negative: " << corrected_profile[element_name] << std::endl;
941 return corrected_profile;
961 if (size() != weights.getsize()) {
968 for (
const auto& [element_name, concentration] : *
this) {
969 sum += concentration * weights[index];
991 vector<string> processed_elements;
993 for (
size_t i = 0; i < size(); i++) {
994 double target_value = ascending ? 1e6 : -1e6;
995 string target_element;
997 for (
const auto& [element_name, concentration] : *
this) {
999 if (lookup(processed_elements, element_name) != -1) {
1004 bool is_better = ascending ? (concentration < target_value)
1005 : (concentration > target_value);
1008 target_element = element_name;
1009 target_value = concentration;
1013 processed_elements.push_back(target_element);
1014 sorted_result.
append(target_element, target_value);
1017 return sorted_result;
1035 vector<string> top_elements;
1037 for (
int i = 0; i < n && i < sorted.num; i++) {
1038 top_elements.push_back(sorted.
Label(i));
1041 return top_elements;
Vector class with string labels for Chemical Mass Balance analysis.
void append(const string &label, const double &val)
Appends a labeled element to the vector.
string Label(int i) const
Gets label at specified index.
Container for elemental concentration data of a single sediment sample.
Elemental_Profile & operator=(const Elemental_Profile &other)
Copy assignment operator.
Elemental_Profile CreateAnalysisProfile(const map< string, element_information > *elementinfo=nullptr) const
Create profile with only analyzed elements.
Elemental_Profile ExtractChemicalElements(const map< string, element_information > *elementinfo, bool include_isotopes=false) const
Extract chemical elements only (exclude isotopes, metadata)
Elemental_Profile ExtractElements(const vector< string > &element_names) const
Extract subset of specified elements.
Elemental_Profile ApplyOrganicMatterAndSizeCorrections(const vector< double > &reference_om_size, const MultipleLinearRegressionSet *regression_models, const map< string, element_information > *elementinfo=nullptr) const
Apply organic matter and particle size corrections.
bool IsMarked(const string &name) const
Check if element is marked.
map< string, bool > marked_elements_
Map tracking marked elements for quality control.
double GetMaximum() const
Get maximum concentration value.
vector< string > GetElementNames() const
Get list of all element names.
double CalculateDotProduct(const CMBVector &weights) const
Calculate dot product with weight vector.
CMBVector SortByConcentration(bool ascending=true) const
Sort elements by concentration value.
bool included_in_analysis_
Whether profile should be included in analysis.
double GetMinimum() const
Get minimum concentration value.
vector< double > GetAllValues() const
Get all concentration values as vector.
bool SetMarked(const string &name, bool marked)
Set marked status for an element.
QTableWidget * ToTable() override
Create Qt table widget representation.
void SetIncludedInAnalysis(bool included)
Set analysis inclusion status.
Elemental_Profile CreateCorrectedProfile(bool exclude_elements, bool apply_corrections, const vector< double > &reference_om_size, const MultipleLinearRegressionSet *regression_models=nullptr, const map< string, element_information > *elementinfo=nullptr) const
Create corrected profile with filtering and corrections.
bool AppendElement(const string &name, double val=0.0)
Add new element to profile.
double GetValue(const string &name) const
Get element concentration by name.
vector< string > SelectTopElements(int n, bool ascending=true) const
Select top N elements by concentration.
Elemental_Profile()
Default constructor - creates empty profile.
string ToString() const override
Convert profile to string representation.
bool writetofile(QFile *file) override
Write profile to file.
bool ReadFromJsonObject(const QJsonObject &json) override
Deserialize from JSON object.
QJsonObject toJsonObject() const override
Serialize to JSON object.
bool IsIncludedInAnalysis() const
Check if profile is included in analysis.
bool SetValue(const string &name, double val)
Set concentration value for existing element.
bool Read(const QStringList &string_list) override
Read profile from string list.
bool Contains(const string &name) const
Check if element exists in profile.
Abstract base class providing common serialization and visualization interface.
double lowlimit
Lower threshold for value highlighting (when enabled)
Interface & operator=(const Interface &intf)
Assignment operator.
QString XAxisLabel() const
Get the X-axis label.
bool SetXAxisLabel(const QString &label)
Set the X-axis label.
QString YAxisLabel() const
Get the Y-axis label.
bool highlightoutsideoflimit
Flag indicating whether to highlight values outside defined limits.
bool SetYAxisLabel(const QString &label)
Set the Y-axis label.
double highlimit
Upper threshold for value highlighting (when enabled)
Elemental concentration profile for sediment source fingerprinting.