Skip to content

Commit 3d5affd

Browse files
committed
Add FT0 CTF reading and writing
* Rename and move FT0-related workflows/specs from FIT/workflow to FIT/FT0/workflow * Add separate FT0 digits reader workflow * CTF class for FT0, encoder/decoder and reader/writer
1 parent d741ae2 commit 3d5affd

41 files changed

Lines changed: 976 additions & 260 deletions

Some content is hidden

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

DataFormats/Detectors/FIT/FT0/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ o2_add_library(DataFormatsFT0
1414
SOURCES src/ChannelData.cxx
1515
SOURCES src/RecPoints.cxx
1616
SOURCES src/RawEventData.cxx
17+
src/CTF.cxx
1718
PUBLIC_LINK_LIBRARIES O2::CommonDataFormat O2::Headers
1819
O2::SimulationDataFormat O2::FT0Base
1920
)
@@ -26,4 +27,5 @@ o2_target_root_dictionary(DataFormatsFT0
2627
include/DataFormatsFT0/MCLabel.h
2728
include/DataFormatsFT0/HitType.h
2829
include/DataFormatsFT0/RawEventData.h
29-
include/DataFormatsFT0/LookUpTable.h )
30+
include/DataFormatsFT0/LookUpTable.h
31+
include/DataFormatsFT0/CTF.h)
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
/// \file CTF.h
12+
/// \author ruben.shahoyan@cern.ch
13+
/// \brief Definitions for FT0 CTF data
14+
15+
#ifndef O2_FT0_CTF_H
16+
#define O2_FT0_CTF_H
17+
18+
#include <vector>
19+
#include <Rtypes.h>
20+
#include "DetectorsCommonDataFormats/EncodedBlocks.h"
21+
22+
namespace o2
23+
{
24+
namespace ft0
25+
{
26+
27+
/// Header for a single CTF
28+
struct CTFHeader {
29+
uint32_t nTriggers = 0; /// number of truggers in TF
30+
uint32_t firstOrbit = 0; /// 1st orbit of TF
31+
uint16_t firstBC = 0; /// 1st BC of TF
32+
33+
ClassDefNV(CTFHeader, 1);
34+
};
35+
36+
/// Intermediate, compressed but not yet entropy-encoded digits
37+
struct CompressedDigits {
38+
39+
CTFHeader header;
40+
41+
// trigger data
42+
std::vector<uint8_t> trigger; // trigger bits
43+
std::vector<uint16_t> bcInc; // increment in BC if the same orbit, otherwise abs bc
44+
std::vector<uint32_t> orbitInc; // increment in orbit
45+
std::vector<uint8_t> nChan; // number of fired channels
46+
47+
// channel data
48+
std::vector<uint8_t> idChan; // channels ID: 1st on absolute, then increment
49+
std::vector<int16_t> cfdTime; // CFD time
50+
std::vector<uint32_t> qtcAmpl; // Amplitude
51+
std::vector<uint8_t> qtc; // QTC
52+
53+
CompressedDigits() = default;
54+
55+
void clear();
56+
57+
ClassDefNV(CompressedDigits, 1);
58+
};
59+
60+
/// wrapper for the Entropy-encoded clusters of the TF
61+
struct CTF : public o2::ctf::EncodedBlocks<CTFHeader, 8, uint32_t> {
62+
63+
static constexpr size_t N = getNBlocks();
64+
enum Slots {
65+
BLC_trigger, // trigger bits
66+
BLC_bcInc, // increment in BC
67+
BLC_orbitInc, // increment in orbit
68+
BLC_nChan, // number of fired channels
69+
BLC_idChan, // channels ID: 1st on absolute, then increment
70+
BLC_qtc, // QTC
71+
BLC_cfdTime, // CFD time
72+
BLC_qtcAmpl
73+
}; // Amplitude
74+
75+
ClassDefNV(CTF, 1);
76+
};
77+
78+
} // namespace ft0
79+
} // namespace o2
80+
81+
#endif

DataFormats/Detectors/FIT/FT0/include/DataFormatsFT0/Digit.h

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ struct Triggers {
3636
bitVertex,
3737
bitCen,
3838
bitSCen };
39-
uint8_t triggersignals; // T0 trigger signals
40-
int8_t nChanA; // number of faired channels A side
41-
int8_t nChanC; // number of faired channels A side
42-
int32_t amplA; // sum amplitude A side
43-
int32_t amplC; // sum amplitude C side
44-
int16_t timeA; // average time A side
45-
int16_t timeC; // average time C side
39+
uint8_t triggersignals = 0; // T0 trigger signals
40+
int8_t nChanA = 0; // number of fired channels A side
41+
int8_t nChanC = 0; // number of fired channels A side
42+
int32_t amplA = -1000; // sum amplitude A side
43+
int32_t amplC = -1000; // sum amplitude C side
44+
int16_t timeA = -1000; // average time A side
45+
int16_t timeC = -1000; // average time C side
4646
Triggers() = default;
4747
Triggers(uint8_t signals, int8_t chanA, int8_t chanC, int32_t aamplA, int32_t aamplC, int16_t atimeA, int16_t atimeC)
4848
{
@@ -54,11 +54,11 @@ struct Triggers {
5454
timeA = atimeA;
5555
timeC = atimeC;
5656
}
57-
bool getOrA() { return (triggersignals & (1 << bitA)) != 0; }
58-
bool getOrC() { return (triggersignals & (1 << bitC)) != 0; }
59-
bool getVertex() { return (triggersignals & (1 << bitVertex)) != 0; }
60-
bool getCen() { return (triggersignals & (1 << bitCen)) != 0; }
61-
bool getSCen() { return (triggersignals & (1 << bitSCen)) != 0; }
57+
bool getOrA() const { return (triggersignals & (1 << bitA)) != 0; }
58+
bool getOrC() const { return (triggersignals & (1 << bitC)) != 0; }
59+
bool getVertex() const { return (triggersignals & (1 << bitVertex)) != 0; }
60+
bool getCen() const { return (triggersignals & (1 << bitCen)) != 0; }
61+
bool getSCen() const { return (triggersignals & (1 << bitSCen)) != 0; }
6262

6363
void setTriggers(Bool_t isA, Bool_t isC, Bool_t isVrtx, Bool_t isCnt, Bool_t isSCnt, int8_t chanA, int8_t chanC, int32_t aamplA,
6464
int32_t aamplC, int16_t atimeA, int16_t atimeC)
@@ -74,13 +74,11 @@ struct Triggers {
7474
void cleanTriggers()
7575
{
7676
triggersignals = 0;
77-
nChanA = nChanC = -1;
77+
nChanA = nChanC = 0;
7878
amplA = amplC = -1000;
7979
timeA = timeC = -1000;
8080
}
8181

82-
Triggers getTriggers();
83-
8482
ClassDefNV(Triggers, 1);
8583
};
8684

@@ -90,7 +88,7 @@ struct Digit {
9088
o2::InteractionRecord mIntRecord; // Interaction record (orbit, bc)
9189
int mEventID;
9290
Digit() = default;
93-
Digit(int first, int ne, o2::InteractionRecord iRec, Triggers chTrig, int event)
91+
Digit(int first, int ne, const o2::InteractionRecord& iRec, const Triggers& chTrig, int event)
9492
{
9593
ref.setFirstEntry(first);
9694
ref.setEntries(ne);
@@ -100,7 +98,7 @@ struct Digit {
10098
}
10199
uint32_t getOrbit() const { return mIntRecord.orbit; }
102100
uint16_t getBC() const { return mIntRecord.bc; }
103-
Triggers getTriggers() { return mTriggers; }
101+
Triggers getTriggers() const { return mTriggers; }
104102
int getEventID() const { return mEventID; }
105103
o2::InteractionRecord getIntRecord() { return mIntRecord; };
106104
gsl::span<const ChannelData> getBunchChannelData(const gsl::span<const ChannelData> tfdata) const;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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 <stdexcept>
12+
#include <cstring>
13+
#include "Framework/Logger.h"
14+
#include "DataFormatsFT0/CTF.h"
15+
16+
using namespace o2::ft0;
17+
18+
///________________________________
19+
void CompressedDigits::clear()
20+
{
21+
trigger.clear();
22+
bcInc.clear();
23+
orbitInc.clear();
24+
nChan.clear();
25+
26+
idChan.clear();
27+
qtc.clear();
28+
cfdTime.clear();
29+
qtcAmpl.clear();
30+
31+
header.nTriggers = 0;
32+
header.firstOrbit = 0;
33+
header.firstBC = 0;
34+
}

DataFormats/Detectors/FIT/FT0/src/DataFormatsFT0LinkDef.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,9 @@
3939
#pragma link C++ class o2::ft0::EventData + ;
4040
#pragma link C++ class o2::ft0::Topo + ;
4141

42+
#pragma link C++ class o2::ft0::CTFHeader + ;
43+
#pragma link C++ class o2::ft0::CompressedDigits + ;
44+
#pragma link C++ class o2::ft0::CTF + ;
45+
#pragma link C++ class o2::ctf::EncodedBlocks < o2::ft0::CTFHeader, 8, uint32_t> + ;
46+
4247
#endif

Detectors/CTF/workflow/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ o2_add_library(CTFWorkflow
1818
O2::DataFormatsParameters
1919
O2::ITSMFTWorkflow
2020
O2::TPCWorkflow
21+
O2::FT0Workflow
2122
O2::Algorithm
2223
O2::CommonUtils)
2324

Detectors/CTF/workflow/src/CTFReaderSpec.cxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "DetectorsCommonDataFormats/CTFHeader.h"
2626
#include "DataFormatsITSMFT/CTF.h"
2727
#include "DataFormatsTPC/CTF.h"
28+
#include "DataFormatsFT0/CTF.h"
2829
#include "Algorithm/RangeTokenizer.h"
2930

3031
using namespace o2::framework;
@@ -125,6 +126,13 @@ void CTFReaderSpec::run(ProcessingContext& pc)
125126
setFirstTFOrbit(det.getName());
126127
}
127128

129+
det = DetID::FT0;
130+
if (detsTF[det]) {
131+
auto& bufVec = pc.outputs().make<std::vector<o2::ctf::BufferType>>({det.getName()}, sizeof(o2::ft0::CTF));
132+
o2::ft0::CTF::readFromTree(bufVec, *(tree.get()), det.getName());
133+
setFirstTFOrbit(det.getName());
134+
}
135+
128136
mTimer.Stop();
129137
LOG(INFO) << "Read CTF " << inputFile << " in " << mTimer.CpuTime() - cput << " s";
130138

Detectors/CTF/workflow/src/CTFWriterSpec.cxx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "DetectorsCommonDataFormats/NameConf.h"
2626
#include "DataFormatsITSMFT/CTF.h"
2727
#include "DataFormatsTPC/CTF.h"
28+
#include "DataFormatsFT0/CTF.h"
2829

2930
using namespace o2::framework;
3031

@@ -95,6 +96,16 @@ void CTFWriterSpec::run(ProcessingContext& pc)
9596
header.detectors.set(det);
9697
}
9798

99+
det = DetID::FT0;
100+
if (isPresent(det) && pc.inputs().isValid(det.getName())) {
101+
auto ctfBuffer = pc.inputs().get<gsl::span<o2::ctf::BufferType>>(det.getName());
102+
const auto ctfImage = o2::ft0::CTF::getImage(ctfBuffer.data());
103+
LOG(INFO) << "CTF for " << det.getName();
104+
ctfImage.print();
105+
ctfImage.appendToTree(ctfTree, det.getName());
106+
header.detectors.set(det);
107+
}
108+
98109
appendToTree(ctfTree, "CTFHeader", header);
99110

100111
ctfTree.SetEntries(1);

Detectors/CTF/workflow/src/ctf-reader-workflow.cxx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
// Specific detectors specs
2323
#include "ITSMFTWorkflow/EntropyDecoderSpec.h"
2424
#include "TPCWorkflow/EntropyDecoderSpec.h"
25+
#include "FT0Workflow/EntropyDecoderSpec.h"
2526

2627
using namespace o2::framework;
2728
using DetID = o2::detectors::DetID;
@@ -44,7 +45,9 @@ void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
4445
WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
4546
{
4647
DetID::mask_t dets;
47-
std::string inpNames = configcontext.options().get<std::string>("ctf-input");
48+
WorkflowSpec specs;
49+
50+
std::string inpNames;
4851
if (!configcontext.helpOnCommandLine()) {
4952
dets.set(); // by default read all
5053
auto mskOnly = DetID::getMask(configcontext.options().get<std::string>("onlyDet"));
@@ -54,11 +57,11 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
5457
} else {
5558
dets ^= mskSkip;
5659
}
57-
} else if (inpNames.empty()) {
58-
throw std::runtime_error("--ctf-input <file,...> is not provided");
60+
if ((inpNames = configcontext.options().get<std::string>("ctf-input")).empty()) {
61+
throw std::runtime_error("--ctf-input <file,...> is not provided");
62+
}
5963
}
6064

61-
WorkflowSpec specs;
6265
specs.push_back(o2::ctf::getCTFReaderSpec(dets, inpNames));
6366
// add decodors for all allowed detectors.
6467
if (dets[DetID::ITS]) {
@@ -70,6 +73,9 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
7073
if (dets[DetID::TPC]) {
7174
specs.push_back(o2::tpc::getEntropyDecoderSpec());
7275
}
76+
if (dets[DetID::FT0]) {
77+
specs.push_back(o2::ft0::getEntropyDecoderSpec());
78+
}
7379

7480
return std::move(specs);
7581
}

Detectors/CTF/workflow/src/ctf-writer-workflow.cxx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919
#include "DataFormatsParameters/GRPObject.h"
2020
#include "DetectorsCommonDataFormats/DetID.h"
2121

22-
// Specific detectors specs
23-
#include "ITSMFTWorkflow/EntropyEncoderSpec.h"
24-
2522
using namespace o2::framework;
2623
using DetID = o2::detectors::DetID;
2724

0 commit comments

Comments
 (0)