Skip to content

Commit 0f37fe8

Browse files
authored
Merge cbaa216 into sapling-pr-archive-ktf
2 parents 11b0837 + cbaa216 commit 0f37fe8

7 files changed

Lines changed: 45 additions & 26 deletions

File tree

Detectors/Upgrades/ALICE3/FT3/README.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@ This is top page for the FT3 detector documentation.
1212
Configuration of the endcap disks can be done by setting values for the `FT3Base.layoutFT3` configurable,
1313
the available options are presented in the following Table:
1414

15-
| Option | Comments |
16-
| ---------------------- | ----------------------------------------------------------------------------------------------------------------- |
17-
| `kSegmented` (default) | Currently, only OT disks have realistic implementation, for ML - simple trapezoids |
18-
| `kTrapezoidal` | Simple trapezoisal disks (in both ML and OT), with `FT3Base.nTrapezoidalSegments=32` |
19-
| `kCylindrical` | Simplest possible disks as TGeoTubes (ML and OT), bad for ACTS (wrong digi due to polar coorinates on disk sides) |
15+
| Option | Comments |
16+
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
17+
| `kSegmentedStave` | Segmentation of ML and OT disks: Modules are placed on staggered staves with user defined constants |
18+
| `kSegmentedStaveOTOnly` (default) | Only OT disks are contain staves with modules, ML layers are segmented with strips of modules on front/back |
19+
| `kSegmented` | Segmentation of ML and OT disk with strips of modules of chips on the front and back of a layer |
20+
| `kTrapezoidal` | Simple trapezoidal disks (in both ML and OT), with `FT3Base.nTrapezoidalSegments=32` |
21+
| `kCylindrical` | Simplest possible disks as TGeoTubes (ML and OT), bad for ACTS (wrong digi due to polar coorinates on disk sides) |
22+
23+
Furthermore, there are more options in the case of stave segmentation -- for only OT or both. The user can set to cut the staves exactly on the nominal inner radii (true by default), and outer radii (false by default) of the disks. This exists since (planned) placements of sensors & staves often protrude out of the nominal radii to be more able to cover the nominal disk area. In addition, it is possible to draw reference circles in root for the stave segmented layouts for both the inner (red) and outer (blue) radii. This is off by default, yet can be toggled if the user wants to see how tight the tiling is to the nominal radii -- for visualisation purposes only.
2024

2125
[ [Link to definitions](./base/include/FT3Base/FT3BaseParam.h) ]
2226

23-
For example, a geometry with the endcaps-only can be obtained by
27+
For example, see the command below to generate a geometry with the endcaps only, all layers with the stave geometry, and including reference circles of nominal radii for visualisation.
2428
```bash
2529
o2-sim-serial-run5 -n 1 -g pythia8hi -m FT3 \
26-
--configKeyValues "FT3Base.layoutFT3=kTrapezoidal"
30+
--configKeyValues "FT3Base.layoutFT3=kSegmented; FT3Base.drawReferenceCircles=true"
2731
```
2832

2933
<!-- doxy

Detectors/Upgrades/ALICE3/FT3/simulation/include/FT3Simulation/FT3ModuleConstants.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ namespace o2::ft3::ModuleConstants
4343
*/
4444
// First set all layout constants for the rest of the function
4545
const double single_sensor_width = 2.5;
46-
const double single_sensor_height = 3.2;
46+
const double single_sensor_height = 2.9;
4747
const double inactive_width = 0.2;
4848
const double sensor2x1_gap = 0.02;
4949
const double stackGap = sensor2x1_gap; // gap between 2xN module stacks
@@ -103,7 +103,7 @@ const int SiInactiveColor = kRed;
103103
const int glueColor = kBlue;
104104
const int CuColor = kOrange;
105105
const int kaptonColor = kYellow;
106-
const int carbonColor = kBlack;
106+
const int carbonFiberColor = kGray + 1;
107107

108108
// Struct for stave position configuration (varies between IT/OT)
109109
struct StaveConfig {
@@ -177,7 +177,7 @@ const double x_midpoint_spacing = 4.5;
177177
const std::vector<bool> staveOnFront =
178178
{
179179
1, 0, 1, 0, 1, 0, 1, 0, // L
180-
0, 1, 0, 1, 0, 1, 0, 1 // R
180+
1, 0, 1, 0, 1, 0, 1, 0 // R
181181
};
182182
} // namespace ML_StavePositions
183183

Detectors/Upgrades/ALICE3/FT3/simulation/src/FT3Module.cxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,9 @@ void FT3Module::addStaveVolume(
326326
(volumeName).c_str(),
327327
staveShape,
328328
carbonFiberMed);
329+
staveVolume->SetLineColor(Constants::carbonFiberColor);
330+
staveVolume->SetFillColorAlpha(Constants::carbonFiberColor, 0.4);
331+
329332
TGeoRotation* rot = new TGeoRotation();
330333
rot->RotateX(-90); // lift from xy plane into xz plane
331334
/*

Framework/Core/include/Framework/DataProcessingContext.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "Framework/DataRelayer.h"
1515
#include "Framework/AlgorithmSpec.h"
16+
#include <atomic>
1617
#include <functional>
1718

1819
namespace o2::framework
@@ -33,7 +34,7 @@ struct DataProcessorContext {
3334
DataProcessorContext(DataProcessorContext const&) = delete;
3435
DataProcessorContext() = default;
3536

36-
bool allDone = false;
37+
std::atomic<bool> allDone = false;
3738
/// Latest run number we processed globally for this DataProcessor.
3839
int64_t lastRunNumberProcessed = -1;
3940

@@ -43,7 +44,6 @@ struct DataProcessorContext {
4344

4445
// FIXME: move stuff here from the list below... ;-)
4546
ServiceRegistry* registry = nullptr;
46-
std::vector<DataRelayer::RecordAction> completed;
4747
std::vector<ExpirationHandler> expirationHandlers;
4848
AlgorithmSpec::InitCallback init;
4949
AlgorithmSpec::ProcessCallback statefulProcess;

Framework/Core/include/Framework/StreamContext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#ifndef O2_FRAMEWORK_STREAMCONTEXT_H_
1212
#define O2_FRAMEWORK_STREAMCONTEXT_H_
1313

14+
#include "Framework/DataRelayer.h"
1415
#include "Framework/ServiceHandle.h"
1516
#include "ProcessingContext.h"
1617
#include "ServiceSpec.h"
@@ -64,6 +65,10 @@ struct StreamContext {
6465
// the callback will be called for all of them.
6566
std::vector<ServiceStartStreamHandle> preStartStreamHandles;
6667

68+
/// Per-stream list of actions ready to be dispatched. Populated by
69+
/// getReadyToProcess() and consumed by tryDispatchComputation().
70+
std::vector<DataRelayer::RecordAction> completed;
71+
6772
// Information on wether or not all the required routes have been created.
6873
// This is used to check if the LifetimeTimeframe routes were all created
6974
// for a given iteration.

Framework/Core/src/DataAllocator.cxx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,11 @@ void DataAllocator::adopt(const Output& spec, LifetimeHolder<FragmentToBatch>& f
264264
// get rid of the intermediate tree 2 table object, saving memory.
265265
auto batch = source.finalize();
266266
if (!batch) {
267-
throw std::runtime_error("FragmentToBatch::finalize() returned null RecordBatch");
267+
// Do not throw here: this callback runs from ~LifetimeHolder which may
268+
// execute during stack unwinding (e.g. if fill() failed). Throwing during
269+
// unwinding calls std::terminate.
270+
LOG(error) << "FragmentToBatch::finalize() returned null RecordBatch, skipping serialization";
271+
return;
268272
}
269273
auto mock = std::make_shared<arrow::io::MockOutputStream>();
270274
int64_t expectedSize = 0;

Framework/Core/src/DataProcessingDevice.cxx

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,13 @@ DataProcessingDevice::DataProcessingDevice(RunningDeviceRef running, ServiceRegi
187187
// 99 is to execute DPL callbacks last
188188
this->SubscribeToStateChange("99-dpl", stateWatcher);
189189

190-
// One task for now.
191-
mStreams.resize(1);
192-
mHandles.resize(1);
190+
auto* poolSizeEnv = getenv("DPL_THREADPOOL_SIZE");
191+
// 0 (or unset): synchronous execution on the main thread.
192+
// N > 0: N concurrent async streams; I/O runs on the main thread while
193+
// computation runs on N pool threads.
194+
size_t numStreams = poolSizeEnv ? std::max(0, std::atoi(poolSizeEnv)) : 0;
195+
mStreams.resize(std::max(numStreams, 1UL));
196+
mHandles.resize(std::max(numStreams, 1UL));
193197

194198
ServiceRegistryRef ref{mServiceRegistry};
195199

@@ -1210,10 +1214,8 @@ void DataProcessingDevice::Run()
12101214
O2_SIGNPOST_ID_FROM_POINTER(lid, device, state.loop);
12111215
O2_SIGNPOST_START(device, lid, "device_state", "First iteration of the device loop");
12121216

1213-
bool dplEnableMultithreding = getenv("DPL_THREADPOOL_SIZE") != nullptr;
1214-
if (dplEnableMultithreding) {
1215-
setenv("UV_THREADPOOL_SIZE", "1", 1);
1216-
}
1217+
auto* poolSizeEnv = getenv("DPL_THREADPOOL_SIZE");
1218+
bool dplEnableMultithreding = poolSizeEnv && std::atoi(poolSizeEnv) > 0;
12171219

12181220
while (state.transitionHandling != TransitionHandlingState::Expired) {
12191221
if (state.nextFairMQState.empty() == false) {
@@ -1634,6 +1636,7 @@ void DataProcessingDevice::doPrepare(ServiceRegistryRef ref)
16341636
void DataProcessingDevice::doRun(ServiceRegistryRef ref)
16351637
{
16361638
auto& context = ref.get<DataProcessorContext>();
1639+
auto& streamContext = ref.get<StreamContext>();
16371640
O2_SIGNPOST_ID_FROM_POINTER(dpid, device, &context);
16381641
auto& state = ref.get<DeviceState>();
16391642
auto& spec = ref.get<DeviceSpec const>();
@@ -1642,9 +1645,9 @@ void DataProcessingDevice::doRun(ServiceRegistryRef ref)
16421645
return;
16431646
}
16441647

1645-
context.completed.clear();
1646-
context.completed.reserve(16);
1647-
if (DataProcessingDevice::tryDispatchComputation(ref, context.completed)) {
1648+
streamContext.completed.clear();
1649+
streamContext.completed.reserve(16);
1650+
if (DataProcessingDevice::tryDispatchComputation(ref, streamContext.completed)) {
16481651
state.lastActiveDataProcessor.store(&context);
16491652
}
16501653
DanglingContext danglingContext{*context.registry};
@@ -1658,8 +1661,8 @@ void DataProcessingDevice::doRun(ServiceRegistryRef ref)
16581661
state.lastActiveDataProcessor = &context;
16591662
}
16601663

1661-
context.completed.clear();
1662-
if (DataProcessingDevice::tryDispatchComputation(ref, context.completed)) {
1664+
streamContext.completed.clear();
1665+
if (DataProcessingDevice::tryDispatchComputation(ref, streamContext.completed)) {
16631666
state.lastActiveDataProcessor = &context;
16641667
}
16651668

@@ -1685,7 +1688,7 @@ void DataProcessingDevice::doRun(ServiceRegistryRef ref)
16851688

16861689
bool shouldProcess = DataProcessingHelpers::hasOnlyGenerated(spec) == false;
16871690

1688-
while (DataProcessingDevice::tryDispatchComputation(ref, context.completed) && shouldProcess) {
1691+
while (DataProcessingDevice::tryDispatchComputation(ref, streamContext.completed) && shouldProcess) {
16891692
relayer.processDanglingInputs(context.expirationHandlers, *context.registry, false);
16901693
}
16911694

0 commit comments

Comments
 (0)