SedSat3 1.1.6
Sediment Source Apportionment Tool - Advanced statistical methods for environmental pollution research
Loading...
Searching...
No Matches
conductor.cpp
Go to the documentation of this file.
1#include "conductor.h"
2#include "ProgressWindow.h"
3#include "results.h"
4#include "contribution.h"
5#include "resultitem.h"
6#include "testmcmc.h"
7#include "rangeset.h"
8#include <QMessageBox>
9
10#include "mainwindow.h"
11
13 : data(nullptr),
14 mainwindow(mainwindow)
15{
16}
17
18bool Conductor::Execute(const string &command, map<string,string> arguments)
19{
20 results.clear();
22 return false;
23
24 if (command == "GA")
25 {
26 ExecuteGA(arguments);
27 }
28 if (command == "GA (fixed elemental contribution)")
29 {
30 ExecuteGA_FixedProfile(arguments);
31 }
32 if (command == "GA (disregarding targets)")
33 {
34 ExecuteGA_NoTargets(arguments);
35 }
36 if (command == "Levenberg-Marquardt")
37 {
38 ExecuteLevenbergMarquardt(arguments);
39 }
40 if (command == "Levenberg-Marquardt-Batch")
41 {
43
44 }
45 if (command == "OM-Size Correct")
46 {
47 ExecuteOMSizeCorrect(arguments);
48 }
49 if (command == "MLR")
50 {
51 ExecuteMLR(arguments);
52 }
53 if (command == "CovMat")
54 {
55 ExecuteCovarianceMatrix(arguments);
56
57 }
58 if (command == "CorMat")
59 {
60 ExecuteCorrelationMatrix(arguments);
61 }
62 if (command == "DFA")
63 {
64 ExecuteDFA(arguments);
65 }
66
67 if (command == "DFAOnevsRest")
68 {
69 ExecuteDFAOnevsRest(arguments);
70
71 }
72 if (command == "DFAM")
73 {
74 ExecuteDFAM(arguments);
75
76 }
77 if (command == "SDFA")
78 {
79 ExecuteSDFA(arguments);
80
81 }
82
83 if (command == "SDFAM")
84 {
85 ExecuteSDFAM(arguments);
86 }
87
88 if (command == "SDFAOnevsRest")
89 {
90 ExecuteSDFAOnevsRest(arguments);
91
92 }
93
94 if (command == "KS")
95 {
96 ExecuteKolmogorovSmirnov(arguments);
97 }
98 if (command == "KS-individual")
99 {
101 }
102 if (command == "CMB Bayesian")
103 {
104 ExecuteCMBBayesian(arguments);
105 }
106 if (command == "CMB Bayesian-Batch")
107 {
108 ExecuteCMBBayesianBatch(arguments);
109 }
110 if (command == "Test CMB Bayesian")
111 {
112 ExecuteTestCMBBayesian(arguments);
113
114
115 }
116
117 if (command == "DF")
118 {
120
121 }
122
123 if (command == "Bracketing Analysis")
124 {
125 ExecuteBracketingAnalysis(arguments);
126
127 }
128 if (command == "Bracketing Analysis Batch")
129 {
131
132 }
133 if (command == "BoxCox")
134 {
135 return ExecuteBoxCox(arguments);
136 }
137
138 if (command == "Outlier")
139 {
140 return ExecuteOutlierAnalysis(arguments);
141 }
142
143 if (command == "EDP")
144 {
145 return ExecuteEDP(arguments);
146 }
147
148 if (command == "EDPM")
149 {
150 return ExecuteEDPM(arguments);
151 }
152 if (command == "ANOVA")
153 {
154 return ExecuteANOVA(arguments);
155 }
156
157 if (command == "Error_Analysis")
158 {
159 return ExecuteErrorAnalysis(arguments);
160 }
161
162 if (command == "Source_Verify")
163 {
164 return ExecuteSourceVerify(arguments);
165 }
166
167 if (command == "AutoSelect")
168 {
169 return ExecuteAutoSelect(arguments);
170 }
171 Data()->AddtoToolsUsed(command);
172 return true;
173}
174
176{
177 if (_data==nullptr)
178 _data = Data();
179 vector<string> NegativeCheckResults =_data->NegativeValueCheck();
180
181 if (NegativeCheckResults.size()>0)
182 {
183 QString message;
184 for (unsigned int i=0; i<NegativeCheckResults.size(); i++)
185 {
186 message += QString::fromStdString(NegativeCheckResults[i]+"\n");
187 }
188 QMessageBox::warning(mainwindow, "SedSAT3",message, QMessageBox::Ok);
189 return false;
190 }
191 return true;
192
193}
194
195bool Conductor::CheckNegativeElements(map<string,vector<string>> negative_elements)
196{
197 QString message;
198 for (map<string,vector<string>>::iterator it = negative_elements.begin(); it!=negative_elements.end(); it++)
199 {
200 if (it->second.size()>0)
201 { message += "For target sample '" + QString::fromStdString(it->first) + ":\n";
202 for (unsigned int i=0; i<it->second.size(); i++)
203 {
204 message += QString::fromStdString("\t" + it->second[i]) + "\n";
205 }
206 }
207
208 }
209
210 if (message!="")
211 { QMessageBox::warning(mainwindow, "SedSAT3",message, QMessageBox::Ok);
212 return false;
213 }
214
215}
216
217bool Conductor::ExecuteGA(const std::map<std::string, std::string>& arguments)
218{
220
221 bool organic_size_correction;
222 if (arguments.at("Apply size and organic matter correction") == "true")
223 {
224 organic_size_correction = true;
225 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
226 {
227 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
228 return false;
229 }
230 }
231 else
232 {
233 organic_size_correction = false;
234 }
235
236 SourceSinkData corrected_data = Data()->CreateCorrectedDataset(
237 arguments.at("Sample"),
238 organic_size_correction,
239 Data()->GetElementInformation()
240 );
241
242 rtw->show();
243 corrected_data.InitializeParametersAndObservations(arguments.at("Sample"));
244
245 if (!CheckNegativeElements(&corrected_data))
246 return false;
247
248 GA = std::make_unique<CGA<SourceSinkData>>(&corrected_data);
249 GA->filenames.pathname = workingfolder.toStdString() + "/";
250 GA->SetRunTimeWindow(rtw);
251 GA->SetProperties(arguments);
252 GA->InitiatePopulation();
253 GA->optimize();
254
255 results.SetName("GA " + arguments.at("Sample"));
256
257 ResultItem result_contribution = GA->Model_out.GetContribution();
258 result_contribution.SetShowTable(true);
259 result_contribution.SetType(result_type::contribution);
260 result_contribution.SetShowGraph(true);
261 results.Append(result_contribution);
262
263 ResultItem result_modeled_vs_measured = GA->Model_out.GetObservedvsModeledElementalProfile();
264 result_modeled_vs_measured.SetShowGraph(true);
265 result_modeled_vs_measured.SetShowTable(true);
266 results.Append(result_modeled_vs_measured);
267
268 ResultItem result_modeled_vs_measured_isotope = GA->Model_out.GetObservedvsModeledElementalProfile_Isotope();
269 result_modeled_vs_measured_isotope.SetShowGraph(true);
270 result_modeled_vs_measured_isotope.SetShowTable(true);
271 results.Append(result_modeled_vs_measured_isotope);
272
273 ResultItem result_calculated_means = GA->Model_out.GetCalculatedElementMeans();
274 result_calculated_means.SetShowTable(true);
275 result_calculated_means.SetShowGraph(false);
276 results.Append(result_calculated_means);
277
278 ResultItem result_estimated_means = GA->Model_out.GetEstimatedElementMean();
279 result_estimated_means.SetShowTable(true);
280 result_estimated_means.SetShowGraph(false);
281 results.Append(result_estimated_means);
282
283 ResultItem result_calculated_mu = GA->Model_out.GetCalculatedElementMu();
284 result_calculated_mu.SetShowTable(true);
285 result_calculated_mu.SetShowGraph(false);
286 results.Append(result_calculated_mu);
287
288 ResultItem result_estimated_mu = GA->Model_out.GetEstimatedElementMu();
289 result_estimated_mu.SetShowTable(true);
290 result_estimated_mu.SetShowGraph(false);
291 results.Append(result_estimated_mu);
292
293 ResultItem result_calculated_sigma = GA->Model_out.GetCalculatedElementSigma();
294 result_calculated_sigma.SetShowTable(true);
295 result_calculated_sigma.SetShowGraph(false);
296 results.Append(result_calculated_sigma);
297
298 ResultItem result_estimated_sigma = GA->Model_out.GetEstimatedElementSigma();
299 result_estimated_sigma.SetShowTable(true);
300 result_estimated_sigma.SetShowGraph(false);
301 results.Append(result_estimated_sigma);
302
303 return true;
304}
305
306
307bool Conductor::ExecuteGA_FixedProfile(const std::map<std::string, std::string>& arguments)
308{
310 rtw->SetTitle("Fitness", 0);
311 rtw->SetYAxisTitle("Fitness", 0);
312
313 bool organic_size_correction;
314 if (arguments.at("Apply size and organic matter correction") == "true")
315 {
316 organic_size_correction = true;
317 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
318 {
319 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
320 return false;
321 }
322 }
323 else
324 {
325 organic_size_correction = false;
326 }
327
328 SourceSinkData corrected_data = Data()->CreateCorrectedDataset(
329 arguments.at("Sample"),
330 organic_size_correction,
331 Data()->GetElementInformation()
332 );
333
334 if (!CheckNegativeElements(&corrected_data))
335 return false;
336
337 rtw->show();
339 arguments.at("Sample"),
341 );
343
344 GA = std::make_unique<CGA<SourceSinkData>>(&corrected_data);
345 GA->filenames.pathname = workingfolder.toStdString() + "/";
346 GA->SetRunTimeWindow(rtw);
347 GA->SetProperties(arguments);
348 GA->InitiatePopulation();
349 GA->optimize();
350
351 results.SetName("GA (fixed profile) " + arguments.at("Sample"));
352
353 ResultItem result_contribution = GA->Model_out.GetContribution();
354 results.Append(result_contribution);
355
356 ResultItem result_modeled_vs_measured = GA->Model_out.GetObservedvsModeledElementalProfile(parameter_mode::direct);
357 results.Append(result_modeled_vs_measured);
358
359 ResultItem result_modeled_vs_measured_isotope = GA->Model_out.GetObservedvsModeledElementalProfile_Isotope(parameter_mode::direct);
360 results.Append(result_modeled_vs_measured_isotope);
361
362 return true;
363}
364
365bool Conductor::ExecuteGA_NoTargets(const std::map<std::string, std::string>& arguments)
366{
368 rtw->show();
369
371 arguments.at("Sample"),
373 );
375
376 GA = std::make_unique<CGA<SourceSinkData>>(Data());
377 GA->filenames.pathname = workingfolder.toStdString() + "/";
378 GA->SetRunTimeWindow(rtw);
379 GA->SetProperties(arguments);
380 GA->InitiatePopulation();
381 GA->optimize();
382
383 results.SetName("GA (no targets) " + arguments.at("Sample"));
384
385 ResultItem result_calculated_means = GA->Model_out.GetCalculatedElementMeans();
386 results.Append(result_calculated_means);
387
388 ResultItem result_estimated_means = GA->Model_out.GetEstimatedElementMean();
389 results.Append(result_estimated_means);
390
391 ResultItem result_calculated_stds = GA->Model_out.GetCalculatedElementSigma();
392 results.Append(result_calculated_stds);
393
394 ResultItem result_estimated_stds = GA->Model_out.GetEstimatedElementSigma();
395 results.Append(result_estimated_stds);
396
397 return true;
398}
399
400bool Conductor::ExecuteLevenbergMarquardt(const std::map<std::string, std::string>& arguments)
401{
403
404 bool organic_size_correction;
405 if (arguments.at("Apply size and organic matter correction") == "true")
406 {
407 organic_size_correction = true;
408 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
409 {
410 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
411 return false;
412 }
413 }
414 else
415 {
416 organic_size_correction = false;
417 }
418
419 rtw->show();
420
421 SourceSinkData corrected_data = Data()->CreateCorrectedDataset(
422 arguments.at("Sample"),
423 organic_size_correction,
424 Data()->GetElementInformation()
425 );
426
427 if (!CheckNegativeElements(&corrected_data))
428 return false;
429
430 corrected_data.InitializeParametersAndObservations(arguments.at("Sample"));
431 corrected_data.SetProgressWindow(rtw);
432
433 if (arguments.at("Softmax transformation") == "true")
434 {
436 }
437 else
438 {
440 }
441
442 results.SetName("LM " + arguments.at("Sample"));
443
444 ResultItem result_contribution = corrected_data.GetContribution();
445 result_contribution.SetShowTable(true);
446 results.Append(result_contribution);
447
448 ResultItem result_modeled = corrected_data.GetPredictedElementalProfile(parameter_mode::direct);
449 result_modeled.SetShowTable(true);
450 results.Append(result_modeled);
451
452 ResultItem result_modeled_vs_measured = corrected_data.GetObservedvsModeledElementalProfile();
453 result_modeled_vs_measured.SetShowTable(true);
454 results.Append(result_modeled_vs_measured);
455
456 ResultItem result_modeled_vs_measured_isotope = corrected_data.GetObservedvsModeledElementalProfile_Isotope(parameter_mode::direct);
457 result_modeled_vs_measured_isotope.SetShowTable(true);
458 results.Append(result_modeled_vs_measured_isotope);
459
460 return true;
461}
462
463bool Conductor::ExecuteLevenbergMarquardtBatch(const std::map<std::string, std::string>& arguments)
464{
466
467 bool organic_size_correction;
468 if (arguments.at("Apply size and organic matter correction") == "true")
469 {
470 organic_size_correction = true;
471 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
472 {
473 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
474 return false;
475 }
476 }
477 else
478 {
479 organic_size_correction = false;
480 }
481
482 rtw->show();
483
484 Data()->SetProgressWindow(rtw);
485
486 CMBTimeSeriesSet* contributions;
487 std::map<std::string, std::vector<std::string>> negative_elements;
488
489 if (arguments.at("Softmax transformation") == "true")
490 {
491 contributions = new CMBTimeSeriesSet(Data()->LM_Batch(
493 organic_size_correction,
494 negative_elements
495 ));
496 }
497 else
498 {
499 contributions = new CMBTimeSeriesSet(Data()->LM_Batch(
501 organic_size_correction,
502 negative_elements
503 ));
504 }
505
506 if (negative_elements.size() > 0)
507 {
508 CheckNegativeElements(negative_elements);
509 }
510
511 results.SetName("LM-Batch");
512
513 contributions->GetOptions().X_suffix = "";
514 contributions->GetOptions().Y_suffix = "";
515 contributions->SetOption(options_key::single_column_x, true);
516
517 ResultItem contributions_result_item;
518 contributions_result_item.SetName("Levenberg-Marquardt-Batch");
519 contributions_result_item.SetResult(contributions);
520 contributions_result_item.SetType(result_type::stacked_bar_chart);
521 contributions_result_item.SetShowAsString(true);
522 contributions_result_item.SetShowTable(true);
523 contributions_result_item.SetShowGraph(true);
524 contributions_result_item.SetYLimit(_range::high, 1);
525 contributions_result_item.SetXAxisMode(xaxis_mode::counter);
526 contributions_result_item.setYAxisTitle("Contribution");
527 contributions_result_item.setXAxisTitle("Sample");
528 contributions_result_item.SetYLimit(_range::low, 0);
529
530 results.Append(contributions_result_item);
531
532 return true;
533}
534
535bool Conductor::ExecuteOMSizeCorrect(const std::map<std::string, std::string>& arguments)
536{
537 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
538 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
539
540 Data()->SetSelectedTargetSample(arguments.at("Sample"));
541
543 exclude_samples,
544 exclude_elements,
545 true,
546 arguments.at("Sample")
547 );
548
549 std::vector<ResultItem> result_items = transformed_data.GetSourceProfiles();
550
551 results.SetName("Corrected Elemental Profiles for Target" + arguments.at("Sample"));
552
553 for (size_t i = 0; i < result_items.size(); i++)
554 {
555 results.Append(result_items[i]);
556 }
557
558 return true;
559}
560
561bool Conductor::ExecuteMLR(const std::map<std::string, std::string>& arguments)
562{
563 if (arguments.at("Organic Matter constituent") == "" &&
564 arguments.at("Particle Size constituent") == "")
565 {
566 QMessageBox::information(
568 "Exclude Elements",
569 "At least one of Organic Matter constituent and Particle Size constituent must be selected",
570 QMessageBox::Ok
571 );
572 return false;
573 }
574
575 results.SetName("MLR_vs_OM&Size ");
576
577 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
578
580 exclude_samples,
581 false,
582 false
583 );
584
585 double p_value_threshold = QString::fromStdString(arguments.at("P-value threshold")).toDouble();
586
587 if (arguments.at("Equation") == "Linear")
588 {
589 transformed_data.PerformRegressionVsOMAndSize(
590 arguments.at("Organic Matter constituent"),
591 arguments.at("Particle Size constituent"),
593 p_value_threshold
594 );
595 }
596 else
597 {
598 transformed_data.PerformRegressionVsOMAndSize(
599 arguments.at("Organic Matter constituent"),
600 arguments.at("Particle Size constituent"),
602 p_value_threshold
603 );
604 }
605
607 arguments.at("Organic Matter constituent"),
608 arguments.at("Particle Size constituent")
609 );
610
611 for (std::map<std::string, Elemental_Profile_Set>::iterator it = Data()->begin();
612 it != Data()->end();
613 ++it)
614 {
615 if (it->first != Data()->GetTargetGroup())
616 {
617 it->second.SetRegressionModels(transformed_data[it->first].GetRegressionModels());
618 }
619 }
620
621 std::vector<ResultItem> regression_results = transformed_data.GetMLRResults();
622
623 for (size_t i = 0; i < regression_results.size(); i++)
624 {
625 results.Append(regression_results[i]);
626 }
627
628 return true;
629}
630
631bool Conductor::ExecuteCovarianceMatrix(const std::map<std::string, std::string>& arguments)
632{
633 results.SetName("Covariance Matrix for " + arguments.at("Source/Target group"));
634
635 ResultItem covariance_matrix_item;
636 covariance_matrix_item.SetName("Covariance Matrix for " + arguments.at("Source/Target group"));
637 covariance_matrix_item.SetShowTable(true);
638 covariance_matrix_item.SetType(result_type::matrix);
639 covariance_matrix_item.SetShowGraph(false);
640
641 CMBMatrix* covariance_matrix = new CMBMatrix(
642 Data()->at(arguments.at("Source/Target group")).CalculateCovarianceMatrix()
643 );
644
645 covariance_matrix_item.SetResult(covariance_matrix);
646 results.Append(covariance_matrix_item);
647
648 return true;
649}
650
651
652bool Conductor::ExecuteCorrelationMatrix(const std::map<std::string, std::string>& arguments)
653{
654 results.SetName("Correlation Matrix for " + arguments.at("Source/Target group"));
655
656 ResultItem correlation_matrix_item;
657 correlation_matrix_item.SetName("Correlation Matrix");
658 correlation_matrix_item.SetShowTable(true);
659 correlation_matrix_item.setTableTitle("Correlation Matrix for source group '" +
660 arguments.at("Source/Target group") + "'");
661 correlation_matrix_item.SetType(result_type::matrix);
662 correlation_matrix_item.SetShowGraph(false);
663
664 double threshold = QString::fromStdString(arguments.at("Threshold")).toDouble();
665 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
666 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
667
669 exclude_samples,
670 exclude_elements,
671 false
672 );
673
674 if (arguments.at("OM and Size Correct based on target sample") != "")
675 {
676 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
677 {
678 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
679 return false;
680 }
681 transformed_data = transformed_data.CreateCorrectedDataset(
682 arguments.at("OM and Size Correct based on target sample"),
683 true,
684 Data()->GetElementInformation()
685 );
686 }
687
688 CMBMatrix* correlation_matrix = new CMBMatrix(
689 transformed_data.at(arguments.at("Source/Target group")).CalculateCorrelationMatrix()
690 );
691
692 correlation_matrix->SetLimit(_range::high, threshold);
693 correlation_matrix->SetLimit(_range::low, -threshold);
694
695 correlation_matrix_item.SetResult(correlation_matrix);
696 results.Append(correlation_matrix_item);
697
698 return true;
699}
700
701bool Conductor::ExecuteDFA(const std::map<std::string, std::string>& arguments)
702{
703 if (arguments.at("Source/Target group I") == arguments.at("Source/Target group II"))
704 {
705 QMessageBox::warning(mainwindow, "SedSAT3", "The selected sources must be different", QMessageBox::Ok);
706 return false;
707 }
708
710 rtw->show();
711
712 results.SetName("DFA between " + arguments.at("Source/Target group I") +
713 "&" + arguments.at("Source/Target group II"));
714
715 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
716 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
717
718 SourceSinkData transformed_data = *Data();
719
720 if (arguments.at("OM and Size Correct based on target sample") != "")
721 {
722 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
723 {
724 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
725 return false;
726 }
727 transformed_data = transformed_data.CreateCorrectedDataset(
728 arguments.at("OM and Size Correct based on target sample"),
729 true,
730 Data()->GetElementInformation()
731 );
732 }
733
734 transformed_data = transformed_data.CreateCorrectedAndFilteredDataset(
735 exclude_samples,
736 exclude_elements,
737 false
738 );
739
740 transformed_data.SetProgressWindow(rtw);
741
742 if (arguments.at("Box-cox transformation") == "true")
743 {
744 transformed_data = transformed_data.BoxCoxTransformed(true);
745 }
746
747 DFA_result dfa_result = transformed_data.DiscriminantFunctionAnalysis(
748 arguments.at("Source/Target group I"),
749 arguments.at("Source/Target group II")
750 );
751
752 if (dfa_result.eigen_vectors.size() == 0)
753 {
754 QMessageBox::warning(mainwindow, "SedSAT3", "Singular matrix in within group scatter matrix!\n", QMessageBox::Ok);
755 return false;
756 }
757
758 // Chi-squared P-Value result
759 CMBVector* p_value = new CMBVector(dfa_result.p_values);
760 ResultItem dfa_p_value;
761 dfa_p_value.SetName("Chi-squared P-Value");
762 dfa_p_value.SetType(result_type::vector);
763 dfa_p_value.SetShowTable(true);
764 dfa_p_value.SetShowGraph(false);
765 dfa_p_value.SetResult(p_value);
766 results.Append(dfa_p_value);
767
768 // F-test P-Value result
769 CMBVector* f_test_p_value = new CMBVector(dfa_result.F_test_P_value);
770 ResultItem dfa_f_test_p_value;
771 dfa_f_test_p_value.SetName("F-test P-Value");
772 dfa_f_test_p_value.SetType(result_type::vector);
773 dfa_f_test_p_value.SetShowTable(true);
774 dfa_f_test_p_value.SetShowGraph(false);
775 dfa_f_test_p_value.SetResult(f_test_p_value);
776 results.Append(dfa_f_test_p_value);
777
778 // Projected Elemental Profiles result
779 ResultItem dfa_projected;
780 dfa_projected.SetName("Projected Elemental Profiles");
782 dfa_projected.SetShowTable(true);
783 dfa_projected.SetShowGraph(true);
784 dfa_projected.SetYAxisMode(yaxis_mode::normal);
785 CMBVectorSet* projected = new CMBVectorSet(dfa_result.projected);
786 dfa_projected.SetResult(projected);
787 results.Append(dfa_projected);
788
789 // Eigen vector result
790 ResultItem dfa_eigen_vector;
791 dfa_eigen_vector.SetName("Eigen vector");
792 dfa_eigen_vector.SetType(result_type::vector);
793 dfa_eigen_vector.SetShowTable(true);
794 dfa_eigen_vector.SetShowGraph(true);
795 dfa_eigen_vector.SetYAxisMode(yaxis_mode::normal);
796 CMBVector* eigen_vector = new CMBVector(dfa_result.eigen_vectors.begin()->second);
797 dfa_eigen_vector.SetResult(eigen_vector);
798 results.Append(dfa_eigen_vector);
799
800 rtw->SetProgress(1);
801
802 return true;
803}
804
805bool Conductor::ExecuteDFAOnevsRest(const std::map<std::string, std::string>& arguments)
806{
808 rtw->show();
809
810 results.SetName("DFA between " + arguments.at("Source group") + "& the rest");
811
812 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
813 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
814
815 SourceSinkData transformed_data = *Data();
816
817 if (arguments.at("OM and Size Correct based on target sample") != "")
818 {
819 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
820 {
821 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
822 return false;
823 }
824 transformed_data = transformed_data.CreateCorrectedDataset(
825 arguments.at("OM and Size Correct based on target sample"),
826 true,
827 Data()->GetElementInformation()
828 );
829 }
830
831 transformed_data = transformed_data.CreateCorrectedAndFilteredDataset(
832 exclude_samples,
833 exclude_elements,
834 false
835 );
836
837 transformed_data.SetProgressWindow(rtw);
838
839 if (arguments.at("Box-cox transformation") == "true")
840 {
841 transformed_data = transformed_data.BoxCoxTransformed(true);
842 }
843
844 DFA_result dfa_result = transformed_data.DiscriminantFunctionAnalysis(
845 arguments.at("Source group")
846 );
847
848 if (dfa_result.eigen_vectors.size() == 0)
849 {
850 QMessageBox::warning(mainwindow, "SedSAT3", "Singular matrix in within group scatter matrix!\n", QMessageBox::Ok);
851 return false;
852 }
853
854 // Chi-squared P-Value result
855 CMBVector* p_value = new CMBVector(dfa_result.p_values);
856 ResultItem dfa_p_value;
857 dfa_p_value.SetName("Chi-squared P-Value");
858 dfa_p_value.SetType(result_type::vector);
859 dfa_p_value.SetShowTable(true);
860 dfa_p_value.SetShowGraph(false);
861 dfa_p_value.SetResult(p_value);
862 results.Append(dfa_p_value);
863
864 // F-test P-Value result
865 CMBVector* f_test_p_value = new CMBVector(dfa_result.F_test_P_value);
866 ResultItem dfa_f_test_p_value;
867 dfa_f_test_p_value.SetName("F-test P-Value");
868 dfa_f_test_p_value.SetType(result_type::vector);
869 dfa_f_test_p_value.SetShowTable(true);
870 dfa_f_test_p_value.SetShowGraph(false);
871 dfa_f_test_p_value.SetResult(f_test_p_value);
872 results.Append(dfa_f_test_p_value);
873
874 // Projected Elemental Profiles result
875 ResultItem dfa_projected;
876 dfa_projected.SetName("Projected Elemental Profiles");
878 dfa_projected.SetShowTable(true);
879 dfa_projected.SetShowGraph(true);
880 dfa_projected.SetYAxisMode(yaxis_mode::normal);
881 CMBVectorSet* projected = new CMBVectorSet(dfa_result.projected);
882 dfa_projected.SetResult(projected);
883 results.Append(dfa_projected);
884
885 // Eigen vector result
886 ResultItem dfa_eigen_vector;
887 dfa_eigen_vector.SetName("Eigen vector");
888 dfa_eigen_vector.SetType(result_type::vector);
889 dfa_eigen_vector.SetShowTable(true);
890 dfa_eigen_vector.SetShowGraph(true);
891 dfa_eigen_vector.SetYAxisMode(yaxis_mode::normal);
892 CMBVector* eigen_vector = new CMBVector(dfa_result.eigen_vectors.begin()->second);
893 dfa_eigen_vector.SetResult(eigen_vector);
894 results.Append(dfa_eigen_vector);
895
896 rtw->SetProgress(1);
897
898 return true;
899}
900
901bool Conductor::ExecuteDFAM(const std::map<std::string, std::string>& arguments)
902{
904 rtw->show();
905
906 results.SetName("Multi-way DFA analysis");
907
908 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
909 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
910
911 SourceSinkData transformed_data = *Data();
912
913 if (arguments.at("OM and Size Correct based on target sample") != "")
914 {
915 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
916 {
917 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
918 return false;
919 }
920 transformed_data = transformed_data.CreateCorrectedDataset(
921 arguments.at("OM and Size Correct based on target sample"),
922 true,
923 Data()->GetElementInformation()
924 );
925 }
926
927 transformed_data = transformed_data.CreateCorrectedAndFilteredDataset(
928 exclude_samples,
929 exclude_elements,
930 false
931 );
932
933 if (!CheckNegativeElements(&transformed_data))
934 return false;
935
936 transformed_data.SetProgressWindow(rtw);
937
938 if (arguments.at("Box-cox transformation") == "true")
939 {
940 transformed_data = transformed_data.BoxCoxTransformed(true);
941 }
942
943 DFA_result dfa_result = transformed_data.DiscriminantFunctionAnalysis();
944
945 if (dfa_result.eigen_vectors.size() == 0)
946 {
947 QMessageBox::warning(mainwindow, "SedSAT3", "Singular matrix in within group scatter matrix!\n", QMessageBox::Ok);
948 return false;
949 }
950
951 // Chi-squared P-Value result
952 CMBVector* p_value = new CMBVector(dfa_result.p_values);
953 ResultItem dfa_p_value;
954 dfa_p_value.SetName("Chi-squared P-Value");
955 dfa_p_value.SetType(result_type::vector);
956 dfa_p_value.SetShowTable(true);
957 dfa_p_value.SetShowGraph(false);
958 dfa_p_value.SetResult(p_value);
959 results.Append(dfa_p_value);
960
961 // F-test P-Value result
962 CMBVector* f_test_p_value = new CMBVector(dfa_result.F_test_P_value);
963 ResultItem dfa_f_test_p_value;
964 dfa_f_test_p_value.SetName("F-test P-Value");
965 dfa_f_test_p_value.SetType(result_type::vector);
966 dfa_f_test_p_value.SetShowTable(true);
967 dfa_f_test_p_value.SetShowGraph(false);
968 dfa_f_test_p_value.SetResult(f_test_p_value);
969 results.Append(dfa_f_test_p_value);
970
971 // Multiway Projected Elemental Profiles result
972 ResultItem dfa_projected;
973 dfa_projected.SetName("Multiway Projected Elemental Profiles");
975 dfa_projected.SetShowTable(true);
976 dfa_projected.SetShowGraph(true);
977 dfa_projected.SetYAxisMode(yaxis_mode::normal);
978 CMBVectorSetSet* projected = new CMBVectorSetSet(dfa_result.multi_projected);
979 dfa_projected.SetResult(projected);
980 results.Append(dfa_projected);
981
982 // Eigen vectors result (multiple vectors for multiway)
983 ResultItem dfa_eigen_vectors;
984 dfa_eigen_vectors.SetName("Eigen vector");
985 dfa_eigen_vectors.SetType(result_type::vectorset);
986 dfa_eigen_vectors.SetShowTable(true);
987 dfa_eigen_vectors.SetShowGraph(true);
988 dfa_eigen_vectors.SetYAxisMode(yaxis_mode::normal);
989 CMBVectorSet* eigen_vectors = new CMBVectorSet(dfa_result.eigen_vectors);
990 dfa_eigen_vectors.SetResult(eigen_vectors);
991 results.Append(dfa_eigen_vectors);
992
993 rtw->SetProgress(1);
994
995 return true;
996}
997
998bool Conductor::ExecuteSDFA(const std::map<std::string, std::string>& arguments)
999{
1000 if (arguments.at("Source/Target group I") == arguments.at("Source/Target group II"))
1001 {
1002 QMessageBox::warning(mainwindow, "SedSAT3", "The selected sources must be different", QMessageBox::Ok);
1003 return false;
1004 }
1005
1007 rtw->show();
1008
1009 results.SetName("Stepwise DFA between " + arguments.at("Source/Target group I") +
1010 "&" + arguments.at("Source/Target group II"));
1011
1012 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
1013 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
1014
1015 SourceSinkData transformed_data;
1016
1017 if (arguments.at("OM and Size Correct based on target sample") != "")
1018 {
1019 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
1020 {
1021 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
1022 return false;
1023 }
1024 transformed_data = Data()->CreateCorrectedDataset(
1025 arguments.at("OM and Size Correct based on target sample"),
1026 true,
1027 Data()->GetElementInformation()
1028 ).CreateCorrectedAndFilteredDataset(exclude_samples, exclude_elements, false);
1029 }
1030 else
1031 {
1032 transformed_data = Data()->CreateCorrectedAndFilteredDataset(
1033 exclude_samples,
1034 exclude_elements,
1035 false
1036 );
1037 }
1038
1039 if (!CheckNegativeElements(&transformed_data))
1040 return false;
1041
1042 if (arguments.at("Box-cox transformation") == "true")
1043 {
1044 transformed_data = transformed_data.BoxCoxTransformed(true);
1045 }
1046
1047 transformed_data.SetProgressWindow(rtw);
1048
1049 std::vector<CMBVector> sdfa_results = transformed_data.StepwiseDiscriminantFunctionAnalysis(
1050 arguments.at("Source/Target group I"),
1051 arguments.at("Source/Target group II")
1052 );
1053
1054 if (sdfa_results[0].size() == 0)
1055 {
1056 QMessageBox::warning(mainwindow, "SedSAT3", "Singular matrix in within group scatter matrix!\n", QMessageBox::Ok);
1057 return false;
1058 }
1059
1060 // Chi-squared P-Values result
1061 CMBVector* p_vector = new CMBVector(sdfa_results[0]);
1062 ResultItem sdfa_p_values;
1063 sdfa_p_values.SetName("Chi-squared P-Values");
1064 sdfa_p_values.SetType(result_type::vector);
1065 sdfa_p_values.SetShowTable(true);
1066 sdfa_p_values.SetAbsoluteValue(true);
1067 sdfa_p_values.SetYAxisMode(yaxis_mode::log);
1068 sdfa_p_values.SetYLimit(_range::high, 1);
1069 sdfa_p_values.SetResult(p_vector);
1070 results.Append(sdfa_p_values);
1071
1072 // Wilks' Lambda result
1073 CMBVector* wilks_lambda_vector = new CMBVector(sdfa_results[1]);
1074 ResultItem sdfa_wilks_lambda;
1075 sdfa_wilks_lambda.SetName("Wilks' Lambda");
1076 sdfa_wilks_lambda.SetType(result_type::vector);
1077 sdfa_wilks_lambda.SetShowTable(true);
1078 sdfa_wilks_lambda.SetAbsoluteValue(true);
1079 sdfa_wilks_lambda.SetYAxisMode(yaxis_mode::log);
1080 sdfa_wilks_lambda.SetYLimit(_range::high, 1);
1081 sdfa_wilks_lambda.SetResult(wilks_lambda_vector);
1082 results.Append(sdfa_wilks_lambda);
1083
1084 // F-test P-Value result
1085 CMBVector* f_test_p_value = new CMBVector(sdfa_results[2]);
1086 ResultItem sdfa_f_test_p_value;
1087 sdfa_f_test_p_value.SetName("F-test P-Value");
1088 sdfa_f_test_p_value.SetType(result_type::vector);
1089 sdfa_f_test_p_value.SetShowTable(true);
1090 sdfa_f_test_p_value.SetAbsoluteValue(true);
1091 sdfa_f_test_p_value.SetYAxisMode(yaxis_mode::log);
1092 sdfa_f_test_p_value.SetYLimit(_range::high, 1);
1093 sdfa_f_test_p_value.SetResult(f_test_p_value);
1094 results.Append(sdfa_f_test_p_value);
1095
1096 return true;
1097}
1098
1099bool Conductor::ExecuteSDFAM(const std::map<std::string, std::string>& arguments)
1100{
1102 rtw->show();
1103
1104 results.SetName("Multiway Stepwise DFA");
1105
1106 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
1107 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
1108
1109 SourceSinkData transformed_data;
1110
1111 if (arguments.at("OM and Size Correct based on target sample") != "")
1112 {
1113 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
1114 {
1115 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
1116 return false;
1117 }
1118 transformed_data = Data()->CreateCorrectedDataset(
1119 arguments.at("OM and Size Correct based on target sample"),
1120 true,
1121 Data()->GetElementInformation()
1122 ).CreateCorrectedAndFilteredDataset(exclude_samples, exclude_elements, false);
1123 }
1124 else
1125 {
1126 transformed_data = Data()->CreateCorrectedAndFilteredDataset(
1127 exclude_samples,
1128 exclude_elements,
1129 false
1130 );
1131 }
1132
1133 if (!CheckNegativeElements(&transformed_data))
1134 return false;
1135
1136 if (arguments.at("Box-cox transformation") == "true")
1137 {
1138 transformed_data = transformed_data.BoxCoxTransformed(true);
1139 }
1140
1141 transformed_data.SetProgressWindow(rtw);
1142
1143 std::vector<CMBVector> sdfa_results = transformed_data.StepwiseDiscriminantFunctionAnalysis();
1144
1145 if (sdfa_results[0].size() == 0)
1146 {
1147 QMessageBox::warning(mainwindow, "SedSAT3", "Singular matrix in within group scatter matrix!\n", QMessageBox::Ok);
1148 return false;
1149 }
1150
1151 // Chi-squared P-Values result
1152 CMBVector* p_vector = new CMBVector(sdfa_results[0]);
1153 ResultItem sdfa_p_values;
1154 sdfa_p_values.SetName("Chi-squared P-Values");
1155 sdfa_p_values.SetType(result_type::vector);
1156 sdfa_p_values.SetShowTable(true);
1157 sdfa_p_values.SetAbsoluteValue(true);
1158 sdfa_p_values.SetYAxisMode(yaxis_mode::log);
1159 sdfa_p_values.SetYLimit(_range::high, 1);
1160 sdfa_p_values.SetResult(p_vector);
1161 results.Append(sdfa_p_values);
1162
1163 // Selected elements result
1164 ResultItem sdfa_selected;
1165 sdfa_selected.SetName("Elements to be Selected");
1166 sdfa_selected.SetType(result_type::vector);
1167 sdfa_selected.SetShowTable(true);
1168 sdfa_selected.SetAbsoluteValue(true);
1169 sdfa_selected.SetYAxisMode(yaxis_mode::log);
1170 sdfa_selected.SetYLimit(_range::high, 1);
1171
1172 CMBVector* p_vector_selected = new CMBVector();
1173 std::vector<std::string> selected = p_vector->ExtractUpToMinimum().Labels();
1174
1175 if (arguments.at("Modify the included elements based on the results") == "true")
1176 {
1178 }
1179
1180 for (size_t i = 0; i < selected.size(); i++)
1181 {
1182 p_vector_selected->append(selected[i], p_vector->valueAt(i));
1183 }
1184
1185 sdfa_selected.SetResult(p_vector_selected);
1186 results.Append(sdfa_selected);
1187
1188 // Wilks' Lambda result
1189 CMBVector* wilks_lambda_vector = new CMBVector(sdfa_results[1]);
1190 ResultItem sdfa_wilks_lambda;
1191 sdfa_wilks_lambda.SetName("Wilks' Lambda");
1192 sdfa_wilks_lambda.SetType(result_type::vector);
1193 sdfa_wilks_lambda.SetShowTable(true);
1194 sdfa_wilks_lambda.SetAbsoluteValue(true);
1195 sdfa_wilks_lambda.SetYAxisMode(yaxis_mode::log);
1196 sdfa_wilks_lambda.SetYLimit(_range::high, 1);
1197 sdfa_wilks_lambda.SetResult(wilks_lambda_vector);
1198 results.Append(sdfa_wilks_lambda);
1199
1200 // F-test P-Value result
1201 CMBVector* f_test_p_value = new CMBVector(sdfa_results[2]);
1202 ResultItem sdfa_f_test_p_value;
1203 sdfa_f_test_p_value.SetName("F-test P-Value");
1204 sdfa_f_test_p_value.SetType(result_type::vector);
1205 sdfa_f_test_p_value.SetShowTable(true);
1206 sdfa_f_test_p_value.SetAbsoluteValue(true);
1207 sdfa_f_test_p_value.SetYAxisMode(yaxis_mode::log);
1208 sdfa_f_test_p_value.SetYLimit(_range::high, 1);
1209 sdfa_f_test_p_value.SetResult(f_test_p_value);
1210 results.Append(sdfa_f_test_p_value);
1211
1212 return true;
1213}
1214
1215bool Conductor::ExecuteSDFAOnevsRest(const std::map<std::string, std::string>& arguments)
1216{
1218 rtw->show();
1219
1220 results.SetName("Stepwise DFA between " + arguments.at("Source group") + "& the rest");
1221
1222 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
1223 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
1224
1225 SourceSinkData transformed_data;
1226
1227 if (arguments.at("OM and Size Correct based on target sample") != "")
1228 {
1229 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
1230 {
1231 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
1232 return false;
1233 }
1234 transformed_data = Data()->CreateCorrectedDataset(
1235 arguments.at("OM and Size Correct based on target sample"),
1236 true,
1237 Data()->GetElementInformation()
1238 ).CreateCorrectedAndFilteredDataset(exclude_samples, exclude_elements, false);
1239 }
1240 else
1241 {
1242 transformed_data = Data()->CreateCorrectedAndFilteredDataset(
1243 exclude_samples,
1244 exclude_elements,
1245 false
1246 );
1247 }
1248
1249 if (!CheckNegativeElements(&transformed_data))
1250 return false;
1251
1252 if (arguments.at("Box-cox transformation") == "true")
1253 {
1254 transformed_data = transformed_data.BoxCoxTransformed(true);
1255 }
1256
1257 transformed_data.SetProgressWindow(rtw);
1258
1259 std::vector<CMBVector> sdfa_results = transformed_data.StepwiseDiscriminantFunctionAnalysis(
1260 arguments.at("Source group")
1261 );
1262
1263 if (sdfa_results[0].size() == 0)
1264 {
1265 QMessageBox::warning(mainwindow, "SedSAT3", "Singular matrix in within group scatter matrix!\n", QMessageBox::Ok);
1266 return false;
1267 }
1268
1269 // Chi-squared P-Values result
1270 CMBVector* p_vector = new CMBVector(sdfa_results[0]);
1271 ResultItem sdfa_p_values;
1272 sdfa_p_values.SetName("Chi-squared P-Values");
1273 sdfa_p_values.SetType(result_type::vector);
1274 sdfa_p_values.SetShowTable(true);
1275 sdfa_p_values.SetAbsoluteValue(true);
1276 sdfa_p_values.SetYAxisMode(yaxis_mode::log);
1277 sdfa_p_values.SetYLimit(_range::high, 1);
1278 sdfa_p_values.SetResult(p_vector);
1279 results.Append(sdfa_p_values);
1280
1281 // Wilks' Lambda result
1282 CMBVector* wilks_lambda_vector = new CMBVector(sdfa_results[1]);
1283 ResultItem sdfa_wilks_lambda;
1284 sdfa_wilks_lambda.SetName("Wilks' Lambda");
1285 sdfa_wilks_lambda.SetType(result_type::vector);
1286 sdfa_wilks_lambda.SetShowTable(true);
1287 sdfa_wilks_lambda.SetAbsoluteValue(true);
1288 sdfa_wilks_lambda.SetYAxisMode(yaxis_mode::log);
1289 sdfa_wilks_lambda.SetYLimit(_range::high, 1);
1290 sdfa_wilks_lambda.SetResult(wilks_lambda_vector);
1291 results.Append(sdfa_wilks_lambda);
1292
1293 // F-test P-Value result
1294 CMBVector* f_test_p_value = new CMBVector(sdfa_results[2]);
1295 ResultItem sdfa_f_test_p_value;
1296 sdfa_f_test_p_value.SetName("F-test P-Value");
1297 sdfa_f_test_p_value.SetType(result_type::vector);
1298 sdfa_f_test_p_value.SetShowTable(true);
1299 sdfa_f_test_p_value.SetAbsoluteValue(true);
1300 sdfa_f_test_p_value.SetYAxisMode(yaxis_mode::log);
1301 sdfa_f_test_p_value.SetYLimit(_range::high, 1);
1302 sdfa_f_test_p_value.SetResult(f_test_p_value);
1303 results.Append(sdfa_f_test_p_value);
1304
1305 return true;
1306}
1307
1308bool Conductor::ExecuteKolmogorovSmirnov(const std::map<std::string, std::string>& arguments)
1309{
1310 results.SetName("Kolmogorov–Smirnov statististics for " + arguments.at("Source/Target group"));
1311
1312 ResultItem ks_item;
1313 ks_item.SetName("Kolmogorov–Smirnov statististics for " + arguments.at("Source/Target group"));
1316
1317 distribution_type dist;
1318 if (arguments.at("Distribution") == "Normal")
1319 {
1321 }
1322 else if (arguments.at("Distribution") == "Lognormal")
1323 {
1325 }
1326
1327 CMBVector* ks_output = new CMBVector(
1328 Data()->at(arguments.at("Source/Target group")).CalculateKolmogorovSmirnovStatistics(dist)
1329 );
1330
1331 ks_item.SetShowTable(true);
1332 ks_item.SetResult(ks_output);
1333 results.Append(ks_item);
1334
1335 return true;
1336}
1337
1338bool Conductor::ExecuteKolmogorovSmirnovIndividual(const std::map<std::string, std::string>& arguments)
1339{
1340 results.SetName("Kolmogorov–Smirnov statististics for constituent " +
1341 arguments.at("Constituent") + " in group " +
1342 arguments.at("Source/Target group"));
1343
1344 ResultItem ks_item;
1345 ks_item.SetName("Kolmogorov–Smirnov statististics for constituent " +
1346 arguments.at("Constituent") + " in group " +
1347 arguments.at("Source/Target group"));
1349
1350 distribution_type dist;
1351 if (arguments.at("Distribution") == "Normal")
1352 {
1354 }
1355 else if (arguments.at("Distribution") == "Lognormal")
1356 {
1358 }
1359
1360 CMBTimeSeriesSet* ks_output = new CMBTimeSeriesSet(
1361 Data()->at(arguments.at("Source/Target group"))
1362 .GetElementDistribution(arguments.at("Constituent"))
1363 ->CreateCDFComparison(dist)
1364 );
1365
1366 ks_item.SetResult(ks_output);
1367 ks_item.SetShowTable(false);
1368 results.Append(ks_item);
1369
1370 return true;
1371}
1372
1373bool Conductor::ExecuteCMBBayesianBatch(const std::map<std::string, std::string>& arguments)
1374{
1375 if (arguments.at("Apply size and organic matter correction") == "true")
1376 {
1377 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
1378 {
1379 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
1380 return false;
1381 }
1382 }
1383
1384 // Initialize MCMC object
1385 MCMC = std::make_unique<CMCMC<SourceSinkData>>();
1386
1387 // Create progress window with 3 charts for monitoring (with batch mode enabled)
1388 ProgressWindow* rtw = new ProgressWindow(mainwindow, 3, true);
1389 rtw->SetTitle("Acceptance Rate", 0);
1390 rtw->SetTitle("Purturbation Factor", 1);
1391 rtw->SetTitle("Log posterior value", 2);
1392 rtw->SetYAxisTitle("Acceptance Rate", 0);
1393 rtw->SetYAxisTitle("Purturbation Factor", 1);
1394 rtw->SetYAxisTitle("Log posterior value", 2);
1395 rtw->show();
1396
1397 // Execute batch MCMC sampling
1398 CMBMatrix* contributions = new CMBMatrix(
1399 Data()->MCMC_Batch(
1400 arguments,
1401 MCMC.get(),
1402 rtw,
1403 workingfolder.toStdString()
1404 )
1405 );
1406
1407 results.SetName("CMB Bayesian-Batch");
1408
1409 // Create result item for contribution range matrix
1410 ResultItem contribution_matrix_item;
1411 contribution_matrix_item.SetName("Contribution Range Matrix");
1412 contribution_matrix_item.SetType(result_type::matrix);
1413 contribution_matrix_item.SetYAxisMode(yaxis_mode::normal);
1414 contribution_matrix_item.SetResult(contributions);
1415 contribution_matrix_item.SetShowTable(true);
1416 results.Append(contribution_matrix_item);
1417
1418 rtw->SetProgress(1);
1419
1420 return true;
1421}
1422
1423bool Conductor::ExecuteTestCMBBayesian(const std::map<std::string, std::string>& arguments)
1424{
1425 results.SetName("MCMC results for testing MCMC'");
1426
1427 // Create MCMC samples result item
1431 mcmc_samples.SetName("MCMC samples for testing MCMC'");
1432
1434
1435 // Initialize MCMC for testing with TestMCMC model
1436 CMCMC<TestMCMC>* mcmc_for_testing = new CMCMC<TestMCMC>();
1437 TestMCMC testing_model;
1438 mcmc_for_testing->Model = &testing_model;
1439
1440 // Create progress window with 3 charts
1442 rtw->SetTitle("Acceptance Rate", 0);
1443 rtw->SetTitle("Purturbation Factor", 1);
1444 rtw->SetTitle("Log posterior value", 2);
1445 rtw->SetYAxisTitle("Acceptance Rate", 0);
1446 rtw->SetYAxisTitle("Purturbation Factor", 1);
1447 rtw->SetYAxisTitle("Log posterior value", 2);
1448 rtw->show();
1449
1450 // Set up parameter bounds for test model
1451 std::vector<double> mins;
1452 std::vector<double> maxs;
1453 mins.push_back(0.1);
1454 mins.push_back(1);
1455 maxs.push_back(1.0);
1456 maxs.push_back(10);
1457
1458 testing_model.InitializeParametersObservations(mins, maxs);
1459
1460 // Configure MCMC parameters
1461 mcmc_for_testing->SetProperty("number_of_samples", arguments.at("Number of samples"));
1462 mcmc_for_testing->SetProperty("number_of_chains", arguments.at("Number of chains"));
1463 mcmc_for_testing->SetProperty("number_of_burnout_samples", arguments.at("Samples to be discarded (burnout)"));
1464
1465 mcmc_for_testing->initialize(samples, true);
1466
1467 // Determine output folder path
1468 std::string folder_path;
1469 if (!QString::fromStdString(arguments.at("samples_file_name")).contains("/"))
1470 {
1471 folder_path = workingfolder.toStdString() + "/";
1472 }
1473
1474 // Execute MCMC sampling
1475 mcmc_for_testing->step(
1476 QString::fromStdString(arguments.at("Number of chains")).toInt(),
1477 QString::fromStdString(arguments.at("Number of samples")).toInt(),
1478 folder_path + arguments.at("samples_file_name"),
1479 samples,
1480 rtw
1481 );
1482
1483 mcmc_samples.SetResult(samples);
1485
1486 // Generate posterior distributions from samples
1487 ResultItem distribution_result_item;
1488 CMBTimeSeriesSet* dists = new CMBTimeSeriesSet();
1489 *dists = samples->distribution(
1490 100,
1491 QString::fromStdString(arguments.at("Samples to be discarded (burnout)")).toInt()
1492 );
1493
1494 distribution_result_item.SetName("Posterior Distributions");
1495 distribution_result_item.SetShowAsString(false);
1496 distribution_result_item.SetType(result_type::distribution);
1497 distribution_result_item.SetResult(dists);
1498 results.Append(distribution_result_item);
1499
1500 // Clean up (TestMCMC uses raw pointer)
1501 delete mcmc_for_testing;
1502
1503 return true;
1504}
1505
1506bool Conductor::ExecuteDistributionFitting(const std::map<std::string, std::string>& arguments)
1507{
1508 results.SetName("Distribution fitting results for '" + arguments.at("Constituent") +
1509 "' in '" + arguments.at("Source/Target group"));
1510
1511 // Prepare result items for PDF and CDF
1512 ResultItem distribution_item;
1513 distribution_item.SetName("Fitted PDF for '" + arguments.at("Constituent") +
1514 "' in '" + arguments.at("Source/Target group"));
1515 distribution_item.SetShowAsString(false);
1517 distribution_item.SetYAxisMode(yaxis_mode::normal);
1518 distribution_item.setXAxisTitle("Value");
1519 distribution_item.setYAxisTitle("PDF");
1520
1521 ResultItem cumulative_distribution_item;
1522 cumulative_distribution_item.SetName("Fitted CDF for '" + arguments.at("Constituent") +
1523 "' in '" + arguments.at("Source/Target group"));
1524 cumulative_distribution_item.SetShowAsString(false);
1525 cumulative_distribution_item.SetType(result_type::timeseries_set_first_symbol);
1526 cumulative_distribution_item.SetYAxisMode(yaxis_mode::normal);
1527 cumulative_distribution_item.setXAxisTitle("Value");
1528 cumulative_distribution_item.setYAxisTitle("CDF");
1529
1530 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
1531
1532 SourceSinkData transformed_data;
1533
1534 if (arguments.at("OM and Size Correct based on target sample") != "")
1535 {
1536 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
1537 {
1538 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
1539 return false;
1540 }
1541 transformed_data = Data()->CreateCorrectedDataset(
1542 arguments.at("OM and Size Correct based on target sample"),
1543 true,
1544 Data()->GetElementInformation()
1545 ).CreateCorrectedAndFilteredDataset(exclude_samples, false, false);
1546 }
1547 else
1548 {
1549 transformed_data = Data()->CreateCorrectedAndFilteredDataset(exclude_samples, false, false);
1550 }
1551
1552 if (!CheckNegativeElements(&transformed_data))
1553 return false;
1554
1555 if (arguments.at("Box-cox transformation") == "true")
1556 {
1557 transformed_data = transformed_data.BoxCoxTransformed(true);
1558 }
1559
1560 // Fit normal distribution
1561 CMBTimeSeriesSet fitted_normal = transformed_data.at(arguments.at("Source/Target group"))
1562 .GetElementDistribution(arguments.at("Constituent"))
1564
1565 // Fit lognormal distribution (only if not Box-Cox transformed)
1566 CMBTimeSeriesSet fitted_lognormal;
1567 if (arguments.at("Box-cox transformation") != "true")
1568 {
1569 fitted_lognormal = transformed_data.at(arguments.at("Source/Target group"))
1570 .GetElementDistribution(arguments.at("Constituent"))
1572 }
1573
1574 // Create CDF comparisons for normal
1575 CMBTimeSeriesSet observed_fitted_normal_cdf = transformed_data.at(arguments.at("Source/Target group"))
1576 .GetElementDistribution(arguments.at("Constituent"))
1578
1579 // Create CDF comparisons for lognormal (only if not Box-Cox transformed)
1580 CMBTimeSeriesSet observed_fitted_lognormal_cdf;
1581 if (arguments.at("Box-cox transformation") != "true")
1582 {
1583 observed_fitted_lognormal_cdf = transformed_data.at(arguments.at("Source/Target group"))
1584 .GetElementDistribution(arguments.at("Constituent"))
1586 }
1587
1588 // Build PDF result
1590 pdf->append(fitted_normal["Observed"]);
1591 pdf->append(fitted_normal["Fitted"]);
1592 if (arguments.at("Box-cox transformation") != "true")
1593 {
1594 pdf->append(fitted_lognormal["Fitted"]);
1595 }
1596 pdf->setname(0, "Samples");
1597 pdf->setname(1, "Normal");
1598 if (arguments.at("Box-cox transformation") != "true")
1599 {
1600 pdf->setname(2, "Log-normal");
1601 }
1602
1603 // Build CDF result
1605 cdf->append(observed_fitted_normal_cdf["Observed"]);
1606 cdf->append(observed_fitted_normal_cdf["Fitted"]);
1607 if (arguments.at("Box-cox transformation") != "true")
1608 {
1609 cdf->append(observed_fitted_lognormal_cdf["Fitted"]);
1610 }
1611 cdf->setname(0, "Observed");
1612 cdf->setname(1, "Normal");
1613 if (arguments.at("Box-cox transformation") != "true")
1614 {
1615 cdf->setname(2, "Log-normal");
1616 }
1617
1618 distribution_item.SetResult(pdf);
1619 cumulative_distribution_item.SetResult(cdf);
1620
1621 results.Append(distribution_item);
1622 results.Append(cumulative_distribution_item);
1623
1624 return true;
1625}
1626
1627bool Conductor::ExecuteBracketingAnalysis(const std::map<std::string, std::string>& arguments)
1628{
1629 results.SetName("Bracketing analysis for sample '" + arguments.at("Sample") + "'");
1630
1631 ResultItem bracketing_result_item;
1632 bracketing_result_item.SetName("Bracketing results");
1633 bracketing_result_item.SetType(result_type::vector);
1634 bracketing_result_item.SetShowTable(true);
1635 bracketing_result_item.SetShowGraph(false);
1636
1637 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
1638 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
1639 bool correct_based_on_size_and_organic_matter = (arguments.at("Correct based on size and organic matter") == "true");
1640
1642 exclude_samples,
1643 exclude_elements,
1644 correct_based_on_size_and_organic_matter,
1645 arguments.at("Sample")
1646 );
1647
1648 if (!CheckNegativeElements(&transformed_data))
1649 return false;
1650
1651 CMBVector* bracketing_result = new CMBVector(
1652 transformed_data.BracketTest(arguments.at("Sample"), false)
1653 );
1654
1655 bracketing_result->SetBooleanValue(true);
1656 bracketing_result_item.SetResult(bracketing_result);
1657 results.Append(bracketing_result_item);
1658
1659 return true;
1660}
1661
1662bool Conductor::ExecuteBracketingAnalysisBatch(const std::map<std::string, std::string>& arguments)
1663{
1664 results.SetName("Bracketing analysis");
1665
1666 ResultItem bracketing_result_item;
1667 bracketing_result_item.SetName("Bracketing results");
1668 bracketing_result_item.SetType(result_type::matrix);
1669 bracketing_result_item.SetShowTable(true);
1670 bracketing_result_item.SetShowGraph(false);
1671 bracketing_result_item.SetShowAsString(false);
1672
1673 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
1674 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
1675 bool correct_based_on_size_and_organic_matter = (arguments.at("Correct based on size and organic matter") == "true");
1676
1678 return false;
1679
1680 if (correct_based_on_size_and_organic_matter)
1681 {
1682 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
1683 {
1684 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
1685 return false;
1686 }
1687 }
1688
1689 CMBMatrix* bracketing_result = new CMBMatrix(
1690 Data()->BracketTest(
1691 correct_based_on_size_and_organic_matter,
1692 exclude_elements,
1693 exclude_samples
1694 )
1695 );
1696
1697 bracketing_result->SetBooleanValue(true);
1698 bracketing_result_item.SetResult(bracketing_result);
1699 results.Append(bracketing_result_item);
1700
1701 return true;
1702}
1703
1704bool Conductor::ExecuteBoxCox(const std::map<std::string, std::string>& arguments)
1705{
1706 results.SetName("Box-Cox parameter for '" + arguments.at("Source/Target group") + "'");
1707
1708 ResultItem boxcox_result_item;
1709 boxcox_result_item.SetName("Box-Cox parameters");
1710 boxcox_result_item.SetType(result_type::vector);
1711 boxcox_result_item.SetShowTable(true);
1712 boxcox_result_item.SetShowGraph(true);
1713 boxcox_result_item.SetYAxisMode(yaxis_mode::normal);
1714
1715 CMBVector* boxcox_params = new CMBVector(
1716 Data()->at(arguments.at("Source/Target group")).CalculateBoxCoxParameters()
1717 );
1718
1719 boxcox_result_item.SetResult(boxcox_params);
1720 results.Append(boxcox_result_item);
1721
1722 return true;
1723}
1724
1725bool Conductor::ExecuteOutlierAnalysis(const std::map<std::string, std::string>& arguments)
1726{
1727 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
1728 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
1729
1731 exclude_samples,
1732 exclude_elements,
1733 false
1734 );
1735
1736 if (!CheckNegativeElements(&transformed_data))
1737 return false;
1738
1739 results.SetName("Outlier analysis for '" + arguments.at("Source/Target group") + "'");
1740
1741 ResultItem outlier_result_item;
1742 outlier_result_item.SetName("Outlier Analysis");
1743 outlier_result_item.SetType(result_type::matrix);
1744 outlier_result_item.SetShowAsString(false);
1745 outlier_result_item.SetShowTable(true);
1746 outlier_result_item.SetShowGraph(false);
1747
1748 double threshold = QString::fromStdString(arguments.at("Threshold")).toDouble();
1749
1750 CMBMatrix* outlier_matrix = new CMBMatrix(
1751 transformed_data.at(arguments.at("Source/Target group")).DetectOutliers(-threshold, threshold)
1752 );
1753
1754 outlier_matrix->SetLimit(_range::high, threshold);
1755 outlier_matrix->SetLimit(_range::low, -threshold);
1756
1757 outlier_result_item.SetResult(outlier_matrix);
1758 results.Append(outlier_result_item);
1759
1760 return true;
1761}
1762
1763bool Conductor::ExecuteEDP(const std::map<std::string, std::string>& arguments)
1764{
1765 results.SetName("Two-way element discriminant power between '" +
1766 arguments.at("Source/Target group I") + "' and '" +
1767 arguments.at("Source/Target group II") + "'");
1768
1769 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
1770
1771 SourceSinkData transformed_data;
1772
1773 if (arguments.at("OM and Size Correct based on target sample") != "")
1774 {
1775 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
1776 {
1777 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
1778 return false;
1779 }
1780 transformed_data = Data()->CreateCorrectedDataset(
1781 arguments.at("OM and Size Correct based on target sample"),
1782 true,
1783 Data()->GetElementInformation()
1784 ).CreateCorrectedAndFilteredDataset(exclude_samples, false, false);
1785 }
1786 else
1787 {
1788 transformed_data = Data()->CreateCorrectedAndFilteredDataset(exclude_samples, false, false);
1789 }
1790
1791 if (!CheckNegativeElements(&transformed_data))
1792 return false;
1793
1794 if (arguments.at("Box-cox transformation") == "true")
1795 {
1796 transformed_data = transformed_data.BoxCoxTransformed(true);
1797 }
1798
1799 // Discriminant difference to standard deviation ratio
1800 ResultItem edp_result_std;
1801 edp_result_std.SetName("Discreminant difference to standard deviation ratio");
1803 edp_result_std.SetShowAsString(false);
1804 edp_result_std.SetShowTable(true);
1805 edp_result_std.SetShowGraph(true);
1806
1807 Elemental_Profile* edp_profile_set = new Elemental_Profile(
1808 transformed_data.DifferentiationPower(
1809 arguments.at("Source/Target group I"),
1810 arguments.at("Source/Target group II"),
1811 false
1812 )
1813 );
1814
1815 edp_result_std.SetYAxisMode(yaxis_mode::normal);
1816 edp_result_std.setYAxisTitle("Discrimination power");
1817 edp_result_std.SetResult(edp_profile_set);
1818 edp_result_std.setXAxisTitle("Element");
1819 edp_result_std.setYAxisTitle("Standard deviation to mean ratio");
1820 results.Append(edp_result_std);
1821
1822 // Discriminant fraction
1823 ResultItem edp_result_percent;
1824 edp_result_percent.SetName("Discriminat fraction");
1826 edp_result_percent.SetShowAsString(false);
1827 edp_result_percent.setYAxisTitle("Percentage discriminated");
1828 edp_result_percent.SetShowTable(true);
1829 edp_result_percent.SetShowGraph(true);
1830
1831 Elemental_Profile* edp_profile_set_percent = new Elemental_Profile(
1832 transformed_data.DifferentiationPower_Percentage(
1833 arguments.at("Source/Target group I"),
1834 arguments.at("Source/Target group II")
1835 )
1836 );
1837
1838 edp_result_percent.SetYAxisMode(yaxis_mode::normal);
1839 edp_result_percent.SetYLimit(_range::high, 1);
1840 edp_result_percent.SetResult(edp_profile_set_percent);
1841 edp_result_percent.setXAxisTitle("Element");
1842 edp_result_percent.setYAxisTitle("Discriminant fraction");
1843 results.Append(edp_result_percent);
1844
1845 // Discriminant p-value
1846 ResultItem edp_result_p_value;
1847 edp_result_p_value.SetName("Discriminat p-value");
1849 edp_result_p_value.SetShowAsString(false);
1850 edp_result_p_value.setYAxisTitle("p-Value");
1851 edp_result_p_value.SetShowTable(true);
1852 edp_result_p_value.SetShowGraph(true);
1853
1854 Elemental_Profile* edp_profile_set_p_value = new Elemental_Profile(
1855 transformed_data.t_TestPValue(
1856 arguments.at("Source/Target group I"),
1857 arguments.at("Source/Target group II"),
1858 false
1859 )
1860 );
1861
1862 edp_result_p_value.SetYAxisMode(yaxis_mode::normal);
1863 edp_result_p_value.SetYLimit(_range::high, 1);
1864 edp_result_p_value.SetResult(edp_profile_set_p_value);
1865 edp_profile_set_p_value->SetLimit(_range::high, aquiutils::atof(arguments.at("P-value threshold")));
1866 edp_profile_set_p_value->SetLimit(_range::low, 0);
1867 edp_result_p_value.setXAxisTitle("Element");
1868 edp_result_p_value.setYAxisTitle("Discriminant fraction");
1869 results.Append(edp_result_p_value);
1870
1871 return true;
1872}
1873
1874bool Conductor::ExecuteEDPM(const std::map<std::string, std::string>& arguments)
1875{
1876 bool include_target = (arguments.at("Include target samples") == "true");
1877 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
1878
1879 SourceSinkData transformed_data;
1880
1881 if (arguments.at("OM and Size Correct based on target sample") != "")
1882 {
1883 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
1884 {
1885 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
1886 return false;
1887 }
1888 transformed_data = Data()->CreateCorrectedDataset(
1889 arguments.at("OM and Size Correct based on target sample"),
1890 true,
1891 Data()->GetElementInformation()
1892 ).CreateCorrectedAndFilteredDataset(exclude_samples, false, false);
1893 }
1894 else
1895 {
1896 transformed_data = Data()->CreateCorrectedAndFilteredDataset(exclude_samples, false, false);
1897 }
1898
1899 if (!CheckNegativeElements(&transformed_data))
1900 return false;
1901
1902 if (arguments.at("Box-cox transformation") == "true")
1903 {
1904 transformed_data = transformed_data.BoxCoxTransformed(true);
1905 }
1906
1907 results.SetName("Multi-way element discriminant power between '" +
1908 arguments.at("Source/Target group I") + "' and '" +
1909 arguments.at("Source/Target group II") + "'");
1910
1911 // Multi-way discriminant difference to standard deviation ratio
1912 ResultItem edp_result_std;
1913 edp_result_std.SetName("Multi-way discreminant difference to standard deviation ratio");
1915 edp_result_std.SetShowAsString(true);
1916 edp_result_std.SetShowTable(true);
1917 edp_result_std.SetShowGraph(true);
1918
1919 Elemental_Profile_Set* edp_profile_set = new Elemental_Profile_Set(
1920 transformed_data.DifferentiationPower(false, include_target)
1921 );
1922
1923 edp_result_std.SetYAxisMode(yaxis_mode::normal);
1924 edp_result_std.setYAxisTitle("Discrimination power");
1925 edp_result_std.SetResult(edp_profile_set);
1926 results.Append(edp_result_std);
1927
1928 // Multi-way discriminant fraction
1929 ResultItem edp_result_percent;
1930 edp_result_percent.SetName("Multi-way discriminat fraction");
1931 edp_result_percent.SetType(result_type::elemental_profile_set);
1932 edp_result_percent.SetShowAsString(true);
1933 edp_result_percent.setYAxisTitle("Percentage discriminated");
1934 edp_result_percent.SetShowTable(true);
1935 edp_result_percent.SetShowGraph(true);
1936
1937 Elemental_Profile_Set* edp_profile_set_percent = new Elemental_Profile_Set(
1938 transformed_data.DifferentiationPower_Percentage(include_target)
1939 );
1940
1941 edp_result_percent.SetYAxisMode(yaxis_mode::normal);
1942 edp_result_percent.SetYLimit(_range::high, 1);
1943 edp_result_percent.SetResult(edp_profile_set_percent);
1944 results.Append(edp_result_percent);
1945
1946 // Multi-way discriminant p-value
1947 ResultItem edp_p_value;
1948 edp_p_value.SetName("Multi-way discriminat p-value");
1950 edp_p_value.SetShowAsString(true);
1951 edp_p_value.setYAxisTitle("p-Value");
1952 edp_p_value.SetShowTable(true);
1953 edp_p_value.SetShowGraph(true);
1954
1955 Elemental_Profile_Set* edp_profile_set_p_value = new Elemental_Profile_Set(
1956 transformed_data.DifferentiationPower_P_value(include_target)
1957 );
1958
1959 edp_p_value.SetYAxisMode(yaxis_mode::normal);
1960 edp_p_value.SetYLimit(_range::high, 1);
1961 edp_p_value.SetResult(edp_profile_set_p_value);
1962 edp_profile_set_p_value->SetLimit(_range::high, aquiutils::atof(arguments.at("P-value threshold")));
1963 edp_profile_set_p_value->SetLimit(_range::low, 0);
1964 results.Append(edp_p_value);
1965
1966 return true;
1967}
1968
1969bool Conductor::ExecuteANOVA(const std::map<std::string, std::string>& arguments)
1970{
1971 bool log_transformation = (arguments.at("Log Transformation") == "true");
1972 bool exclude_samples = (arguments.at("Use only selected samples") == "true");
1973 bool exclude_elements = (arguments.at("Use only selected elements") == "true");
1974
1975 SourceSinkData transformed_data;
1976
1977 if (arguments.at("OM and Size Correct based on target sample") != "")
1978 {
1979 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
1980 {
1981 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
1982 return false;
1983 }
1984 transformed_data = Data()->CreateCorrectedDataset(
1985 arguments.at("OM and Size Correct based on target sample"),
1986 true,
1987 Data()->GetElementInformation()
1988 ).CreateCorrectedAndFilteredDataset(true, false, false);
1989 }
1990 else
1991 {
1992 transformed_data = Data()->CreateCorrectedAndFilteredDataset(true, false, false);
1993 }
1994
1995 if (!CheckNegativeElements(&transformed_data))
1996 return false;
1997
1998 if (arguments.at("Box-cox transformation") == "true")
1999 {
2000 transformed_data = transformed_data.BoxCoxTransformed(true);
2001 log_transformation = false;
2002 }
2003
2004 results.SetName("ANOVA analysis");
2005
2006 ResultItem anova_results;
2007 anova_results.SetName("ANOVA");
2008 anova_results.SetType(result_type::vector);
2009 anova_results.SetShowAsString(true);
2010 anova_results.SetShowTable(true);
2011 anova_results.SetShowGraph(true);
2012
2013 CMBVector* p_values = new CMBVector(transformed_data.ANOVA(log_transformation));
2014
2015 p_values->SetLimit(_range::high, aquiutils::atof(arguments.at("P-value threshold")));
2016 p_values->SetLimit(_range::low, 0);
2017
2018 anova_results.SetYAxisMode(yaxis_mode::normal);
2019 anova_results.SetResult(p_values);
2020 anova_results.setYAxisTitle("P-value");
2021 anova_results.setXAxisTitle("Element");
2022
2023 if (arguments.at("Modify the included elements based on the results") == "true")
2024 {
2025 std::vector<std::string> selected = p_values->ExtractWithinRange(
2026 0,
2027 aquiutils::atof(arguments.at("P-value threshold"))
2028 ).Labels();
2030 }
2031
2032 results.Append(anova_results);
2033
2034 return true;
2035}
2036
2037bool Conductor::ExecuteErrorAnalysis(const std::map<std::string, std::string>& arguments)
2038{
2039 results.SetName("Error Analysis");
2040
2042
2043 bool organic_size_correction;
2044 if (arguments.at("Apply size and organic matter correction") == "true")
2045 {
2046 organic_size_correction = true;
2047 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
2048 {
2049 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
2050 return false;
2051 }
2052 }
2053 else
2054 {
2055 organic_size_correction = false;
2056 }
2057
2058 rtw->show();
2059
2060 SourceSinkData corrected_data = Data()->CreateCorrectedDataset(
2061 arguments.at("Sample"),
2062 organic_size_correction,
2063 Data()->GetElementInformation()
2064 );
2065
2066 corrected_data.SetProgressWindow(rtw);
2067
2068 if (!CheckNegativeElements(&corrected_data))
2069 return false;
2070
2071 bool softmax = (arguments.at("Softmax transformation") == "true");
2072
2073 corrected_data.InitializeParametersAndObservations(arguments.at("Sample"));
2074
2075 bool outcome = corrected_data.BootStrap(
2076 &results,
2077 aquiutils::atof(arguments.at("Pecentage eliminated")),
2078 aquiutils::atoi(arguments.at("Number of realizations")),
2079 arguments.at("Sample"),
2080 softmax
2081 );
2082
2083 return outcome;
2084}
2085
2086bool Conductor::ExecuteSourceVerify(const std::map<std::string, std::string>& arguments)
2087{
2088 results.SetName("Source Verification");
2089
2091
2092 bool organic_size_correction;
2093 if (arguments.at("Apply size and organic matter correction") == "true")
2094 {
2095 organic_size_correction = true;
2096 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
2097 {
2098 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
2099 return false;
2100 }
2101 }
2102 else
2103 {
2104 organic_size_correction = false;
2105 }
2106
2107 rtw->show();
2108
2109 SourceSinkData corrected_data = *Data();
2110 corrected_data.SetProgressWindow(rtw);
2111
2112 if (!CheckNegativeElements(&corrected_data))
2113 return false;
2114
2115 bool softmax = (arguments.at("Softmax transformation") == "true");
2116
2117 CMBTimeSeriesSet* contributions = new CMBTimeSeriesSet(
2118 corrected_data.VerifySource(
2119 arguments.at("Source Group"),
2120 softmax,
2121 organic_size_correction
2122 )
2123 );
2124
2125 ResultItem contributions_result_item;
2126 results.SetName("Source verification for source'" + arguments.at("Source Group") + "'");
2127
2128 contributions->GetOptions().X_suffix = "";
2129 contributions->GetOptions().Y_suffix = "";
2130 contributions->SetOption(options_key::single_column_x, true);
2131
2132 contributions_result_item.SetName("Source Verification");
2133 contributions_result_item.SetResult(contributions);
2134 contributions_result_item.SetType(result_type::stacked_bar_chart);
2135 contributions_result_item.SetShowAsString(true);
2136 contributions_result_item.SetShowTable(true);
2137 contributions_result_item.SetShowGraph(true);
2138 contributions_result_item.SetYLimit(_range::high, 1);
2139 contributions_result_item.SetXAxisMode(xaxis_mode::counter);
2140 contributions_result_item.setYAxisTitle("Contribution");
2141 contributions_result_item.setXAxisTitle("Source Sample");
2142 contributions_result_item.SetYLimit(_range::low, 0);
2143
2144 results.Append(contributions_result_item);
2145
2146 rtw->SetProgress(1);
2147
2148 return true;
2149}
2150
2151bool Conductor::ExecuteAutoSelect(const std::map<std::string, std::string>& arguments)
2152{
2153 results.SetName("Auto-select elements");
2154
2155 SourceSinkData transformed_data;
2156
2157 if (arguments.at("OM and Size Correct based on target sample") != "")
2158 {
2159 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
2160 {
2161 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
2162 return false;
2163 }
2164 transformed_data = Data()->CreateCorrectedDataset(
2165 arguments.at("OM and Size Correct based on target sample"),
2166 true,
2167 Data()->GetElementInformation()
2168 ).CreateCorrectedAndFilteredDataset(true, false, false);
2169 }
2170 else
2171 {
2172 transformed_data = Data()->CreateCorrectedAndFilteredDataset(true, false, false);
2173 }
2174
2175 if (!CheckNegativeElements(&transformed_data))
2176 return false;
2177
2178 bool isotopes = (arguments.at("Include Isotopes") == "true");
2179
2180 transformed_data = transformed_data.ExtractChemicalElements(isotopes);
2181
2182 // Multi-way discriminant p-value result
2183 ResultItem edp_p_value;
2184 edp_p_value.SetName("Multi-way discriminat p-value");
2186 edp_p_value.SetShowAsString(true);
2187 edp_p_value.setYAxisTitle("p-Value");
2188 edp_p_value.SetShowTable(true);
2189 edp_p_value.SetShowGraph(true);
2190
2191 Elemental_Profile_Set* edp_profile_set_p_value = new Elemental_Profile_Set(
2192 transformed_data.DifferentiationPower_P_value(false)
2193 );
2194
2195 edp_p_value.SetYAxisMode(yaxis_mode::normal);
2196 edp_p_value.SetYLimit(_range::high, 1);
2197 edp_p_value.SetResult(edp_profile_set_p_value);
2198 results.Append(edp_p_value);
2199
2200 // Selected elements result
2201 Elemental_Profile* selected = new Elemental_Profile(
2202 edp_profile_set_p_value->SelectTopElementsAggregate(
2203 aquiutils::atoi(arguments.at("Number of elements from each pair"))
2204 )
2205 );
2206
2207 ResultItem selected_elements;
2208 selected_elements.SetResult(selected);
2209 selected_elements.SetName("Selected Elements");
2211 selected_elements.SetShowAsString(true);
2212 selected_elements.setYAxisTitle("p-Value");
2213 selected_elements.SetShowTable(true);
2214 selected_elements.SetShowGraph(true);
2215 results.Append(selected_elements);
2216
2217 if (arguments.at("Modify the included elements based on the results") == "true")
2218 {
2220 }
2221
2222 return true;
2223}
2224
2225bool Conductor::ExecuteCMBBayesian(const std::map<std::string, std::string>& arguments)
2226{
2227 if (arguments.at("Apply size and organic matter correction") == "true")
2228 {
2229 if (Data()->OMandSizeConstituents()[0] == "" && Data()->OMandSizeConstituents()[1] == "")
2230 {
2231 QMessageBox::warning(mainwindow, "SedSAT3", "Perform Organic Matter and Size Correction first!\n", QMessageBox::Ok);
2232 return false;
2233 }
2234 }
2235
2236 // Initialize MCMC object
2237 MCMC = std::make_unique<CMCMC<SourceSinkData>>();
2238
2239 // Create progress window with 3 charts for monitoring
2241 rtw->SetTitle("Acceptance Rate", 0);
2242 rtw->SetTitle("Purturbation Factor", 1);
2243 rtw->SetTitle("Log posterior value", 2);
2244 rtw->SetYAxisTitle("Acceptance Rate", 0);
2245 rtw->SetYAxisTitle("Purturbation Factor", 1);
2246 rtw->SetYAxisTitle("Log posterior value", 2);
2247 rtw->show();
2248
2249 // Execute MCMC sampling
2250 results = Data()->MCMC(
2251 arguments.at("Sample"),
2252 arguments,
2253 MCMC.get(),
2254 rtw,
2255 workingfolder.toStdString()
2256 );
2257
2258 // Check for errors during execution
2259 if (results.Error() != "")
2260 {
2261 QMessageBox::warning(mainwindow, "SedSat3", QString::fromStdString(results.Error()), QMessageBox::Ok);
2262 return false;
2263 }
2264
2265 rtw->SetProgress(1);
2266
2267 return true;
2268}
Matrix class with labeled rows and columns for Chemical Mass Balance analysis.
Definition cmbmatrix.h:19
void SetBooleanValue(bool val)
Sets boolean display mode for table widget.
Definition cmbmatrix.h:183
Collection of time series with labels and observed values.
Collection of named CMBVectorSet objects for hierarchical data organization.
Collection of named CMBVector objects for multi-variable analysis.
Vector class with string labels for Chemical Mass Balance analysis.
Definition cmbvector.h:17
CMBVector ExtractWithinRange(const double &lowval, const double &highval) const
Extracts elements with values within specified range.
void SetBooleanValue(bool val)
Sets boolean display mode for table widget.
Definition cmbvector.h:161
CMBVector ExtractUpToMinimum() const
Extracts elements up to first minimum value.
void append(const string &label, const double &val)
Appends a labeled element to the vector.
double valueAt(int i) const
Gets value at specified index.
vector< string > Labels() const
Gets all element labels.
Definition cmbvector.h:138
Markov Chain Monte Carlo sampler for Bayesian parameter estimation.
Definition MCMC.h:326
bool SetProperty(const string &varname, const string &value)
Set MCMC properties from string key-value pairs.
Definition MCMC.hpp:68
bool step(int k, int chain_counter)
Perform single MCMC step for one chain.
Definition MCMC.hpp:337
T * Model
Pointer to the model object being calibrated.
Definition MCMC.h:334
void initialize(CMBTimeSeriesSet *results, bool random=false)
Initialize MCMC chains with starting parameter values.
Definition MCMC.hpp:200
CMBTimeSeriesSet CreateCDFComparison(distribution_type dist_type) const
Create comparison of empirical vs fitted CDF.
CMBTimeSeriesSet CreateFittedDistribution(distribution_type dist_type) const
Create fitted distribution visualization.
bool ExecuteOutlierAnalysis(const std::map< std::string, std::string > &arguments)
Executes outlier detection analysis for a source/target group.
bool ExecuteTestCMBBayesian(const std::map< std::string, std::string > &arguments)
Executes MCMC test with a simple analytical model.
bool ExecuteCMBBayesian(const std::map< std::string, std::string > &arguments)
Executes Bayesian Chemical Mass Balance using MCMC sampling.
bool ExecuteDFAM(const std::map< std::string, std::string > &arguments)
Executes multi-way Discriminant Function Analysis across all groups.
bool ExecuteDFA(const std::map< std::string, std::string > &arguments)
Executes Discriminant Function Analysis between two groups.
bool ExecuteSDFAM(const std::map< std::string, std::string > &arguments)
Executes multi-way Stepwise Discriminant Function Analysis across all groups.
bool ExecuteBoxCox(const std::map< std::string, std::string > &arguments)
Calculates optimal Box-Cox transformation parameters.
bool ExecuteKolmogorovSmirnovIndividual(const std::map< std::string, std::string > &arguments)
Executes Kolmogorov-Smirnov test for a single constituent in a group.
bool CheckNegativeElements(SourceSinkData *data=nullptr)
Validates that all element concentrations are non-negative.
bool ExecuteCMBBayesianBatch(const std::map< std::string, std::string > &arguments)
Executes Bayesian Chemical Mass Balance across all target samples.
bool ExecuteAutoSelect(const std::map< std::string, std::string > &arguments)
Executes automatic element selection based on discriminant power.
bool ExecuteSDFA(const std::map< std::string, std::string > &arguments)
Executes Stepwise Discriminant Function Analysis between two groups.
bool ExecuteBracketingAnalysisBatch(const std::map< std::string, std::string > &arguments)
Executes bracketing analysis across all target samples.
bool ExecuteANOVA(const std::map< std::string, std::string > &arguments)
Executes Analysis of Variance (ANOVA) for element discrimination.
QString workingfolder
Output directory path.
Definition conductor.h:143
std::unique_ptr< CGA< SourceSinkData > > GA
Genetic Algorithm optimizer (owned)
Definition conductor.h:140
bool ExecuteGA_NoTargets(const std::map< std::string, std::string > &arguments)
Executes Genetic Algorithm disregarding target constraints.
bool ExecuteGA(const std::map< std::string, std::string > &arguments)
Executes Genetic Algorithm optimization.
bool ExecuteSourceVerify(const std::map< std::string, std::string > &arguments)
Executes source verification analysis.
bool ExecuteGA_FixedProfile(const std::map< std::string, std::string > &arguments)
Executes Genetic Algorithm with fixed elemental profiles.
bool ExecuteMLR(const std::map< std::string, std::string > &arguments)
Executes multiple linear regression versus organic matter and particle size.
MainWindow * mainwindow
Non-owning pointer to parent window.
Definition conductor.h:144
bool ExecuteDistributionFitting(const std::map< std::string, std::string > &arguments)
Executes distribution fitting analysis for a constituent.
bool ExecuteLevenbergMarquardtBatch(const std::map< std::string, std::string > &arguments)
Executes Levenberg-Marquardt optimization across all target samples.
bool ExecuteKolmogorovSmirnov(const std::map< std::string, std::string > &arguments)
Executes Kolmogorov-Smirnov goodness-of-fit test for a source/target group.
bool ExecuteErrorAnalysis(const std::map< std::string, std::string > &arguments)
Executes bootstrap error analysis for uncertainty quantification.
SourceSinkData * Data()
Returns pointer to the current SourceSinkData.
Definition conductor.h:75
SourceSinkData * data
Non-owning pointer to analysis data.
Definition conductor.h:139
bool ExecuteSDFAOnevsRest(const std::map< std::string, std::string > &arguments)
Executes Stepwise Discriminant Function Analysis for one group versus all others.
bool Execute(const std::string &command, std::map< std::string, std::string > arguments)
Executes a specified analysis command with given parameters.
Definition conductor.cpp:18
bool ExecuteBracketingAnalysis(const std::map< std::string, std::string > &arguments)
Executes bracketing analysis for a single target sample.
bool ExecuteDFAOnevsRest(const std::map< std::string, std::string > &arguments)
Executes Discriminant Function Analysis for one group versus all others.
bool ExecuteCovarianceMatrix(const std::map< std::string, std::string > &arguments)
Calculates covariance matrix for a source or target group.
Conductor(MainWindow *mainwindow)
Constructs a Conductor associated with a MainWindow.
Definition conductor.cpp:12
Results results
Current analysis results (cleared each Execute)
Definition conductor.h:142
bool ExecuteOMSizeCorrect(const std::map< std::string, std::string > &arguments)
Executes organic matter and particle size correction.
bool ExecuteLevenbergMarquardt(const std::map< std::string, std::string > &arguments)
Executes Levenberg-Marquardt nonlinear optimization.
bool ExecuteEDP(const std::map< std::string, std::string > &arguments)
Calculates two-way element discriminant power between two groups.
bool ExecuteEDPM(const std::map< std::string, std::string > &arguments)
Calculates multi-way element discriminant power across all groups.
bool ExecuteCorrelationMatrix(const std::map< std::string, std::string > &arguments)
Calculates correlation matrix for a source or target group.
std::unique_ptr< CMCMC< SourceSinkData > > MCMC
MCMC sampler (owned)
Definition conductor.h:141
Manages a collection of elemental profiles (samples) for source fingerprinting analysis.
Elemental_Profile SelectTopElementsAggregate(int n) const
Select top N elements across all samples (aggregate minimum)
Container for elemental concentration data of a single sediment sample.
vector< string > GetElementNames() const
Get list of all element names.
options & GetOptions()
Get reference to the options structure.
Definition interface.h:275
void SetOption(options_key opt, bool val)
Set a configuration option.
Definition interface.h:250
void SetLimit(_range lowhigh, const double &value)
Set upper or lower limit for value highlighting.
Definition interface.h:233
Main application window for SedSAT3 source apportionment analysis.
Definition mainwindow.h:41
void SetYAxisTitle(const QString &title, int chart=0)
void SetProgress(const double &prog)
void SetTitle(const QString &title, int chart=0)
void SetAbsoluteValue(bool val)
Definition resultitem.h:57
void SetShowGraph(bool state)
Definition resultitem.h:80
void setYAxisTitle(const string &title)
Definition resultitem.h:39
void SetXAxisMode(xaxis_mode mode)
Definition resultitem.h:26
void SetYLimit(_range highlow, const double &value)
Definition resultitem.h:66
void setTableTitle(const string &Title)
Definition resultitem.h:47
void SetName(const string &_name)
Definition resultitem.h:21
void SetResult(Interface *_result)
Definition resultitem.h:18
void SetShowTable(bool state)
Definition resultitem.h:78
void setXAxisTitle(const string &title)
Definition resultitem.h:31
void SetYAxisMode(yaxis_mode mode)
Definition resultitem.h:25
void SetShowAsString(bool value)
Definition resultitem.h:29
void SetType(const result_type &_type)
Definition resultitem.h:23
void Append(const ResultItem &)
Definition results.cpp:25
string Error()
Definition results.h:27
void SetName(const string &_name)
Definition results.h:21
bool InitializeParametersAndObservations(const string &targetsamplename, estimation_mode est_mode=estimation_mode::elemental_profile_and_contribution)
Initialize parameters and observations for MCMC optimization.
void SetProgressWindow(ProgressWindow *_rtw)
Sets the progress window for displaying optimization progress.
bool PerformRegressionVsOMAndSize(const string &om, const string &particle_size, regression_form form, const double &p_value_threshold=0.05)
Performs multiple linear regression of elements vs OM and particle size.
Elemental_Profile_Set DifferentiationPower_Percentage(bool include_target)
Computes rank-based differentiation percentage for all source pairs.
CMBTimeSeriesSet BootStrap(const double &percentage, unsigned int num_iterations, string target_sample, bool use_softmax)
Performs bootstrap uncertainty analysis on source contributions.
SourceSinkData ExtractChemicalElements(bool isotopes) const
Extract only chemical elements (and optionally isotopes)
CMBVector ANOVA(bool use_log)
Performs one-way ANOVA for all elements across source groups.
bool SolveLevenberg_Marquardt(transformation trans=transformation::linear)
Solves for optimal source contributions using the Levenberg-Marquardt algorithm.
vector< CMBVector > StepwiseDiscriminantFunctionAnalysis(const string &source1, const string &source2)
Performs stepwise discriminant analysis between two specific sources.
ConcentrationSet * GetElementDistribution(const string &element_name)
Retrieves pointer to element distribution at dataset level.
SourceSinkData BoxCoxTransformed(bool calculate_optimal_lambda=false)
Applies Box-Cox transformation to all source groups for normalization.
void SetParameterEstimationMode(estimation_mode est_mode)
Sets the estimation mode for parameter optimization.
Elemental_Profile t_TestPValue(const string &source1, const string &source2, bool use_log)
Computes t-test p-values for element-wise differences between two sources.
vector< ResultItem > GetMLRResults()
Retrieves multiple linear regression results for all sample groups.
CMBVector BracketTest(const string &target_sample, bool correct_based_on_om_n_size)
Performs bracket test to check if target concentrations fall within source ranges.
void IncludeExcludeElementsBasedOn(const vector< string > &elements)
Sets element inclusion based on a specified list.
ResultItem GetPredictedElementalProfile(parameter_mode param_mode=parameter_mode::based_on_fitted_distribution)
Generates predicted elemental concentrations for the target sample.
void SetOMandSizeConstituents(const string &_omconstituent, const string &_sizeconsituent)
Sets the names of OM and particle size constituents.
SourceSinkData CreateCorrectedAndFilteredDataset(bool exclude_samples, bool exclude_elements, bool omnsizecorrect, const string &target="") const
Create a corrected and filtered copy of the dataset.
vector< string > NegativeValueCheck()
Checks for zero or negative concentration values across all sources.
CMBTimeSeriesSet VerifySource(const string &source_group, bool use_softmax, bool apply_om_size_correction)
Performs leave-one-out validation on a source group.
bool SetSelectedTargetSample(const string &sample_name)
Sets the currently selected target sample for analysis.
void AddtoToolsUsed(const string &tool)
Adds a tool name to the list of tools used in analysis.
DFA_result DiscriminantFunctionAnalysis()
Performs discriminant function analysis for all source groups.
vector< ResultItem > GetSourceProfiles()
Retrieves elemental profiles for all source groups.
Results MCMC(const string &target_sample, map< string, string > arguments, CMCMC< SourceSinkData > *mcmc, ProgressWindow *progress_window, const string &working_folder)
Performs Markov Chain Monte Carlo analysis for Bayesian source apportionment.
Elemental_Profile_Set DifferentiationPower(bool use_log, bool include_target)
Computes differentiation power for all source pairs.
SourceSinkData CreateCorrectedDataset(const string &target, bool omnsizecorrect, map< string, element_information > *elementinfo)
Create a corrected copy of the dataset for a specific target sample.
ResultItem GetObservedvsModeledElementalProfile(parameter_mode param_mode=parameter_mode::based_on_fitted_distribution)
Creates a comparison of observed vs modeled elemental profiles.
string GetTargetGroup() const
Retrieves the name of the target group.
Elemental_Profile_Set DifferentiationPower_P_value(bool include_target)
Computes t-test p-values for all source pairs.
ResultItem GetContribution()
Packages source contributions into a ResultItem for output.
ResultItem GetObservedvsModeledElementalProfile_Isotope(parameter_mode param_mode=parameter_mode::based_on_fitted_distribution)
Creates a comparison of observed vs modeled isotope delta values.
vector< string > OMandSizeConstituents()
Retrieves the names of OM and particle size constituents.
void InitializeParametersObservations(const vector< double > &mins, const vector< double > &maxs)
Definition testmcmc.cpp:8
@ direct
Use empirical statistics from data.
distribution_type
Enumeration of probability distribution types supported in SedSat3.
@ lognormal
Lognormal distribution: ln(x) ~ N(μ, σ²), for strictly positive variables.
@ normal
Normal (Gaussian) distribution: p(x) = N(μ, σ²)
@ single_column_x
Enable single-column mode for X-axis data representation.
@ low
Lower bound of the parameter range.
@ high
Upper bound of the parameter range.
@ predicted_concentration
@ elemental_profile_set
@ timeseries_set_first_symbol
@ source_elemental_profiles_based_on_source_data
CMBVectorSet projected
CMBVector p_values
CMBVectorSet eigen_vectors
CMBVector F_test_P_value
CMBVectorSetSet multi_projected
QString X_suffix
Suffix appended to X-axis field names in serialization.
Definition interface.h:33
QString Y_suffix
Suffix appended to Y-axis field names in serialization.
Definition interface.h:34