Skip to content

Commit e3a6888

Browse files
authored
Merge branch 'AliceO2Group:dev' into new_new_geometry
2 parents b2ab6bf + 1f4567d commit e3a6888

72 files changed

Lines changed: 2905 additions & 651 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.clang-tidy‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ Checks:
1818
- modernize-use-uncaught-exceptions
1919
- readability-braces-around-statements
2020
- -clang-diagnostic-vla-cxx-extension
21+
# Select which of the enabled checks should be reported as errors instead of warnings.
22+
WarningsAsErrors: >-
23+
*,
2124
CheckOptions:
2225
# Naming conventions
2326
readability-identifier-naming.ClassCase: CamelCase

‎.skills/dpl-mcp/SKILL.md‎

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
name: dpl-mcp
3+
description: Inspect a running DPL workflow through the DPL MCP server (Framework/Core/scripts/dpl-mcp-server) — devices and their state, live metrics, logs, signposts, per-mapping memory (smaps), resuming a workflow started with -s. Use when asked to look at, debug or measure a workflow while it runs, locally or on Hyperloop.
4+
---
5+
6+
# DPL MCP server
7+
8+
`Framework/Core/scripts/dpl-mcp-server/dpl_mcp_server.py` is an MCP server
9+
(`FastMCP("DPL Status")`) that talks to the `/status` WebSocket of a running
10+
DPL **driver**. Everything it reports comes from the driver, which already
11+
holds the devices' metrics, logs and pids, so nothing has to be enabled in the
12+
workflow: every driver listens, `-b` or not.
13+
14+
The driver side is `Framework/Core/src/StatusWebSocketHandler.{h,cxx}`; the
15+
header documents the wire protocol. A tool and its driver command are added
16+
together: a command the driver does not know is silently ignored, which the
17+
tool reports as a timeout.
18+
19+
## Setup
20+
21+
Dependencies are `mcp` and `websockets` (`pyproject.toml`, Python ≥ 3.11).
22+
Use a virtualenv next to the script and register the script itself; the server
23+
takes no command-line arguments, workflows are attached at run time with
24+
`connect`:
25+
26+
```sh
27+
cd Framework/Core/scripts/dpl-mcp-server
28+
python3 -m venv .venv && .venv/bin/pip install mcp websockets
29+
claude mcp add dpl -- "$PWD/.venv/bin/python3" "$PWD/dpl_mcp_server.py"
30+
```
31+
32+
Several workflows can be connected at once; each tool takes the `workflow`
33+
name that `connect` returned.
34+
35+
## Attaching to a workflow
36+
37+
- **Local**: `connect(pid=<driver pid>)` or `connect(port=<port>)`.
38+
The driver binds `8080 + pid % 30000` (or `DPL_REMOTE_GUI_PORT`), but moves
39+
to the next free port if that one is taken, so when `pid=` fails take the
40+
port from the driver log: `Driver listening on port: <n>`. The driver pid is
41+
the one without `--id` on its command line.
42+
- **Hyperloop**: `connect_hyperloop(url=https://alimonitor.cern.ch/train-workdir/remote-gui/remote_proxy.html?<token>/<port>)`
43+
for a test that exposes the remote GUI. NOTE: this still targets the old
44+
`ws://localhost:8888` proxy with `HYPERLOOP_TOKEN`; it has to be moved to
45+
the security-proxy before it works again.
46+
47+
## Tools
48+
49+
| Tool | What it does |
50+
|------|--------------|
51+
| `connect`, `connect_hyperloop`, `disconnect`, `list_workflows` | attach / detach workflows |
52+
| `list_devices(workflow)` | name, pid, active, streaming state, device state of every device |
53+
| `list_metrics(workflow, device)` | numeric metrics a device publishes (string/enum ones are left out) |
54+
| `subscribe` / `unsubscribe(workflow, device, metrics)` | the driver pushes a subscribed metric each cycle in which it changed |
55+
| `get_updates(workflow, max_updates)` | drain the buffered metric updates, time-ordered |
56+
| `subscribe_logs` / `unsubscribe_logs(workflow, device)` | stream a device's log lines |
57+
| `get_logs(workflow, max_lines)` | drain the buffered log lines |
58+
| `enable_signpost` / `disable_signpost(workflow, device, streams)` | switch signpost streams on a device (`device=""` for the driver), e.g. `ch.cern.aliceo2.device`, `ch.cern.aliceo2.completion`, `ch.cern.aliceo2.monitoring_service`, `ch.cern.aliceo2.data_processor_context`, `ch.cern.aliceo2.stream_context`; the output arrives in the logs |
59+
| `start_devices(workflow)` | SIGCONT every device of a workflow started with `-s` (stop before device start) |
60+
| `smaps(workflow, device, top)` | memory per mapping, read by the driver from `/proc/<pid>/smaps` (Linux only) |
61+
62+
Updates and logs are buffered by the server between calls and drained by
63+
`get_updates` / `get_logs`, so poll them rather than expecting a push.
64+
65+
## Memory per mapping (`smaps`)
66+
67+
The driver reads `/proc/<pid>/smaps` of the device and returns, per path, kB of
68+
rss, pss, shared/private clean/dirty and swap (unnamed mappings as `[anon]`).
69+
The tool groups them into O2Physics, O2, ROOT, arrow and other libraries,
70+
heap, anon and shm, and lists the `top` paths by PSS.
71+
72+
- Compare **private-dirty**: it is what the device itself costs. PSS splits
73+
shared pages among every process mapping them, so it moves with how many
74+
other jobs on the node use the same libraries.
75+
- It works where an outside reader cannot: Hyperloop tests run as `alitrain`,
76+
and only a process of that user (the driver) may read the devices' smaps.
77+
- Take it while the workflow is processing, to see the working set rather than
78+
what is left after end of stream.
79+
80+
## Typical uses
81+
82+
- Why is a workflow stuck: `list_devices` for the states, then
83+
`subscribe_logs` + `get_logs` on the device whose streaming or device state lags the others
84+
and the `completion` signpost stream to see which inputs a
85+
device is waiting for.
86+
- Throughput or backpressure: `list_metrics`, then `subscribe` to the rate,
87+
size or relayer metrics (e.g. `inputs/relayed/*`, `total_rate_in_mb_s`) and
88+
read `get_updates` over time.
89+
- Where the memory of a device goes: `smaps`.
90+
- Debugging from the start: launch with `-s`, attach, enable signposts /
91+
subscribe to logs, then `start_devices`.

‎CCDB/CMakeLists.txt‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ o2_target_root_dictionary(CCDB
3232
include/CCDB/IdPath.h
3333
include/CCDB/BasicCCDBManager.h
3434
include/CCDB/CCDBTimeStampUtils.h
35-
include/CCDB/CCDBQuery.h
36-
include/CCDB/CCDBDownloader.h)
35+
include/CCDB/CCDBQuery.h)
3736

3837
o2_add_executable(inspectccdbfile
3938
COMPONENT_NAME ccdb

‎CODEOWNERS‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
/DataFormats/Detectors/TPC @davidrohr @wiechula @shahor02
4343
/DataFormats/Detectors/TRD @f3sch @bazinski @wille10
4444
/DataFormats/Detectors/Upgrades @mconcas
45+
/DataFormats/Detectors/Upgrades/ALICE3 @mconcas @njacazio @fcolamar @pbutti
4546
/DataFormats/Detectors/Upgrades/ITS3 @fgrosa @arossi81
4647
/DataFormats/Detectors/ZDC @coppedis @cortesep
4748

‎DataFormats/Detectors/GlobalTracking/include/DataFormatsGlobalTracking/RecoContainer.h‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ class Decay3Body;
172172
class Decay3BodyIndex;
173173
class StrangeTrack;
174174
class TrackCosmics;
175+
struct TrackCosmicsExtended;
176+
struct CosmicsTFInfo;
177+
struct TFIDInfo;
175178
class GlobalFwdTrack;
176179
class MatchInfoFwd;
177180
class TrackMCHMID;
@@ -253,6 +256,7 @@ struct DataRequest {
253256
void requestCPVClusters(bool mc);
254257

255258
void requestCoscmicTracks(bool mc);
259+
void requestCosmicExtTracks(bool mc); // MC is not supported, argument is for uniformity
256260

257261
void requestPrimaryVertices(bool mc);
258262
void requestPrimaryVerticesTMP(bool mc);
@@ -324,6 +328,9 @@ struct RecoContainer {
324328
// slots for cosmics
325329
enum CosmicsSlots { COSM_TRACKS,
326330
COSM_TRACKS_MC,
331+
COSMEXT_TRACKS, // extended cosmics (with clusters), no MC
332+
COSMEXT_TFINFO, // per-TF info of the extended cosmics
333+
COSMEXT_TFID, // TFIDInfo of the extended cosmics
327334
NCOSMSLOTS };
328335

329336
// slots to register ITS/MFT clusters data (per layer, or all layers together in the slot 0)
@@ -371,6 +378,7 @@ struct RecoContainer {
371378
std::unique_ptr<const std::vector<o2::MCCompLabel>> mcMIDTracks;
372379
o2::ctp::LumiInfo mCTPLumi;
373380

381+
std::shared_ptr<const void> cosmExtHolder[3]; // owners of the extended cosmics, TF info and TFID objects deserialized from the messages
374382
gsl::span<const unsigned char> clusterShMapTPC; ///< externally set TPC clusters sharing map
375383
gsl::span<const unsigned int> occupancyMapTPC; ///< externally set TPC clusters occupancy map
376384

@@ -429,6 +437,7 @@ struct RecoContainer {
429437
void addEMCALCells(o2::framework::ProcessingContext& pc, bool mc);
430438

431439
void addCosmicTracks(o2::framework::ProcessingContext& pc, bool mc);
440+
void addCosmicExtTracks(o2::framework::ProcessingContext& pc, bool mc);
432441

433442
void addPVertices(o2::framework::ProcessingContext& pc, bool mc);
434443
void addPVerticesTMP(o2::framework::ProcessingContext& pc, bool mc);
@@ -755,6 +764,12 @@ struct RecoContainer {
755764
auto getCosmicTracks() const { return cosmPool.getSpan<o2::dataformats::TrackCosmics>(COSM_TRACKS); }
756765
auto getCosmicTrackMCLabels() const { return cosmPool.getSpan<o2::MCCompLabel>(COSM_TRACKS_MC); }
757766

767+
// Extended cosmic tracks (with clusters); the user must include DataFormatsGlobalTracking/TrackCosmicsExtended.h and CommonDataFormat/TFIDInfo.h
768+
const o2::dataformats::TrackCosmicsExtended& getCosmicExtTrack(int i) const { return cosmPool.get_as<o2::dataformats::TrackCosmicsExtended>(COSMEXT_TRACKS, i); }
769+
auto getCosmicExtTracks() const { return cosmPool.getSpan<o2::dataformats::TrackCosmicsExtended>(COSMEXT_TRACKS); }
770+
const o2::dataformats::CosmicsTFInfo& getCosmicExtTFInfo() const { return cosmPool.get_as<o2::dataformats::CosmicsTFInfo>(COSMEXT_TFINFO, 0); }
771+
const o2::dataformats::TFIDInfo& getCosmicExtTFID() const { return cosmPool.get_as<o2::dataformats::TFIDInfo>(COSMEXT_TFID, 0); }
772+
758773
// IRFrames where ITS was reconstructed and tracks were seen (e.g. sync.w-flow mult. selection)
759774
auto getIRFramesITS() const { return getSpan<o2::dataformats::IRFrame>(GTrackID::ITS, VARIA); }
760775

‎DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include "ReconstructionDataFormats/VtxTrackIndex.h"
3232
#include "ReconstructionDataFormats/VtxTrackRef.h"
3333
#include "ReconstructionDataFormats/TrackCosmics.h"
34+
#include "DataFormatsGlobalTracking/TrackCosmicsExtended.h"
35+
#include "CommonDataFormat/TFIDInfo.h"
3436
#include "ReconstructionDataFormats/TrackMCHMID.h"
3537
#include "DataFormatsITSMFT/TrkClusRef.h"
3638
#include "DataFormatsITSMFT/TopologyDictionary.h"
@@ -429,6 +431,17 @@ void DataRequest::requestCoscmicTracks(bool mc)
429431
requestMap["Cosmics"] = mc;
430432
}
431433

434+
void DataRequest::requestCosmicExtTracks(bool mc)
435+
{
436+
addInput({"cosmicsExt", "GLO", "COSMFULL", 0, Lifetime::Timeframe});
437+
addInput({"cosmicsExtTF", "GLO", "COSMFULLTF", 0, Lifetime::Timeframe});
438+
addInput({"cosmicsExtTFID", "GLO", "COSMFULLTFID", 0, Lifetime::Timeframe});
439+
if (mc) {
440+
LOG(error) << "Extended cosmics do not support MC truth";
441+
}
442+
requestMap["CosmicsExt"] = false;
443+
}
444+
432445
void DataRequest::requestPrimaryVertices(bool mc)
433446
{
434447
addInput({"pvtx", "GLO", "PVTX", 0, Lifetime::Timeframe});
@@ -825,6 +838,11 @@ void RecoContainer::collectData(ProcessingContext& pc, const DataRequest& reques
825838
addCosmicTracks(pc, req->second);
826839
}
827840

841+
req = reqMap.find("CosmicsExt");
842+
if (req != reqMap.end()) {
843+
addCosmicExtTracks(pc, req->second);
844+
}
845+
828846
req = reqMap.find("PVertex");
829847
if (req != reqMap.end()) {
830848
addPVertices(pc, req->second);
@@ -903,6 +921,27 @@ void RecoContainer::addPVerticesTMP(ProcessingContext& pc, bool mc)
903921
}
904922
}
905923

924+
//____________________________________________________________
925+
void RecoContainer::addCosmicExtTracks(ProcessingContext& pc, bool mc)
926+
{
927+
using o2::dataformats::CosmicsTFInfo;
928+
using o2::dataformats::TFIDInfo;
929+
using o2::dataformats::TrackCosmicsExtended;
930+
// the messages are ROOT-serialized, keep the deserialized objects alive until the next TF
931+
std::shared_ptr<const std::vector<TrackCosmicsExtended>> cosm = pc.inputs().get<std::vector<TrackCosmicsExtended>*>("cosmicsExt");
932+
std::shared_ptr<const CosmicsTFInfo> tfInfo = pc.inputs().get<CosmicsTFInfo*>("cosmicsExtTF");
933+
std::shared_ptr<const TFIDInfo> tfID = pc.inputs().get<TFIDInfo*>("cosmicsExtTFID");
934+
cosmPool.registerContainer(*cosm, COSMEXT_TRACKS);
935+
cosmPool.registerContainer(gsl::span<const CosmicsTFInfo>(tfInfo.get(), 1), COSMEXT_TFINFO);
936+
cosmPool.registerContainer(gsl::span<const TFIDInfo>(tfID.get(), 1), COSMEXT_TFID);
937+
cosmExtHolder[0] = std::move(cosm);
938+
cosmExtHolder[1] = std::move(tfInfo);
939+
cosmExtHolder[2] = std::move(tfID);
940+
if (mc) {
941+
LOG(error) << "Extended cosmics do not support MC truth";
942+
}
943+
}
944+
906945
//____________________________________________________________
907946
void RecoContainer::addCosmicTracks(ProcessingContext& pc, bool mc)
908947
{

‎DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/include/DataFormatsTRKFT3/Digit.h‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@ namespace o2::trkft3
2222
class Digit
2323
{
2424
public:
25-
Digit(UShort_t chipindex = 0, UShort_t row = 0, UShort_t col = 0, Int_t charge = 0);
25+
Digit(UShort_t chipindex = 0, UShort_t row = 0, UShort_t col = 0, Int_t charge = 0, float toa = 0);
2626
~Digit() = default;
2727

2828
UShort_t getChipIndex() const { return mChipIndex; }
2929
UShort_t getColumn() const { return mCol; }
3030
UShort_t getRow() const { return mRow; }
3131
Int_t getCharge() const { return mCharge; }
32+
float getTimeOfArrival() const { return mToA; }
3233

3334
void setChipIndex(UShort_t index) { mChipIndex = index; }
3435
void setPixelIndex(UShort_t row, UShort_t col)
@@ -38,6 +39,7 @@ class Digit
3839
}
3940
void setCharge(Int_t charge) { mCharge = charge < USHRT_MAX ? charge : USHRT_MAX; }
4041
void addCharge(int charge) { setCharge(charge + int(mCharge)); }
42+
void setToA(float toa) { mToA = toa; }
4143

4244
std::ostream& print(std::ostream& output) const;
4345
friend std::ostream& operator<<(std::ostream& output, const Digit& digi)
@@ -51,8 +53,9 @@ class Digit
5153
UShort_t mRow = 0;
5254
UShort_t mCol = 0;
5355
UShort_t mCharge = 0;
56+
float mToA = 0; // TimeOfArrival, set to float at the moment. TODO: implement correctly the size https://indico.cern.ch/event/1724141/contributions/7252329/attachments/3336751/5980668/data_throughput_estimation.pdf
5457

55-
ClassDefNV(Digit, 1);
58+
ClassDefNV(Digit, 2);
5659
};
5760

5861
} // namespace o2::trkft3

‎DataFormats/Detectors/Upgrades/ALICE3/TRKFT3/common/src/Digit.cxx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ ClassImp(o2::trkft3::Digit);
1616

1717
using namespace o2::trkft3;
1818

19-
Digit::Digit(UShort_t chipindex, UShort_t row, UShort_t col, Int_t charge)
19+
Digit::Digit(UShort_t chipindex, UShort_t row, UShort_t col, Int_t charge, float toa)
2020
: mChipIndex(chipindex), mRow(row), mCol(col)
2121
{
2222
setCharge(charge);
23+
setToA(toa);
2324
}
2425

2526
std::ostream& Digit::print(std::ostream& output) const
2627
{
27-
output << "TRKFT3Digit chip [" << mChipIndex << "] R:" << mRow << " C:" << mCol << " Q: " << mCharge;
28+
output << "TRKFT3Digit chip [" << mChipIndex << "] R:" << mRow << " C:" << mCol << " Q: " << mCharge << " ToA: " << mToA;
2829
return output;
2930
}

0 commit comments

Comments
 (0)