78 mCalibHandler->checkUpdates(ctx);
89 mDigitizerTRU.
flush();
99 if (mcReader ==
nullptr) {
103 auto& timesview = context->getEventRecords();
104 LOG(
debug) <<
"GOT " << timesview.size() <<
" COLLISSION TIMES";
107 if (timesview.size() == 0) {
114 auto& eventParts = context->getEventParts();
124 mDigitizerTRU.
setFEE(mCalibHandler->getFEEDCS());
138 for (
int collID = 0; collID < timesview.size(); ++collID) {
140 if (mRunDigitizerTRU ==
false) {
144 if (intRate < 10000.) {
154 for (
auto& part : eventParts[collID]) {
161 context->retrieveHits(mSimChains,
"EMCHit", part.sourceID, part.entryID, &mHits);
171 std::vector<o2::emcal::LabeledDigit> summedLabeledDigits;
172 std::vector<o2::emcal::Digit> summedDigits;
174 summedLabeledDigits = mSumDigitizerTRU.
process(mHits);
175 for (
auto labeledsummeddigit : summedLabeledDigits) {
176 summedDigits.push_back(labeledsummeddigit.getDigit());
179 for (
auto& hit : mHits) {
180 summedDigits.emplace_back(hit.GetDetectorID(), hit.GetEnergyLoss(), hit.GetTime());
185 mDigitizerTRU.
process(summedDigits);
195 std::vector<o2::InteractionRecord> mbtriggers;
196 if (mRequireCTPInput) {
201 std::vector<uint64_t> inputmasks;
205 LOG(
debug) <<
"Found trigger class for EMCAL cluster: " << trg.name <<
" with input mask " << std::bitset<64>(trg.descriptor->getInputsMask());
206 inputmasks.emplace_back(trg.descriptor->getInputsMask());
209 unsigned long ft0mask = 0, fv0mask = 0;
210 std::map<std::string, uint64_t> detInputName2Mask =
211 {{
"MVBA", 1}, {
"MVOR", 2}, {
"MVNC", 4}, {
"MVCH", 8}, {
"MVIR", 0x10}, {
"MT0A", 1}, {
"MT0C", 2}, {
"MTSC", 4}, {
"MTCE", 8}, {
"MTVX", 0x10}};
213 std::map<std::string, std::pair<o2::detectors::DetID, std::string>> ctpInput2DetInput = {
214 {
"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"}}};
219 for (
const auto& input : ctpinputs) {
220 LOG(
debug) <<
"CTP det input: " << input.name <<
" with mask " << std::bitset<64>(input.inputMask);
221 bool isSelected =
false;
222 for (
auto testmask : inputmasks) {
223 if (testmask & input.inputMask) {
228 std::string usedInputName = input.name;
231 auto found = ctpInput2DetInput.find(input.name);
232 if (found != ctpInput2DetInput.end()) {
233 usedInputName = found->second.second;
234 usedDetID = found->second.first;
235 LOG(
debug) <<
"Decoded " << input.name <<
" -> " << usedInputName;
238 auto maskFound = detInputName2Mask.find(usedInputName);
239 if (maskFound != detInputName2Mask.end()) {
241 ft0mask |= maskFound->second;
243 fv0mask |= maskFound->second;
249 LOG(
debug) <<
"FTO mask: " << std::bitset<64>(ft0mask);
250 LOG(
debug) <<
"FVO mask: " << std::bitset<64>(fv0mask);
252 for (
const auto& trg : ctx.inputs().get<gsl::span<o2::ft0::DetTrigInput>>(
"ft0inputs")) {
253 if (trg.mInputs.to_ulong() & ft0mask) {
254 mbtriggers.emplace_back(trg.mIntRecord);
259 for (
const auto& trg : ctx.inputs().get<gsl::span<o2::fv0::DetTrigInput>>(
"fv0inputs")) {
260 if (trg.mInputs.to_ulong() & fv0mask) {
261 if (std::find(mbtriggers.begin(), mbtriggers.end(), trg.mIntRecord) == mbtriggers.end()) {
262 mbtriggers.emplace_back(trg.mIntRecord);
269 LOG(info) <<
" CALLING EMCAL DIGITIZATION ";
273 std::vector<std::tuple<o2::InteractionRecord, std::bitset<5>>> acceptedTriggers;
274 enum EMCALTriggerBits { kMB,
277 TRandom3 mRandomGenerator(std::chrono::high_resolution_clock::now().time_since_epoch().
count());
281 for (
int collID = 0; collID < timesview.size(); ++collID) {
283 std::bitset<5> trigger{0x1};
284 if (mRequireCTPInput) {
298 auto mbtrigger = std::find(mbtriggers.begin(), mbtriggers.end(), timesview[collID]);
299 if (mbtrigger != mbtriggers.end()) {
308 downscaling = trg.downScale;
311 if (mRandomGenerator.Uniform(0., 1) < downscaling) {
313 trigger.set(EMCALTriggerBits::kMB,
true);
316 for (
auto emcalTrigger : emcalTriggers) {
317 auto bcTimingOfEmcalTrigger = emcalTrigger.mInterRecord.bc;
318 auto bcTimingOfMBTrigger = (*mbtrigger).bc;
319 if (std::abs(bcTimingOfEmcalTrigger - bcTimingOfMBTrigger) < 12) {
320 if (emcalTrigger.mTriggeredTRU < 32) {
321 trigger.set(EMCALTriggerBits::kEMC,
true);
323 trigger.set(EMCALTriggerBits::kDMC,
true);
331 trigger.set(EMCALTriggerBits::kMB,
false);
336 if (!trigger.any()) {
340 mDigitizer.
setEventTime(timesview[collID], trigger.any());
348 acceptedTriggers.push_back(std::make_tuple(timesview[collID], trigger));
349 LOG(
debug) <<
"EMCAL TRU simulation: Sending trg = " << trigger <<
" to CTP";
353 for (
auto& part : eventParts[collID]) {
359 auto& mcEventHeader = mcReader->
getMCEventHeader(part.sourceID, part.entryID);
360 mcEventHeader.
print();
364 context->retrieveHits(mSimChains,
"EMCHit", part.sourceID, part.entryID, &mHits);
366 LOG(info) <<
"For collision " << collID <<
" eventID " << part.entryID <<
" found " << mHits.size() <<
" hits ";
368 std::vector<o2::emcal::LabeledDigit> summedDigits;
370 summedDigits = mSumDigitizer.
process(mHits);
372 for (
auto& hit : mHits) {
373 o2::emcal::MCLabel digitlabel(hit.GetTrackID(), part.entryID, part.sourceID,
false, 1.);
374 if (hit.GetEnergyLoss() < __DBL_EPSILON__) {
377 summedDigits.emplace_back(hit.GetDetectorID(), hit.GetEnergyLoss(), hit.GetTime(), digitlabel);
382 mDigitizer.
process(summedDigits);
389 ctx.outputs().snapshot(
Output{
"EMC",
"DIGITS", 0}, mDigitizer.
getDigits());
391 if (ctx.outputs().isAllowed({
"EMC",
"DIGITSMCTR", 0})) {
392 ctx.outputs().snapshot(
Output{
"EMC",
"DIGITSMCTR", 0}, mDigitizer.
getMCLabels());
396 LOG(info) <<
"EMCAL: Sending ROMode= " << roMode <<
" to GRPUpdater";
397 ctx.outputs().snapshot(
Output{
"EMC",
"ROMode", 0}, roMode);
399 std::vector<o2::ctp::CTPInputDigit> triggerinputs;
410 for (
auto& trg : acceptedTriggers) {
417 if (std::get<1>(trg)[
i] != 0) {
422 triggerinputs.push_back(nextdigit);
424 ctx.outputs().snapshot(
Output{
"EMC",
"TRIGGERINPUT", 0}, triggerinputs);
427 LOG(info) <<
"Digitization took " << timer.CpuTime() <<
"s";
429 ctx.services().get<
ControlService>().readyToQuit(QuitRequest::Me);
474 std::vector<OutputSpec> outputs;
475 outputs.emplace_back(
"EMC",
"DIGITS", 0, Lifetime::Timeframe);
476 outputs.emplace_back(
"EMC",
"TRGRDIG", 0, Lifetime::Timeframe);
478 outputs.emplace_back(
"EMC",
"DIGITSMCTR", 0, Lifetime::Timeframe);
480 outputs.emplace_back(
"EMC",
"ROMode", 0, Lifetime::Timeframe);
481 outputs.emplace_back(
"EMC",
"TRIGGERINPUT", 0, Lifetime::Timeframe);
483 std::vector<o2::framework::InputSpec> inputs;
484 inputs.emplace_back(
"collisioncontext",
"SIM",
"COLLISIONCONTEXT",
static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
485 std::shared_ptr<CalibLoader> calibloader;
487 calibloader = std::make_shared<CalibLoader>();
488 calibloader->enableSimParams(
true);
489 calibloader->enableFEEDCS(
true);
490 calibloader->defineInputSpecs(inputs);
493 if (requireCTPInput) {
496 inputs.emplace_back(
"ft0inputs",
"FT0",
"TRIGGERINPUT", 0, Lifetime::Timeframe);
500 inputs.emplace_back(
"fv0inputs",
"FV0",
"TRIGGERINPUT", 0, Lifetime::Timeframe);
502 inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config",
true));
509 AlgorithmSpec{o2::framework::adaptFromTask<DigitizerSpec>(calibloader, requireCTPInput, detMask)},
511 {
"pileup", VariantType::Int, 1, {
"whether to run in continuous time mode"}},
512 {
"disable-dig-tru", VariantType::Bool,
false, {
"Disable TRU digitisation"}},
513 {
"debug-stream", VariantType::Bool,
false, {
"Enable debug streaming"}}}