Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F10711630
main.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
11 KB
Referenced Files
None
Subscribers
None
main.cpp
View Options
//===-- apps/sa-ews1/sa-ews1.cpp --------------------------------*- C++ -*-===//
//
// The RoSA Framework -- Application SA-EWS1
//
//===----------------------------------------------------------------------===//
///
/// \file apps/sa-ews1/sa-ews1.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief The application SA-EWS1 implements the case study from the paper:
/// M. Götzinger, N. Taherinejad, A. M. Rahmani, P. Liljeberg, A. Jantsch, and
/// H. Tenhunen: Enhancing the Early Warning Score System Using Data Confidence
/// DOI: 10.1007/978-3-319-58877-3_12
//===----------------------------------------------------------------------===//
#include
"rosa/agent/Abstraction.hpp"
#include
"rosa/agent/Confidence.hpp"
#include
"rosa/config/version.h"
#include
"rosa/deluxe/DeluxeContext.hpp"
#include
"rosa/support/csv/CSVReader.hpp"
#include
"rosa/support/csv/CSVWriter.hpp"
#include
<fstream>
using
namespace
rosa
;
using
namespace
rosa
::
agent
;
using
namespace
rosa
::
deluxe
;
using
namespace
rosa
::
terminal
;
const
std
::
string
AppName
=
"Test-CSVFiles"
;
/// Paths for the CSV files for simulation.
///
///@{
//const std::string HRCSVPath = "HR.csv";
const
std
::
string
HRCSVPathOld
=
"HR-New.csv"
;
const
std
::
string
HRCSVPath
=
"HR-New-Semicolon.csv"
;
const
std
::
string
BRCSVPath
=
"BR.csv"
;
const
std
::
string
SpO2CSVPath
=
"SpO2.csv"
;
const
std
::
string
BPSysCSVPath
=
"BPSys.csv"
;
const
std
::
string
BodyTempCSVPath
=
"BodyTemp.csv"
;
const
std
::
string
ScoreCSVPath
=
"Score.csv"
;
///@}
/// How many cycles of simulation to perform.
const
size_t
NumberOfSimulationCycles
=
16
;
/// Warning levels for abstraction.
enum
WarningScore
{
No
=
0
,
Low
=
1
,
High
=
2
,
Emergency
=
3
};
/// Helper function creating a deluxe agent for pre-processing sensory values.
///
/// Received values are first validated for confidence. Values which the
/// validator does not mark confident are ignored. Confident values are
/// abstracted into a \c WarningScore value, which is the result of the
/// processing function.
///
/// \note The result, \c WarningScore, is returned as \c uint32_t because
/// enumeration types are not integrated into built-in types. Hence, a master
/// to these agents receives its input as \c uint32_t values, and may cast them
/// to \c WarningScore explicitly.
///
/// \tparam T type of values to receive from the sensor
///
/// \param C the deluxe context to create the agent in
/// \param Name name of the new agent
/// \param CC confidence validator to use
/// \param A abstraction to use
///
/// \return handle for the new agent
template
<
typename
T
>
AgentHandle
createLowLevelAgent
(
std
::
unique_ptr
<
DeluxeContext
>
&
C
,
const
std
::
string
&
Name
,
const
Confidence
<
T
>
&
CC
,
const
Abstraction
<
T
,
WarningScore
>
&
A
)
{
using
handler
=
DeluxeAgent
::
D
<
uint32_t
,
T
>
;
using
result
=
Optional
<
uint32_t
>
;
return
C
->
createAgent
(
Name
,
handler
([
&
,
Name
](
std
::
pair
<
T
,
bool
>
I
)
->
result
{
LOG_INFO_STREAM
<<
"
\n
******
\n
"
<<
Name
<<
" "
<<
(
I
.
second
?
"<New>"
:
"<Old>"
)
<<
" value: "
<<
I
.
first
<<
"
\n
******
\n
"
;
return
(
I
.
second
&&
CC
(
I
.
first
))
?
result
(
A
(
I
.
first
))
:
result
();
}));
}
int
main
(
void
)
{
LOG_INFO_STREAM
<<
'\n'
<<
library_string
()
<<
" -- "
<<
Color
::
Red
<<
AppName
<<
"app"
<<
Color
::
Default
<<
'\n'
<<
Color
::
Yellow
<<
"CSV files are read from and written to the current working directory."
<<
Color
::
Default
<<
'\n'
;
std
::
unique_ptr
<
DeluxeContext
>
C
=
DeluxeContext
::
create
(
AppName
);
//
// Create deluxe sensors.
//
LOG_INFO
(
"Creating sensors."
);
// All sensors are created without defining a normal generator function, but
// with the default value of the second argument. That, however, requires the
// data type to be explicitly defined. This is good for simulation only.
AgentHandle
HRSensor
=
C
->
createSensor
<
int32_t
>
(
"HR Sensor"
);
AgentHandle
BRSensor
=
C
->
createSensor
<
int32_t
>
(
"BR Sensor"
);
AgentHandle
SpO2Sensor
=
C
->
createSensor
<
int32_t
>
(
"SpO2 Sensor"
);
AgentHandle
BPSysSensor
=
C
->
createSensor
<
int32_t
>
(
"BPSys Sensor"
);
AgentHandle
BodyTempSensor
=
C
->
createSensor
<
float
>
(
"BodyTemp Sensor"
);
//
// Create functionalities.
//
LOG_INFO
(
"Creating Functionalities for Agents."
);
//
// Define confidence validators.
//
// Lower bounds are inclusive and upper bounds are exclusive.
Confidence
<
int32_t
>
HRConfidence
(
0
,
501
);
Confidence
<
int32_t
>
BRConfidence
(
0
,
301
);
Confidence
<
int32_t
>
SpO2Confidence
(
0
,
101
);
Confidence
<
int32_t
>
BPSysConfidence
(
0
,
501
);
Confidence
<
float
>
BodyTempConfidence
(
-60
,
nextRepresentableFloatingPoint
(
50.0f
));
//
// Define abstractions.
//
RangeAbstraction
<
int32_t
,
WarningScore
>
HRAbstraction
(
{{{
0
,
40
},
Emergency
},
{{
40
,
51
},
High
},
{{
51
,
60
},
Low
},
{{
60
,
100
},
No
},
{{
100
,
110
},
Low
},
{{
110
,
129
},
High
},
{{
129
,
200
},
Emergency
}},
Emergency
);
RangeAbstraction
<
int32_t
,
WarningScore
>
BRAbstraction
({{{
0
,
9
},
High
},
{{
9
,
14
},
No
},
{{
14
,
20
},
Low
},
{{
20
,
29
},
High
},
{{
29
,
50
},
Emergency
}},
Emergency
);
RangeAbstraction
<
int32_t
,
WarningScore
>
SpO2Abstraction
({{{
1
,
85
},
Emergency
},
{{
85
,
90
},
High
},
{{
90
,
95
},
Low
},
{{
95
,
100
},
No
}},
Emergency
);
RangeAbstraction
<
int32_t
,
WarningScore
>
BPSysAbstraction
(
{{{
0
,
70
},
Emergency
},
{{
70
,
81
},
High
},
{{
81
,
101
},
Low
},
{{
101
,
149
},
No
},
{{
149
,
169
},
Low
},
{{
169
,
179
},
High
},
{{
179
,
200
},
Emergency
}},
Emergency
);
RangeAbstraction
<
float
,
WarningScore
>
BodyTempAbstraction
(
{{{
0.f
,
28.f
},
Emergency
},
{{
28.f
,
32.f
},
High
},
{{
32.f
,
35.f
},
Low
},
{{
35.f
,
38.f
},
No
},
{{
38.f
,
39.5f
},
High
},
{{
39.5f
,
100.f
},
Emergency
}},
Emergency
);
//
// Create low-level deluxe agents with \c createLowLevelAgent.
//
LOG_INFO
(
"Creating low-level agents."
);
AgentHandle
HRAgent
=
createLowLevelAgent
(
C
,
"HR Agent"
,
HRConfidence
,
HRAbstraction
);
AgentHandle
BRAgent
=
createLowLevelAgent
(
C
,
"BR Agent"
,
BRConfidence
,
BRAbstraction
);
AgentHandle
SpO2Agent
=
createLowLevelAgent
(
C
,
"SpO2 Agent"
,
SpO2Confidence
,
SpO2Abstraction
);
AgentHandle
BPSysAgent
=
createLowLevelAgent
(
C
,
"BPSys Agent"
,
BPSysConfidence
,
BPSysAbstraction
);
AgentHandle
BodyTempAgent
=
createLowLevelAgent
(
C
,
"BodyTemp Agent"
,
BodyTempConfidence
,
BodyTempAbstraction
);
//
// Connect sensors to low-level agents.
//
LOG_INFO
(
"Connect sensors to their corresponding low-level agents."
);
C
->
connectSensor
(
HRAgent
,
0
,
HRSensor
,
"HR Sensor Channel"
);
C
->
connectSensor
(
BRAgent
,
0
,
BRSensor
,
"BR Sensor Channel"
);
C
->
connectSensor
(
SpO2Agent
,
0
,
SpO2Sensor
,
"SpO2 Sensor Channel"
);
C
->
connectSensor
(
BPSysAgent
,
0
,
BPSysSensor
,
"BPSys Sensor Channel"
);
C
->
connectSensor
(
BodyTempAgent
,
0
,
BodyTempSensor
,
"BodyTemp Sensor Channel"
);
//
// Create a high-level deluxe agent.
//
LOG_INFO
(
"Create high-level agent."
);
// The new agent logs its input values and results in the the sum of them.
AgentHandle
BodyAgent
=
C
->
createAgent
(
"Body Agent"
,
DeluxeAgent
::
D
<
uint32_t
,
uint32_t
,
uint32_t
,
uint32_t
,
uint32_t
,
uint32_t
>
(
[](
std
::
pair
<
uint32_t
,
bool
>
HR
,
std
::
pair
<
uint32_t
,
bool
>
BR
,
std
::
pair
<
uint32_t
,
bool
>
SpO2
,
std
::
pair
<
uint32_t
,
bool
>
BPSys
,
std
::
pair
<
uint32_t
,
bool
>
BodyTemp
)
->
Optional
<
uint32_t
>
{
LOG_INFO_STREAM
<<
"
\n
*******
\n
Body Agent trigged with values:
\n
"
<<
(
HR
.
second
?
"<New>"
:
"<Old>"
)
<<
" HR warning score: "
<<
HR
.
first
<<
"
\n
"
<<
(
BR
.
second
?
"<New>"
:
"<Old>"
)
<<
" BR warning score: "
<<
BR
.
first
<<
"
\n
"
<<
(
SpO2
.
second
?
"<New>"
:
"<Old>"
)
<<
" SpO2 warning score: "
<<
SpO2
.
first
<<
"
\n
"
<<
(
BPSys
.
second
?
"<New>"
:
"<Old>"
)
<<
" BPSys warning score: "
<<
BPSys
.
first
<<
"
\n
"
<<
(
BodyTemp
.
second
?
"<New>"
:
"<Old>"
)
<<
" BodyTemp warning score: "
<<
BodyTemp
.
first
<<
"
\n
******
\n
"
;
return
{
HR
.
first
+
BR
.
first
+
SpO2
.
first
+
BPSys
.
first
+
BodyTemp
.
first
};
}));
//
// Connect low-level agents to the high-level agent.
//
LOG_INFO
(
"Connect low-level agents to the high-level agent."
);
C
->
connectAgents
(
BodyAgent
,
0
,
HRAgent
,
"HR Agent Channel"
);
C
->
connectAgents
(
BodyAgent
,
1
,
BRAgent
,
"BR Agent Channel"
);
C
->
connectAgents
(
BodyAgent
,
2
,
SpO2Agent
,
"SpO2 Agent Channel"
);
C
->
connectAgents
(
BodyAgent
,
3
,
BPSysAgent
,
"BPSys Agent Channel"
);
C
->
connectAgents
(
BodyAgent
,
4
,
BodyTempAgent
,
"BodyTemp Agent Channel"
);
//
// For simulation output, create a logger agent writing the output of the
// high-level agent into a CSV file.
//
LOG_INFO
(
"Create a logger agent."
);
// Create CSV writer.
std
::
ofstream
ScoreCSV
(
ScoreCSVPath
);
csv
::
CSVWriter
<
uint32_t
>
ScoreWriter
(
ScoreCSV
);
// The agent writes each new input value into a CSV file and produces nothing.
AgentHandle
LoggerAgent
=
C
->
createAgent
(
"Logger Agent"
,
DeluxeAgent
::
D
<
unit_t
,
uint32_t
>
(
[
&
ScoreWriter
](
std
::
pair
<
uint32_t
,
bool
>
Score
)
->
Optional
<
unit_t
>
{
if
(
Score
.
second
)
{
// The state of \p ScoreWriter is not checked, expecting good.
ScoreWriter
<<
Score
.
first
;
}
return
{};
}));
//
// Connect the high-level agent to the logger agent.
//parseparse
LOG_INFO
(
"Connect the high-level agent to the logger agent."
);
C
->
connectAgents
(
LoggerAgent
,
0
,
BodyAgent
,
"Body Agent Channel"
);
//
// Do simulation.
//
LOG_INFO
(
"Setting up and performing simulation."
);
//
// Initialize deluxe context for simulation.
//
C
->
initializeSimulation
();
//
// Open CSV files and register them for their corresponding sensors.
//
// Type aliases for iterators.
using
CSVInt
=
csv
::
CSVIterator
<
int32_t
>
;
using
CSVFloat
=
csv
::
CSVIterator
<
float
>
;
//std::ifstream HRCSV(HRCSVPath);
//CSVInt testIt(HRCSV);
/* std::ifstream HRCSV(HRCSVPath);
C->registerSensorValues(HRSensor, CSVInt(HRCSV, 5, false, ';', '\n'), CSVInt()); */
std
::
ifstream
HRCSVOld
(
HRCSVPathOld
);
C
->
registerSensorValues
(
HRSensor
,
CSVInt
(
HRCSVOld
/*, 2*/
),
CSVInt
());
/*
std::ifstream BRCSV(HRCSVPath);
C->registerSensorValues(BRSensor, CSVInt(BRCSV, 4, false, ';', '\n'), CSVInt()); */
std
::
ifstream
SpO2CSV
(
HRCSVPath
);
C
->
registerSensorValues
(
SpO2Sensor
,
CSVInt
(
SpO2CSV
/*, 2, false, ';', '\n'*/
),
CSVInt
());
/*
std::ifstream BPSysCSV(BPSysCSVPath);
C->registerSensorValues(BPSysSensor, CSVInt(BPSysCSV), CSVInt());*/
std
::
ifstream
BodyTempCSV
(
HRCSVPath
);
C
->
registerSensorValues
(
BodyTempSensor
,
CSVFloat
(
BodyTempCSV
/*, 2, false, ';', '\n'*/
),
CSVFloat
());
//
// Simulate.
//
C
->
simulate
(
NumberOfSimulationCycles
);
return
0
;
}
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Sun, May 31, 5:21 PM (18 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
328594
Default Alt Text
main.cpp (11 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment