From 636dab497be2cd630b2f0a549f381a323bf23b77 Mon Sep 17 00:00:00 2001
From: rakhimov
Date: Fri, 11 Aug 2017 21:28:10 -0700
Subject: [PATCH] Add alignment & phase info into event tree reports
Issue #153
---
input/EventTrees/attack_alignment.xml | 6 ++++++
share/report.rng | 6 ++++++
src/reporter.cc | 18 +++++++++++++-----
src/reporter.h | 4 ++--
src/risk_analysis.cc | 3 ++-
src/risk_analysis.h | 17 ++++++++++++-----
tests/risk_analysis_tests.cc | 11 ++++++++++-
7 files changed, 51 insertions(+), 14 deletions(-)
create mode 100644 input/EventTrees/attack_alignment.xml
diff --git a/input/EventTrees/attack_alignment.xml b/input/EventTrees/attack_alignment.xml
new file mode 100644
index 0000000000..b1e7cce543
--- /dev/null
+++ b/input/EventTrees/attack_alignment.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/share/report.rng b/share/report.rng
index 78699bb0bc..7d675669a7 100644
--- a/share/report.rng
+++ b/share/report.rng
@@ -496,6 +496,12 @@
+
+
+
+
+
+
diff --git a/src/reporter.cc b/src/reporter.cc
index 32e5783e56..763b649a56 100644
--- a/src/reporter.cc
+++ b/src/reporter.cc
@@ -74,9 +74,9 @@ void Reporter::Report(const core::RiskAnalysis& risk_an, std::ostream& out) {
TIMER(DEBUG1, "Reporting analysis results");
XmlStreamElement results = report.AddChild("results");
if (risk_an.settings().probability_analysis()) {
- for (const std::unique_ptr& result :
+ for (const core::RiskAnalysis::EtaResult& result :
risk_an.event_tree_results()) {
- ReportResults(*result, &results);
+ ReportResults(result, &results);
}
}
@@ -336,11 +336,19 @@ void Reporter::ReportUnusedElements(const T& container,
information->AddChild("warning").AddText(header + out);
}
-void Reporter::ReportResults(const core::EventTreeAnalysis& eta,
+void Reporter::ReportResults(const core::RiskAnalysis::EtaResult& eta_result,
XmlStreamElement* results) {
+ const core::EventTreeAnalysis& eta = *eta_result.event_tree_analysis;
XmlStreamElement initiating_event = results->AddChild("initiating-event");
- initiating_event.SetAttribute("name", eta.initiating_event().name())
- .SetAttribute("sequences", eta.sequences().size());
+ initiating_event.SetAttribute("name", eta.initiating_event().name());
+
+ if (eta_result.context) {
+ initiating_event
+ .SetAttribute("alignment", eta_result.context->alignment.name())
+ .SetAttribute("phase", eta_result.context->phase.name());
+ }
+
+ initiating_event.SetAttribute("sequences", eta.sequences().size());
for (const core::EventTreeAnalysis::Result& result_sequence :
eta.sequences()) {
initiating_event.AddChild("sequence")
diff --git a/src/reporter.h b/src/reporter.h
index 12ca940f6f..ec4ec23cd1 100644
--- a/src/reporter.h
+++ b/src/reporter.h
@@ -114,11 +114,11 @@ class Reporter {
/// Reports the results of event tree analysis
/// to a specified output destination.
///
- /// @param[in] eta Event Tree Analysis with sequence results.
+ /// @param[in] eta_result Event Tree Analysis with sequence results.
/// @param[in,out] results XML element to for all results.
///
/// @pre The probability analysis has been performed.
- void ReportResults(const core::EventTreeAnalysis& eta,
+ void ReportResults(const core::RiskAnalysis::EtaResult& eta_result,
XmlStreamElement* results);
/// Reports the results of fault tree analysis
diff --git a/src/risk_analysis.cc b/src/risk_analysis.cc
index 8d31258d3f..83736a2cf7 100644
--- a/src/risk_analysis.cc
+++ b/src/risk_analysis.cc
@@ -98,7 +98,8 @@ void RiskAnalysis::RunAnalysis(boost::optional context) {
result.p_sequence = results_.back().probability_analysis->p_total();
LOG(INFO) << "Finished analysis for sequence: " << sequence.name();
}
- event_tree_results_.push_back(std::move(eta));
+ event_tree_results_.push_back(
+ {*initiating_event, context, std::move(eta)});
LOG(INFO) << "Finished event tree analysis: " << initiating_event->name();
}
}
diff --git a/src/risk_analysis.h b/src/risk_analysis.h
index 6903345757..b20b779127 100644
--- a/src/risk_analysis.h
+++ b/src/risk_analysis.h
@@ -72,6 +72,16 @@ class RiskAnalysis : public Analysis {
/// @}
};
+ /// The analysis results grouped by an event-tree.
+ ///
+ /// @todo Replace with query (group_by).
+ struct EtaResult {
+ const mef::InitiatingEvent& initiating_event; ///< Unique event per tree.
+ boost::optional context; ///< The alignment context.
+ /// The holder of the analysis.
+ std::unique_ptr event_tree_analysis;
+ };
+
/// @param[in] model An analysis model with fault trees, events, etc.
/// @param[in] settings Analysis settings for the given model.
///
@@ -99,8 +109,7 @@ class RiskAnalysis : public Analysis {
const std::vector& results() const { return results_; }
/// @returns The results of the event tree analysis.
- const std::vector>& event_tree_results()
- const {
+ const std::vector& event_tree_results() const {
return event_tree_results_;
}
@@ -146,9 +155,7 @@ class RiskAnalysis : public Analysis {
mef::Model* model_; ///< The model with constructs.
std::vector results_; ///< The analysis result storage.
- /// Event tree analysis of sequences.
- /// @todo Incorporate into the main results container.
- std::vector> event_tree_results_;
+ std::vector event_tree_results_; ///< Grouping of sequences.
};
} // namespace core
diff --git a/tests/risk_analysis_tests.cc b/tests/risk_analysis_tests.cc
index 0957dfbc1e..8fdb731af1 100644
--- a/tests/risk_analysis_tests.cc
+++ b/tests/risk_analysis_tests.cc
@@ -104,10 +104,13 @@ RiskAnalysisTest::product_probability() {
}
std::map RiskAnalysisTest::sequences() {
+ assert(model->alignments().empty());
assert(analysis->event_tree_results().size() == 1);
std::map results;
for (const core::EventTreeAnalysis::Result& result :
- analysis->event_tree_results().front()->sequences()) {
+ analysis->event_tree_results()
+ .front()
+ .event_tree_analysis->sequences()) {
results.emplace(result.sequence.name(), result.p_sequence);
}
return results;
@@ -581,6 +584,12 @@ TEST_F(RiskAnalysisTest, ReportAlignment) {
CheckReport({tree_input});
}
+TEST_F(RiskAnalysisTest, ReportAlignmentEventTree) {
+ std::string dir = "./share/scram/input/EventTrees/";
+ settings.probability_analysis(true);
+ CheckReport({dir + "attack_alignment.xml", dir + "attack.xml"});
+}
+
// NAND and NOR as a child cases.
TEST_P(RiskAnalysisTest, ChildNandNorGates) {
std::string tree_input = "./share/scram/input/fta/children_nand_nor.xml";