Skip to content

Commit cee8012

Browse files
authored
TimeframeReader and TimeframeWriter devices (#370)
Initial attempt at TimeframeReader and TimeframeWriter devices. This includes: - Initial plumbing for the devices themselves. - TimeframeParser helper class can be used to read data from an std:istream and create FairMQParts from it. - The test_TimeframeParser example generates a dummy timeframe and pumps it through the TimeframeParser. - FakeTimeframeGeneratorDevice, which can be used to generate timeframes programmatically. - TimeframeValidationTool which can be used to verify the contents of a timeframe file.
1 parent 615e179 commit cee8012

28 files changed

+1119
-23
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,7 @@ compile_commands.json
5858
.idea
5959
.settings
6060
.ycm_extra_conf.py
61+
62+
# Datafiles
63+
*.root
64+
*.o2tf

DataFormats/Headers/include/Headers/SubframeMetadata.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef SUBFRAMEMETADATA_H
22
#define SUBFRAMEMETADATA_H
33

4+
#include <vector>
5+
46
namespace o2 {
57
namespace DataFlow {
68

DataFormats/TimeFrame/include/TimeFrame/TimeFrame.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ namespace o2
99
{
1010
namespace DataFormat
1111
{
12+
13+
using PartPosition = int;
14+
typedef std::pair<o2::Header::DataHeader, PartPosition> IndexElement;
15+
1216
// helper struct so that we can
1317
// stream messages using ROOT
1418
struct MessageSizePair {

Utilities/DataFlow/CMakeLists.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@ set(MODULE_BUCKET_NAME O2DeviceApplication_bucket)
1818
O2_SETUP(NAME ${MODULE_NAME})
1919

2020
set(SRCS
21+
src/FakeTimeframeBuilder.cxx
22+
src/FakeTimeframeGeneratorDevice.cxx
2123
src/HeartbeatSampler.cxx
2224
src/SubframeBuilderDevice.cxx
25+
src/TimeframeParser.cxx
26+
src/TimeframeReaderDevice.cxx
2327
src/TimeframeValidatorDevice.cxx
28+
src/TimeframeWriterDevice.cxx
2429
src/EPNReceiverDevice.cxx
2530
src/FLPSenderDevice.cxx
2631
)
@@ -36,17 +41,23 @@ set(LIBRARY_NAME ${MODULE_NAME})
3641
set(BUCKET_NAME ${MODULE_BUCKET_NAME})
3742

3843
Set(Exe_Names
44+
FakeTimeframeGeneratorDevice
3945
heartbeatSampler
4046
SubframeBuilderDevice
47+
TimeframeReaderDevice
4148
TimeframeValidatorDevice
49+
TimeframeWriterDevice
4250
EPNReceiverDevice
4351
FLPSenderDevice
4452
)
4553

4654
set(Exe_Source
55+
src/runFakeTimeframeGeneratorDevice.cxx
4756
src/runHeartbeatSampler.cxx
4857
src/runSubframeBuilderDevice.cxx
58+
src/runTimeframeReaderDevice.cxx
4959
src/runTimeframeValidatorDevice.cxx
60+
src/runTimeframeWriterDevice.cxx
5061
src/runEPNReceiver.cxx
5162
src/runFLPSender.cxx
5263
)
@@ -64,3 +75,24 @@ ForEach (_file RANGE 0 ${_length})
6475
BUCKET_NAME ${MODULE_BUCKET_NAME}
6576
)
6677
EndForEach (_file RANGE 0 ${_length})
78+
79+
O2_GENERATE_EXECUTABLE(
80+
EXE_NAME TimeframeValidationTool
81+
SOURCES src/TimeframeValidationTool
82+
MODULE_LIBRARY_NAME ${LIBRARY_NAME}
83+
BUCKET_NAME ${MODULE_BUCKET_NAME}
84+
)
85+
86+
set(TEST_SRCS
87+
test/test_TimeframeParser.cxx
88+
)
89+
90+
O2_GENERATE_TESTS(
91+
MODULE_LIBRARY_NAME ${LIBRARY_NAME}
92+
BUCKET_NAME ${BUCKET_NAME}
93+
TEST_SRCS ${TEST_SRCS})
94+
95+
O2_GENERATE_MAN(NAME TimeframeReaderDevice)
96+
O2_GENERATE_MAN(NAME TimeframeWriterDevice)
97+
98+
target_compile_options(test_TimeframeParser PUBLIC -O0 -g)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.\" Manpage for TimeframeReaderDevice.
2+
.TH man 1 "12 May 2017" "1.0" "TimeframeReaderDevice man page"
3+
4+
.SH NAME
5+
6+
TimeframeReaderDevice - read a timeframe from disk
7+
8+
.SH SYNOPSIS
9+
10+
TimeframeReaderDevice --input-file [FILE]
11+
12+
.SH DESCRIPTION
13+
14+
TimeframeReaderDevice will read a Timeframe from the FILE on disk and streams it
15+
via FairMQ
16+
17+
.SH OPTIONS
18+
19+
.TP 5
20+
21+
--input-file [FILE] the file to be streamed
22+
23+
.SH SEE ALSO
24+
25+
TimeframeWriterDevice(1)
26+
27+
.SH BUGS
28+
29+
Lots of bugs
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.\" Manpage for TimeframeWriterDevice.
2+
.TH man 1 "12 May 2017" "1.0" "TimeframeWriterDevice man page"
3+
4+
.SH NAME
5+
6+
TimeframeWriterDevice - writes a timeframe to disk
7+
8+
.SH SYNOPSIS
9+
10+
TimeframeWriterDevice --input-file [FILE]
11+
12+
.SH DESCRIPTION
13+
14+
TimeframeWriterDevice will receive a Timeframe from FairMQ transport and stream
15+
it via FairMQ.
16+
17+
.SH OPTIONS
18+
19+
.TP 5
20+
21+
--output-file [FILE] the file where to stream results
22+
23+
.SH SEE ALSO
24+
25+
TimeframeReaderDevice(1)
26+
27+
.SH BUGS
28+
29+
Lots of bugs
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef DATAFLOW_FAKETIMEFRAMEBUILDER_H_
2+
#define DATAFLOW_FAKETIMEFRAMEBUILDER_H_
3+
4+
#include "Headers/DataHeader.h"
5+
#include <vector>
6+
#include <memory>
7+
#include <functional>
8+
9+
namespace o2 { namespace DataFlow {
10+
11+
struct FakeTimeframeSpec {
12+
const char *origin;
13+
const char *dataDescription;
14+
std::function<void(char *, size_t)> bufferFiller;
15+
size_t bufferSize;
16+
};
17+
18+
/** Generate a timeframe from the provided specification
19+
*/
20+
std::unique_ptr<char[]> fakeTimeframeGenerator(std::vector<FakeTimeframeSpec> &specs, std::size_t &totalSize);
21+
22+
}}
23+
#endif /* DATAFLOW_FAKETIMEFRAMEBUILDER_H_ */
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef ALICEO2_FAKE_TIMEFRAME_GENERATOR_H_
2+
#define ALICEO2_FAKE_TIMEFRAME_GENERATOR_H_
3+
4+
#include "O2Device/O2Device.h"
5+
6+
namespace o2 {
7+
namespace DataFlow {
8+
9+
/// A device which writes to file the timeframes.
10+
class FakeTimeframeGeneratorDevice : public Base::O2Device
11+
{
12+
public:
13+
static constexpr const char* OptionKeyOutputChannelName = "output-channel-name";
14+
static constexpr const char* OptionKeyMaxTimeframes = "max-timeframes";
15+
16+
/// Default constructor
17+
FakeTimeframeGeneratorDevice();
18+
19+
/// Default destructor
20+
~FakeTimeframeGeneratorDevice() override = default;
21+
22+
void InitTask() final;
23+
24+
protected:
25+
/// Overloads the ConditionalRun() method of FairMQDevice
26+
bool ConditionalRun() final;
27+
28+
std::string mOutChannelName;
29+
size_t mMaxTimeframes;
30+
size_t mTimeframeCount;
31+
};
32+
33+
} // namespace DataFlow
34+
} // namespace o2
35+
36+
#endif
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef TIMEFRAME_PARSER_H_
2+
#define TIMEFRAME_PARSER_H_
3+
4+
#include <iosfwd>
5+
#include <functional>
6+
7+
class FairMQParts;
8+
9+
namespace o2 { namespace DataFlow {
10+
11+
/// An helper function which takes a std::istream pointing
12+
/// to a naively persisted timeframe and pumps its parts to
13+
/// FairMQParts, ready to be shipped via FairMQ.
14+
void streamTimeframe(std::istream &stream,
15+
std::function<void(FairMQParts &parts, char *buffer, size_t size)> onAddPart,
16+
std::function<void(FairMQParts &parts)> onSend);
17+
18+
void streamTimeframe(std::ostream &stream, FairMQParts &parts);
19+
20+
} } // end
21+
22+
#endif // TIMEFRAME_PARSER_H
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef ALICEO2_TIMEFRAME_READER_H_
2+
#define ALICEO2_TIMEFRAME_READER_H_
3+
4+
#include "O2Device/O2Device.h"
5+
#include <fstream>
6+
7+
namespace o2 {
8+
namespace DataFlow {
9+
10+
/// A device which writes to file the timeframes.
11+
class TimeframeReaderDevice : public Base::O2Device
12+
{
13+
public:
14+
static constexpr const char* OptionKeyOutputChannelName = "output-channel-name";
15+
static constexpr const char* OptionKeyInputFileName = "input-file";
16+
17+
/// Default constructor
18+
TimeframeReaderDevice();
19+
20+
/// Default destructor
21+
~TimeframeReaderDevice() override = default;
22+
23+
void InitTask() final;
24+
25+
protected:
26+
/// Overloads the ConditionalRun() method of FairMQDevice
27+
bool ConditionalRun() final;
28+
29+
std::string mOutChannelName;
30+
std::string mInFileName;
31+
std::fstream mFile;
32+
std::vector<std::string> mSeen;
33+
};
34+
35+
} // namespace DataFlow
36+
} // namespace o2
37+
38+
#endif

0 commit comments

Comments
 (0)