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";