Skip to content

Commit bff11fb

Browse files
committed
SimReader device + TPC digitization using DPL
This commit provides a step/initial components towards the processing of simulated hits using the O2 Data Processing Layer. The main components are a) SimReader: A device which is supposed to read and preprocess hit files generated by detector simulation. Main tasks are - reading hits from background + signal simulations - assigning/sampling collision times based on bunch-crossing parameters - sampling of background/signal scenarios - propagating generated information to consuming devices (such as digitization) b) TPCDriftTimeDigitizer: A device doing (sectorwise) digitization for the TPC. The digitization is done in units of drift times which makes the pileup handling convenient. What this PR achieves: - Demonstration of a new parallel workflow using a realistic task from simulation Note that these components are still under heavy development. The features, names as well as file locations are still likely to change.
1 parent 4d87865 commit bff11fb

14 files changed

Lines changed: 542 additions & 6 deletions

Detectors/TPC/simulation/include/TPCSimulation/Point.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class ElementalHit {
3030
float GetX() const { return mPos.X(); }
3131
float GetY() const { return mPos.Y(); }
3232
float GetZ() const { return mPos.Z(); }
33+
const ::Point3D<float>& getPos() const { return mPos; }
3334
float GetEnergyLoss() const { return mELoss; }
3435
float GetTime() const { return mTime; }
3536

Detectors/TPC/simulation/src/DigitizerTask.cxx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ DigitizerTask::DigitizerTask(int sectorid)
5555
DigitizerTask::~DigitizerTask()
5656
{
5757
delete mDigitizer;
58-
delete mDigitsArray;
59-
delete mDigitsDebugArray;
58+
// We need to clarify the ownsership of these potentially external containers
59+
// and reenable the cleanup
60+
// delete mDigitsArray;
61+
// delete mDigitsDebugArray;
6062
}
6163

6264
InitStatus DigitizerTask::Init()

Steer/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ O2_GENERATE_TESTS(
2828
BUCKET_NAME ${BUCKET_NAME}
2929
TEST_SRCS ${TEST_SRCS}
3030
)
31+
32+
add_subdirectory(DigitizerWorkflow)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright CERN and copyright holders of ALICE O2. This software is
2+
# distributed under the terms of the GNU General Public License v3 (GPL
3+
# Version 3), copied verbatim in the file "COPYING".
4+
#
5+
# See https://alice-o2.web.cern.ch/ for full licensing information.
6+
#
7+
# In applying this license CERN does not waive the privileges and immunities
8+
# granted to it by virtue of its status as an Intergovernmental Organization
9+
# or submit itself to any jurisdiction.
10+
11+
set(MODULE_NAME "DigitizerWorkflow")
12+
set(MODULE_BUCKET_NAME run_bucket)
13+
14+
O2_SETUP(NAME ${MODULE_NAME})
15+
16+
## TODO: feature of macro, it deletes the variables we pass to it, set them again
17+
## this has to be fixed in the macro implementation
18+
set(BUCKET_NAME ${MODULE_BUCKET_NAME})
19+
20+
O2_GENERATE_EXECUTABLE(
21+
EXE_NAME digitizer-workflow
22+
23+
SOURCES
24+
src/SimpleDigitizerWorkflow.cxx
25+
src/SimReaderSpec.cxx
26+
src/CollisionTimePrinter.cxx
27+
src/TPCDriftTimeDigitizerSpec.cxx
28+
29+
BUCKET_NAME ${MODULE_BUCKET_NAME}
30+
)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#include "CollisionTimePrinter.h"
12+
#include <Steer/InteractionSampler.h>
13+
#include "Headers/DataHeader.h"
14+
15+
#include "Framework/DataProcessorSpec.h"
16+
#include "Framework/DataRefUtils.h"
17+
#include "Headers/DataHeader.h"
18+
#include "Framework/Lifetime.h"
19+
#include "Framework/ControlService.h"
20+
#include "Steer/HitProcessingManager.h"
21+
#include <FairMQLogger.h>
22+
#include <TMessage.h> // object serialization
23+
#include <memory> // std::unique_ptr
24+
#include <cstring> // memcpy
25+
#include <string> // std::string
26+
27+
using namespace o2::framework;
28+
using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType;
29+
namespace o2
30+
{
31+
namespace steer
32+
{
33+
34+
// a very simple DataProcessor consuming data sent
35+
// from the SimReader
36+
// mainly here for debugging/demonstration
37+
DataProcessorSpec getCollisionTimePrinter(int channel)
38+
{
39+
// set up the processing function
40+
41+
// init function return a lambda taking a ProcessingContext
42+
auto doIt = [](ProcessingContext& pc) {
43+
std::cout << " ######### ";
44+
45+
// access data
46+
auto dataref = pc.inputs().get("input");
47+
auto header = o2::header::get<const o2::header::DataHeader*>(dataref.header);
48+
LOG(INFO) << "PAYLOAD SIZE " << header->payloadSize;
49+
50+
const auto context = pc.inputs().get<o2::steer::RunContext>("input");
51+
// auto view = DataRefUtils::as<o2::MCInteractionRecord>(dataref);
52+
auto view = context->getEventRecords();
53+
LOG(INFO) << "GOT " << view.size() << "times";
54+
int counter = 0;
55+
for (auto& collrecord : view) {
56+
LOG(INFO) << "TIME " << counter++ << " : " << collrecord.timeNS;
57+
}
58+
pc.services().get<ControlService>().readyToQuit(false);
59+
};
60+
61+
return DataProcessorSpec{ /*ID*/ "CollTimePrinter",
62+
/*INPUT CHANNELS*/ Inputs{ InputSpec{ "input", "SIM", "EVENTTIMES",
63+
static_cast<SubSpecificationType>(channel),
64+
Lifetime::Timeframe } },
65+
/*OUTPUT CHANNELS*/ Outputs{},
66+
/* ALGORITHM */
67+
AlgorithmSpec(doIt),
68+
/* OPTIONS */
69+
Options{} };
70+
}
71+
}
72+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#ifndef STEER_DIGITIZERWORKFLOW_SRC_COLLISIONTIMEPRINTER_H_
12+
#define STEER_DIGITIZERWORKFLOW_SRC_COLLISIONTIMEPRINTER_H_
13+
14+
#include "Framework/DataProcessorSpec.h"
15+
16+
namespace o2
17+
{
18+
namespace steer
19+
{
20+
o2::framework::DataProcessorSpec getCollisionTimePrinter(int subchannel);
21+
}
22+
}
23+
24+
#endif /* STEER_DIGITIZERWORKFLOW_SRC_COLLISIONTIMEPRINTER_H_ */
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#include "SimReaderSpec.h"
12+
13+
#include "Framework/DataProcessorSpec.h"
14+
#include "Framework/DataRefUtils.h"
15+
#include "Framework/ControlService.h"
16+
#include "Framework/Lifetime.h"
17+
#include "Headers/DataHeader.h"
18+
#include "Steer/HitProcessingManager.h"
19+
#include <FairMQLogger.h>
20+
#include <TMessage.h> // object serialization
21+
#include <memory> // std::unique_ptr
22+
#include <cstring> // memcpy
23+
#include <string> // std::string
24+
#include <cassert>
25+
#include <chrono>
26+
#include <thread>
27+
28+
using namespace o2::framework;
29+
using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType;
30+
namespace o2
31+
{
32+
namespace steer
33+
{
34+
DataProcessorSpec getSimReaderSpec(int fanoutsize)
35+
{
36+
auto doit = [fanoutsize](ProcessingContext& pc) {
37+
auto& mgr = steer::HitProcessingManager::instance();
38+
auto eventrecords = mgr.getRunContext().getEventRecords();
39+
const auto& context = mgr.getRunContext();
40+
41+
// counter to make sure we are sending the data only once
42+
static int counter = 0;
43+
if (counter++ == 0) {
44+
// sleep(10);
45+
LOG(INFO) << "SENDING " << eventrecords.size() << " records";
46+
47+
for (int subchannel = 0; subchannel < fanoutsize; ++subchannel) {
48+
pc.outputs().snapshot(
49+
Output{ "SIM", "EVENTTIMES", static_cast<SubSpecificationType>(subchannel), Lifetime::Timeframe }, context);
50+
}
51+
52+
// do this only one
53+
pc.services().get<ControlService>().readyToQuit(false);
54+
}
55+
};
56+
57+
// init function return a lambda taking a ProcessingContext
58+
auto initIt = [doit](InitContext& ctx) {
59+
// initialize fundamental objects
60+
auto& mgr = steer::HitProcessingManager::instance();
61+
mgr.addInputFile(ctx.options().get<std::string>("simFile").c_str());
62+
mgr.setupRun();
63+
64+
LOG(INFO) << "Initializing Spec ... have " << mgr.getRunContext().getEventRecords().size() << " times ";
65+
return doit;
66+
};
67+
68+
std::vector<OutputSpec> outputs;
69+
for (int subchannel = 0; subchannel < fanoutsize; ++subchannel) {
70+
outputs.emplace_back(
71+
OutputSpec{ "SIM", "EVENTTIMES", static_cast<SubSpecificationType>(subchannel), Lifetime::Timeframe });
72+
}
73+
74+
return DataProcessorSpec{ /*ID*/ "SimReader",
75+
/*INPUT CHANNELS*/ Inputs{}, outputs,
76+
/* ALGORITHM */
77+
AlgorithmSpec{ initIt },
78+
/* OPTIONS */
79+
Options{ { "simFile", VariantType::String, "o2sim.root", { "Sim input filename" } } } };
80+
}
81+
}
82+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#ifndef O2_STEER_SIMREADERSPEC_H
12+
#define O2_STEER_SIMREADERSPEC_H
13+
14+
#include "Framework/DataProcessorSpec.h"
15+
16+
namespace o2
17+
{
18+
namespace steer
19+
{
20+
o2::framework::DataProcessorSpec getSimReaderSpec(int fanoutsize);
21+
}
22+
}
23+
24+
#endif // O2_STEER_SIMREADERSPEC_H
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#include "Framework/WorkflowSpec.h"
12+
#include "Framework/runDataProcessing.h"
13+
14+
#include "SimReaderSpec.h"
15+
#include "CollisionTimePrinter.h"
16+
17+
// for TPC
18+
#include "TPCDriftTimeDigitizerSpec.h"
19+
20+
using namespace o2::framework;
21+
22+
/// This function is required to be implemented to define the workflow
23+
/// specifications
24+
void defineDataProcessing(WorkflowSpec& specs)
25+
{
26+
specs.clear();
27+
28+
int fanoutsize = 0;
29+
30+
//
31+
// specs.emplace_back(o2::steer::getCollisionTimePrinter(fanoutsize++));
32+
33+
// parallely processing the first 6 TPC sectors
34+
for (int s = 0; s < 6; ++s) {
35+
// probably a parallel construct can be used here
36+
specs.emplace_back(o2::steer::getTPCDriftTimeDigitizer(s, fanoutsize++));
37+
}
38+
39+
specs.emplace_back(o2::steer::getSimReaderSpec(fanoutsize));
40+
}

0 commit comments

Comments
 (0)