Skip to content

Commit be8f7bc

Browse files
mfasDasawenzel
authored andcommitted
[EMCAL-1055] Require FIT trigger in digitization
Triggering of collisons in the DigitsWriteoutBuffer is based of FT0/FV0 detector trigger inputs. All FIT triggers are accepted. The self-triggered mode stays as option for EMCAL-only simulations.
1 parent 19795dc commit be8f7bc

File tree

9 files changed

+131
-17
lines changed

9 files changed

+131
-17
lines changed

Detectors/EMCAL/simulation/include/EMCALSimulation/Digitizer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class Digitizer : public TObject
6767
/// Steer conversion of hits to digits
6868
void process(const std::vector<LabeledDigit>& labeledDigit);
6969

70-
void setEventTime(o2::InteractionTimeRecord record);
70+
void setEventTime(o2::InteractionTimeRecord record, bool trigger);
7171
double getTriggerTime() const { return mDigits.getTriggerTime(); }
7272
double getEventTime() const { return mDigits.getEventTime(); }
7373
bool isLive(double t) const { return mDigits.isLive(t); }

Detectors/EMCAL/simulation/include/EMCALSimulation/DigitsWriteoutBuffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class DigitsWriteoutBuffer
8181
unsigned int getBufferSize() const { return mBufferSize; }
8282

8383
/// forward the marker for every 100 ns
84-
void forwardMarker(o2::InteractionTimeRecord record);
84+
void forwardMarker(o2::InteractionTimeRecord record, bool trigger);
8585

8686
/// Setters for the live time, busy time, pre-trigger time
8787
void setLiveTime(unsigned int liveTime) { mLiveTime = liveTime; }

Detectors/EMCAL/simulation/src/Digitizer.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,10 @@ double Digitizer::smearTime(double time, double energy)
233233
}
234234

235235
//_______________________________________________________________________
236-
void Digitizer::setEventTime(o2::InteractionTimeRecord record)
236+
void Digitizer::setEventTime(o2::InteractionTimeRecord record, bool trigger)
237237
{
238238

239-
mDigits.forwardMarker(record);
239+
mDigits.forwardMarker(record, trigger);
240240

241241
mPhase = mSimParam->doSimulateL1Phase() ? mDigits.getPhase() : 0;
242242

Detectors/EMCAL/simulation/src/DigitsVectorStream.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ void DigitsVectorStream::fill(std::deque<o2::emcal::DigitTimebin>& digitlist, o2
125125
mTriggerRecords.emplace_back(record, o2::trigger::PhT, mStartIndex, numberOfNewDigits);
126126
mStartIndex = mDigits.size();
127127

128-
LOG(info) << "Have " << mStartIndex << " digits ";
128+
LOG(info) << "Trigger Orbit " << record.orbit << ", BC " << record.bc << ": have " << numberOfNewDigits << " digits (" << mStartIndex << " total)";
129129
}
130130

131131
//_______________________________________________________________________

Detectors/EMCAL/simulation/src/DigitsWriteoutBuffer.cxx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "EMCALSimulation/DigitsWriteoutBuffer.h"
2020
#include "CommonDataFormat/InteractionRecord.h"
2121
#include "TMath.h"
22+
#include <fairlogger/Logger.h>
2223

2324
using namespace o2::emcal;
2425

@@ -80,7 +81,7 @@ void DigitsWriteoutBuffer::addDigits(unsigned int towerID, std::vector<LabeledDi
8081
// is removed and pushed at the end of the past dequeue. At the same time a new entry in
8182
// the future dequeue is pushed at the end, and - in case the past dequeue reached 15 entries
8283
// the first entry of the past dequeue is removed.
83-
void DigitsWriteoutBuffer::forwardMarker(o2::InteractionTimeRecord record)
84+
void DigitsWriteoutBuffer::forwardMarker(o2::InteractionTimeRecord record, bool trigger)
8485
{
8586

8687
unsigned long eventTime = record.getTimeNS();
@@ -124,7 +125,8 @@ void DigitsWriteoutBuffer::forwardMarker(o2::InteractionTimeRecord record)
124125

125126
// If we have a trigger, all the time bins in the future buffer will be set to record mode
126127
// the last time bin will the end of the readout window since it will be mTriggerTime + 1500 ns
127-
if ((eventTime - mTriggerTime) >= (mLiveTime + mBusyTime) || mFirstEvent) {
128+
if (trigger && ((eventTime - mTriggerTime) >= (mLiveTime + mBusyTime) || mFirstEvent)) {
129+
LOG(debug) << "Trigger received and accepted";
128130
mTriggerTime = eventTime;
129131
mTimedDigitsFuture.front().mTriggerColl = true;
130132
mTimedDigitsFuture.front().mInterRecord = record;
@@ -142,8 +144,8 @@ void DigitsWriteoutBuffer::forwardMarker(o2::InteractionTimeRecord record)
142144
}
143145

144146
// If we have a pre-trigger collision, all the time bins in the future buffer will be set to record mode
145-
if ((eventTime - mTriggerTime) >= (mLiveTime + mBusyTime - mPreTriggerTime)) {
146-
std::cout << "Pre-trigger collision\n";
147+
if ((eventTime - mTriggerTime) >= (mLiveTime + mBusyTime - mPreTriggerTime) || mFirstEvent) {
148+
LOG(debug) << "Pre-trigger collision";
147149
long timeStamp = (eventTime / 100) * 100; /// This is to make the event time multiple of 100s
148150
for (auto& iNode : mTimedDigitsFuture) {
149151
long diff = (timeStamp - eventTime);

Detectors/EMCAL/workflow/CMakeLists.txt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,20 @@ o2_add_library(EMCALWorkflow
2525
src/CellRecalibratorSpec.cxx
2626
src/EntropyDecoderSpec.cxx
2727
src/StandaloneAODProducerSpec.cxx
28-
PUBLIC_LINK_LIBRARIES O2::Framework O2::DataFormatsCTP O2::DataFormatsEMCAL O2::EMCALSimulation O2::Steer
29-
O2::DPLUtils O2::EMCALBase O2::EMCALCalib O2::EMCALCalibration O2::EMCALReconstruction O2::Algorithm O2::MathUtils)
28+
PUBLIC_LINK_LIBRARIES O2::Framework
29+
O2::DataFormatsCTP
30+
O2::DataFormatsEMCAL
31+
O2::DataFormatsFT0
32+
O2::DataFormatsFV0
33+
O2::EMCALSimulation
34+
O2::Steer
35+
O2::DPLUtils
36+
O2::EMCALBase
37+
O2::EMCALCalib
38+
O2::EMCALCalibration
39+
O2::EMCALReconstruction
40+
O2::Algorithm
41+
O2::MathUtils)
3042

3143
o2_add_executable(reco-workflow
3244
COMPONENT_NAME emcal

Detectors/EMCAL/workflow/include/EMCALWorkflow/EMCALDigitizerSpec.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ class TChain;
2828

2929
namespace o2
3030
{
31+
32+
namespace ctp
33+
{
34+
class CTPConfiguration;
35+
}
36+
3137
namespace emcal
3238
{
3339
class CalibLoader;
@@ -45,7 +51,7 @@ class DigitizerSpec final : public o2::base::BaseDPLDigitizer, public o2::framew
4551
public:
4652
using o2::base::BaseDPLDigitizer::init;
4753
/// \brief Constructor
48-
DigitizerSpec(std::shared_ptr<CalibLoader> calibloader) : o2::base::BaseDPLDigitizer(o2::base::InitServices::GEOM), o2::framework::Task(), mCalibHandler(calibloader) {}
54+
DigitizerSpec(std::shared_ptr<CalibLoader> calibloader, bool requireCTPInput) : o2::base::BaseDPLDigitizer(o2::base::InitServices::GEOM), o2::framework::Task(), mRequireCTPInput(requireCTPInput), mCalibHandler(calibloader) {}
4955

5056
/// \brief Destructor
5157
~DigitizerSpec() final = default;
@@ -71,16 +77,18 @@ class DigitizerSpec final : public o2::base::BaseDPLDigitizer, public o2::framew
7177
Bool_t mFinished = false; ///< Flag for digitization finished
7278
bool mIsConfigured = false; ///< Initialization status of the digitizer
7379
bool mRunSDitizer = false; ///< Run SDigitization
80+
bool mRequireCTPInput = false; ///< Require CTP min. bias input
7481
Digitizer mDigitizer; ///< Digitizer object
7582
o2::emcal::SDigitizer mSumDigitizer; ///< Summed digitizer
7683
std::shared_ptr<CalibLoader> mCalibHandler; ///< Handler of calibration objects
7784
std::vector<Hit> mHits; ///< Vector with input hits
7885
std::vector<TChain*> mSimChains;
86+
o2::ctp::CTPConfiguration* mCTPConfig; ///< CTP configuration
7987
};
8088

8189
/// \brief Create new digitizer spec
8290
/// \return Digitizer spec
83-
o2::framework::DataProcessorSpec getEMCALDigitizerSpec(int channel, bool mctruth = true, bool useccdb = true);
91+
o2::framework::DataProcessorSpec getEMCALDigitizerSpec(int channel, bool requireCTPInput, bool mctruth = true, bool useccdb = true);
8492

8593
} // namespace emcal
8694
} // end namespace o2

Detectors/EMCAL/workflow/src/EMCALDigitizerSpec.cxx

Lines changed: 91 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@
2727
#include "CommonDataFormat/EvIndex.h"
2828
#include "DetectorsCommonDataFormats/DetID.h"
2929
#include "DataFormatsParameters/GRPObject.h"
30+
#include "DataFormatsCTP/Configuration.h"
3031
#include "DataFormatsCTP/Digits.h"
3132
#include "DataFormatsEMCAL/TriggerRecord.h"
33+
#include "DataFormatsFT0/Digit.h"
34+
#include "DataFormatsFV0/Digit.h"
3235

3336
using namespace o2::framework;
3437
using SubSpecificationType = o2::framework::DataAllocator::SubSpecificationType;
@@ -91,6 +94,77 @@ void DigitizerSpec::run(framework::ProcessingContext& ctx)
9194
TStopwatch timer;
9295
timer.Start();
9396

97+
// Load FIT triggers if not running in self-triggered mode
98+
std::vector<o2::InteractionRecord> mbtriggers;
99+
if (mRequireCTPInput) {
100+
// Hopefully at some point we can replace it by CTP input digits
101+
// In case of CTP digits react only to trigger inputs activated in trigger configuration
102+
// For the moment react to FIT vertex, cent and semicent triggers
103+
ctx.inputs().get<o2::ctp::CTPConfiguration*>("ctpconfig");
104+
std::vector<uint64_t> inputmasks;
105+
for (const auto& trg : mCTPConfig->getCTPClasses()) {
106+
if (trg.cluster->maskCluster[o2::detectors::DetID::EMC]) {
107+
// Class triggering EMCAL cluster
108+
LOG(debug) << "Found trigger class for EMCAL cluster: " << trg.name << " with input mask " << std::bitset<64>(trg.descriptor->getInputsMask());
109+
inputmasks.emplace_back(trg.descriptor->getInputsMask());
110+
}
111+
}
112+
unsigned long ft0mask = 0, fv0mask = 0;
113+
std::map<std::string, uint64_t> detInputName2Mask =
114+
{{"MVBA", 1}, {"MVOR", 2}, {"MVNC", 4}, {"MVCH", 8}, {"MVIR", 0x10}, {"MT0A", 1}, {"MT0C", 2}, {"MTSC", 4}, {"MTCE", 8}, {"MTVX", 0x10}};
115+
// Translation 2022: EMCAL cluster received CTP input masks, need to track it to FIT trigger masks
116+
std::map<std::string, std::pair<o2::detectors::DetID, std::string>> ctpInput2DetInput = {
117+
{"0VBA", {o2::detectors::DetID::FV0, "MVBA"}}, {"0VOR", {o2::detectors::DetID::FV0, "MVOR"}}, {"0VNC", {o2::detectors::DetID::FV0, "MVNC"}}, {"0VCH", {o2::detectors::DetID::FV0, "MVCH"}}, {"0VIR", {o2::detectors::DetID::FV0, "MVIR"}}, {"0T0A", {o2::detectors::DetID::FT0, "MT0A"}}, {"0T0C", {o2::detectors::DetID::FT0, "MT0C"}}, {"0TSC", {o2::detectors::DetID::FT0, "MTSC"}}, {"0TCE", {o2::detectors::DetID::FT0, "MTCE"}}, {"0TVX", {o2::detectors::DetID::FT0, "MTVX"}}};
118+
for (const auto& [det, ctpinputs] : mCTPConfig->getDet2InputMap()) {
119+
if (!(det == o2::detectors::DetID::FT0 || det == o2::detectors::DetID::FV0 || det == o2::detectors::DetID::CTP)) {
120+
continue;
121+
}
122+
for (const auto& input : ctpinputs) {
123+
LOG(debug) << "CTP det input: " << input.name << " with mask " << std::bitset<64>(input.inputMask);
124+
bool isSelected = false;
125+
for (auto testmask : inputmasks) {
126+
if (testmask & input.inputMask) {
127+
isSelected = true;
128+
}
129+
}
130+
if (isSelected) {
131+
std::string usedInputName = input.name;
132+
o2::detectors::DetID usedDetID = det;
133+
if (det == o2::detectors::DetID::CTP) {
134+
auto found = ctpInput2DetInput.find(input.name);
135+
if (found != ctpInput2DetInput.end()) {
136+
usedInputName = found->second.second;
137+
usedDetID = found->second.first;
138+
LOG(debug) << "Decoded " << input.name << " -> " << usedInputName;
139+
}
140+
}
141+
auto maskFound = detInputName2Mask.find(usedInputName);
142+
if (maskFound != detInputName2Mask.end()) {
143+
if (usedDetID == o2::detectors::DetID::FT0) {
144+
ft0mask |= maskFound->second;
145+
} else {
146+
fv0mask |= maskFound->second;
147+
}
148+
}
149+
}
150+
}
151+
}
152+
LOG(debug) << "FTO mask: " << std::bitset<64>(ft0mask);
153+
LOG(debug) << "FVO mask: " << std::bitset<64>(fv0mask);
154+
for (const auto& trg : ctx.inputs().get<gsl::span<o2::ft0::DetTrigInput>>("ft0inputs")) {
155+
if (trg.mInputs.to_ulong() & ft0mask) {
156+
mbtriggers.emplace_back(trg.mIntRecord);
157+
}
158+
}
159+
for (const auto& trg : ctx.inputs().get<gsl::span<o2::fv0::DetTrigInput>>("fv0inputs")) {
160+
if (trg.mInputs.to_ulong() & fv0mask) {
161+
if (std::find(mbtriggers.begin(), mbtriggers.end(), trg.mIntRecord) == mbtriggers.end()) {
162+
mbtriggers.emplace_back(trg.mIntRecord);
163+
}
164+
}
165+
}
166+
}
167+
94168
LOG(info) << " CALLING EMCAL DIGITIZATION ";
95169
o2::dataformats::MCTruthContainer<o2::emcal::MCLabel> labelAccum;
96170

@@ -99,8 +173,13 @@ void DigitizerSpec::run(framework::ProcessingContext& ctx)
99173
// loop over all composite collisions given from context
100174
// (aka loop over all the interaction records)
101175
for (int collID = 0; collID < timesview.size(); ++collID) {
176+
bool trigger = true; // Default: Self-triggered mode - all collisions treated as trigger
177+
if (mRequireCTPInput) {
178+
// check if we have a trigger input from CTP
179+
trigger = (std::find(mbtriggers.begin(), mbtriggers.end(), timesview[collID]) != mbtriggers.end());
180+
}
102181

103-
mDigitizer.setEventTime(timesview[collID]);
182+
mDigitizer.setEventTime(timesview[collID], trigger);
104183

105184
if (!mDigitizer.isLive()) {
106185
continue;
@@ -180,9 +259,13 @@ void DigitizerSpec::finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, vo
180259
if (mCalibHandler->finalizeCCDB(matcher, obj)) {
181260
return;
182261
}
262+
if (matcher == o2::framework::ConcreteDataMatcher("CTP", "CTPCONFIG", 0)) {
263+
std::cout << "Loading CTP configuration" << std::endl;
264+
mCTPConfig = reinterpret_cast<o2::ctp::CTPConfiguration*>(obj);
265+
}
183266
}
184267

185-
o2::framework::DataProcessorSpec getEMCALDigitizerSpec(int channel, bool mctruth, bool useccdb)
268+
o2::framework::DataProcessorSpec getEMCALDigitizerSpec(int channel, bool requireCTPInput, bool mctruth, bool useccdb)
186269
{
187270
// create the full data processor spec using
188271
// a name identifier
@@ -206,12 +289,17 @@ o2::framework::DataProcessorSpec getEMCALDigitizerSpec(int channel, bool mctruth
206289
calibloader->enableSimParams(true);
207290
calibloader->defineInputSpecs(inputs);
208291
}
292+
if (requireCTPInput) {
293+
inputs.emplace_back("ft0inputs", "FT0", "TRIGGERINPUT", 0, Lifetime::Timeframe);
294+
inputs.emplace_back("fv0inputs", "FV0", "TRIGGERINPUT", 0, Lifetime::Timeframe);
295+
inputs.emplace_back("ctpconfig", "CTP", "CTPCONFIG", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/Config", true));
296+
}
209297

210298
return DataProcessorSpec{
211299
"EMCALDigitizer", // Inputs{InputSpec{"collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast<SubSpecificationType>(channel), Lifetime::Timeframe}, InputSpec{"EMC_SimParam", o2::header::gDataOriginEMC, "SIMPARAM", 0, Lifetime::Condition, ccdbParamSpec("EMC/Config/SimParam")}},
212300
inputs,
213301
outputs,
214-
AlgorithmSpec{o2::framework::adaptFromTask<DigitizerSpec>(calibloader)},
302+
AlgorithmSpec{o2::framework::adaptFromTask<DigitizerSpec>(calibloader, requireCTPInput)},
215303
Options{
216304
{"pileup", VariantType::Int, 1, {"whether to run in continuous time mode"}},
217305
{"debug-stream", VariantType::Bool, false, {"Enable debug streaming"}}}

Steer/DigitizerWorkflow/src/SimpleDigitizerWorkflow.cxx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
198198
// option to use/not use CCDB for EMCAL
199199
workflowOptions.push_back(ConfigParamSpec{"no-use-ccdb-emc", o2::framework::VariantType::Bool, false, {"Disable access to ccdb EMCAL simulation objects"}});
200200

201+
// option to require/not require CTP MB inputs in EMCAL
202+
workflowOptions.push_back(ConfigParamSpec{"no-require-ctpinputs-emc", o2::framework::VariantType::Bool, false, {"Disable requirement of CTP min. bias inputs in EMCAL simulation"}});
203+
201204
// option to use or not use the Trap Simulator after digitisation (debate of digitization or reconstruction is for others)
202205
workflowOptions.push_back(ConfigParamSpec{"disable-trd-trapsim", VariantType::Bool, false, {"disable the trap simulation of the TRD"}});
203206
workflowOptions.push_back(ConfigParamSpec{"trd-digit-downscaling", VariantType::Int, 1, {"only keep TRD digits for every n-th trigger"}});
@@ -653,9 +656,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
653656
// the EMCal part
654657
if (isEnabled(o2::detectors::DetID::EMC)) {
655658
auto useCCDB = !configcontext.options().get<bool>("no-use-ccdb-emc");
659+
bool requireCTPInputs = !configcontext.options().get<bool>("no-require-ctpinputs-emc");
656660
detList.emplace_back(o2::detectors::DetID::EMC);
657661
// connect the EMCal digitization
658-
digitizerSpecs.emplace_back(o2::emcal::getEMCALDigitizerSpec(fanoutsize++, mctruth, useCCDB));
662+
digitizerSpecs.emplace_back(o2::emcal::getEMCALDigitizerSpec(fanoutsize++, requireCTPInputs, mctruth, useCCDB));
659663
// connect the EMCal digit writer
660664
writerSpecs.emplace_back(o2::emcal::getEMCALDigitWriterSpec(mctruth));
661665
}

0 commit comments

Comments
 (0)