Skip to content

Commit 3f44ff5

Browse files
committed
[PWGLF] eventShapeCoex: Add forward/backward sub-event producer
This is the first commit of this task. It starts the migration to O2Physics of the event-shape analyses developed in AliPhysics under PWGLF/SPECTRA/MultEvShape (https://github.com/alisw/AliPhysics/tree/master/PWGLF/SPECTRA/MultEvShape). The physics programme carries over; the implementation is written anew for O2Physics as a slim per-collision derived table, with the analysis done on top of it.
1 parent bef1958 commit 3f44ff5

4 files changed

Lines changed: 381 additions & 0 deletions

File tree

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file LFEventTopologyTables.h
13+
/// \brief Per-collision forward/backward sub-event tables, reconstructed and generated level.
14+
/// \author Cristian Andrei <Cristian.Andrei@cern.ch>
15+
16+
#ifndef PWGLF_DATAMODEL_LFEVENTTOPOLOGYTABLES_H_
17+
#define PWGLF_DATAMODEL_LFEVENTTOPOLOGYTABLES_H_
18+
19+
#include <Framework/AnalysisDataModel.h>
20+
21+
#include <cstdint>
22+
23+
namespace o2::aod
24+
{
25+
26+
namespace evshapecoex
27+
{
28+
DECLARE_SOA_COLUMN(CollisionId, collisionId, int); //! source collision global index (DF-local; not an index column)
29+
DECLARE_SOA_COLUMN(RunNumber, runNumber, int); //! run number
30+
DECLARE_SOA_COLUMN(GlobalBC, globalBC, uint64_t); //! global bunch crossing
31+
DECLARE_SOA_COLUMN(PosZ, posZ, float); //! primary-vertex z (cm)
32+
DECLARE_SOA_COLUMN(MultFT0A, multFT0A, float); //! FT0-A amplitude
33+
DECLARE_SOA_COLUMN(MultFT0C, multFT0C, float); //! FT0-C amplitude
34+
DECLARE_SOA_COLUMN(NF, nF, uint16_t); //! track count, forward sub-event
35+
DECLARE_SOA_COLUMN(NB, nB, uint16_t); //! track count, backward sub-event
36+
DECLARE_SOA_COLUMN(NGap, nGap, uint16_t); //! track count, central gap
37+
DECLARE_SOA_COLUMN(AF, aF, float); //! mean pT, forward (GeV/c); NaN if empty
38+
DECLARE_SOA_COLUMN(AB, aB, float); //! mean pT, backward (GeV/c); NaN if empty
39+
DECLARE_SOA_COLUMN(SumPt2F, sumPt2F, float); //! sum of pT^2, forward (GeV^2/c^2)
40+
DECLARE_SOA_COLUMN(SumPt2B, sumPt2B, float); //! sum of pT^2, backward (GeV^2/c^2)
41+
DECLARE_SOA_COLUMN(QxF, qxF, float); //! sum of cos(2 phi), forward
42+
DECLARE_SOA_COLUMN(QyF, qyF, float); //! sum of sin(2 phi), forward
43+
DECLARE_SOA_COLUMN(QxB, qxB, float); //! sum of cos(2 phi), backward
44+
DECLARE_SOA_COLUMN(QyB, qyB, float); //! sum of sin(2 phi), backward
45+
DECLARE_SOA_COLUMN(Qx4F, qx4F, float); //! sum of cos(4 phi), forward
46+
DECLARE_SOA_COLUMN(Qy4F, qy4F, float); //! sum of sin(4 phi), forward
47+
DECLARE_SOA_COLUMN(Qx4B, qx4B, float); //! sum of cos(4 phi), backward
48+
DECLARE_SOA_COLUMN(Qy4B, qy4B, float); //! sum of sin(4 phi), backward
49+
DECLARE_SOA_COLUMN(NPlus, nPlus, uint16_t); //! positive tracks, forward + backward
50+
DECLARE_SOA_COLUMN(NMinus, nMinus, uint16_t); //! negative tracks, forward + backward
51+
DECLARE_SOA_COLUMN(QaBits, qaBits, uint16_t); //! event-selection bits, order as QaBitOrder in eventShapeCoex.cxx
52+
DECLARE_SOA_COLUMN(OccTracks, occTracks, int); //! track occupancy in time range
53+
DECLARE_SOA_COLUMN(OccFT0C, occFT0C, float); //! FT0C occupancy in time range
54+
DECLARE_SOA_COLUMN(NumContrib, numContrib, uint16_t); //! number of PV contributors
55+
DECLARE_SOA_COLUMN(CollTimeRes, collTimeRes, float); //! collision time resolution (ns)
56+
DECLARE_SOA_COLUMN(NPVC, nPVC, uint16_t); //! PV contributors among the selected tracks
57+
} // namespace evshapecoex
58+
59+
DECLARE_SOA_TABLE(EvShapeCoex, "AOD", "EVSHAPECOEX", //! per-collision forward/backward sub-events, reconstructed level
60+
o2::soa::Index<>,
61+
evshapecoex::CollisionId, evshapecoex::RunNumber, evshapecoex::GlobalBC, evshapecoex::PosZ,
62+
evshapecoex::MultFT0A, evshapecoex::MultFT0C,
63+
evshapecoex::NF, evshapecoex::NB, evshapecoex::NGap,
64+
evshapecoex::AF, evshapecoex::AB, evshapecoex::SumPt2F, evshapecoex::SumPt2B,
65+
evshapecoex::QxF, evshapecoex::QyF, evshapecoex::QxB, evshapecoex::QyB,
66+
evshapecoex::Qx4F, evshapecoex::Qy4F, evshapecoex::Qx4B, evshapecoex::Qy4B,
67+
evshapecoex::NPlus, evshapecoex::NMinus,
68+
evshapecoex::QaBits, evshapecoex::OccTracks, evshapecoex::OccFT0C,
69+
evshapecoex::NumContrib, evshapecoex::CollTimeRes, evshapecoex::NPVC);
70+
using EvShapeCoexRow = EvShapeCoex::iterator;
71+
72+
// Generator level: charged physical primaries, one row per McCollision (no event selection).
73+
namespace evshapecoexgen
74+
{
75+
DECLARE_SOA_COLUMN(McCollisionId, mcCollisionId, int); //! source McCollision global index (DF-local; not an index column)
76+
DECLARE_SOA_COLUMN(PosZ, posZ, float); //! generated primary-vertex z (cm)
77+
DECLARE_SOA_COLUMN(NFwdA, nFwdA, uint16_t); //! charged primaries in the FT0-A acceptance
78+
DECLARE_SOA_COLUMN(NFwdC, nFwdC, uint16_t); //! charged primaries in the FT0-C acceptance
79+
DECLARE_SOA_COLUMN(NF, nF, uint16_t); //! particle count, forward sub-event
80+
DECLARE_SOA_COLUMN(NB, nB, uint16_t); //! particle count, backward sub-event
81+
DECLARE_SOA_COLUMN(NGap, nGap, uint16_t); //! particle count, central gap
82+
DECLARE_SOA_COLUMN(AF, aF, float); //! mean pT, forward (GeV/c); NaN if empty
83+
DECLARE_SOA_COLUMN(AB, aB, float); //! mean pT, backward (GeV/c); NaN if empty
84+
DECLARE_SOA_COLUMN(SumPt2F, sumPt2F, float); //! sum of pT^2, forward (GeV^2/c^2)
85+
DECLARE_SOA_COLUMN(SumPt2B, sumPt2B, float); //! sum of pT^2, backward (GeV^2/c^2)
86+
DECLARE_SOA_COLUMN(QxF, qxF, float); //! sum of cos(2 phi), forward
87+
DECLARE_SOA_COLUMN(QyF, qyF, float); //! sum of sin(2 phi), forward
88+
DECLARE_SOA_COLUMN(QxB, qxB, float); //! sum of cos(2 phi), backward
89+
DECLARE_SOA_COLUMN(QyB, qyB, float); //! sum of sin(2 phi), backward
90+
DECLARE_SOA_COLUMN(Qx4F, qx4F, float); //! sum of cos(4 phi), forward
91+
DECLARE_SOA_COLUMN(Qy4F, qy4F, float); //! sum of sin(4 phi), forward
92+
DECLARE_SOA_COLUMN(Qx4B, qx4B, float); //! sum of cos(4 phi), backward
93+
DECLARE_SOA_COLUMN(Qy4B, qy4B, float); //! sum of sin(4 phi), backward
94+
DECLARE_SOA_COLUMN(NPlus, nPlus, uint16_t); //! positive particles, forward + backward
95+
DECLARE_SOA_COLUMN(NMinus, nMinus, uint16_t); //! negative particles, forward + backward
96+
} // namespace evshapecoexgen
97+
98+
DECLARE_SOA_TABLE(EvShapeCoexGen, "AOD", "EVSHAPECOEXGEN", //! per-McCollision forward/backward sub-events, generator level
99+
o2::soa::Index<>,
100+
evshapecoexgen::McCollisionId, evshapecoexgen::PosZ,
101+
evshapecoexgen::NFwdA, evshapecoexgen::NFwdC,
102+
evshapecoexgen::NF, evshapecoexgen::NB, evshapecoexgen::NGap,
103+
evshapecoexgen::AF, evshapecoexgen::AB, evshapecoexgen::SumPt2F, evshapecoexgen::SumPt2B,
104+
evshapecoexgen::QxF, evshapecoexgen::QyF, evshapecoexgen::QxB, evshapecoexgen::QyB,
105+
evshapecoexgen::Qx4F, evshapecoexgen::Qy4F, evshapecoexgen::Qx4B, evshapecoexgen::Qy4B,
106+
evshapecoexgen::NPlus, evshapecoexgen::NMinus);
107+
using EvShapeCoexGenRow = EvShapeCoexGen::iterator;
108+
109+
namespace evshapecoexmclabel
110+
{
111+
DECLARE_SOA_INDEX_COLUMN_FULL(EvShapeCoexGen, evShapeCoexGen, int, EvShapeCoexGen, ""); //! matching EvShapeCoexGen row; negative if unlabelled
112+
} // namespace evshapecoexmclabel
113+
114+
DECLARE_SOA_TABLE(EvShapeCoexMcLabels, "AOD", "EVSHAPECOEXLBL", //! MC label, joinable with EvShapeCoex
115+
o2::soa::Index<>, evshapecoexmclabel::EvShapeCoexGenId);
116+
using EvShapeCoexMcLabel = EvShapeCoexMcLabels::iterator;
117+
118+
} // namespace o2::aod
119+
120+
#endif // PWGLF_DATAMODEL_LFEVENTTOPOLOGYTABLES_H_

‎PWGLF/TableProducer/CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
add_subdirectory(QC)
1313
add_subdirectory(Common)
1414

15+
add_subdirectory(GlobalEventProperties)
1516
add_subdirectory(Nuspex)
1617
add_subdirectory(Strangeness)
1718
add_subdirectory(Resonances)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
# All rights not expressly granted are reserved.
4+
#
5+
# This software is distributed under the terms of the GNU General Public
6+
# License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
#
8+
# In applying this license CERN does not waive the privileges and immunities
9+
# granted to it by virtue of its status as an Intergovernmental Organization
10+
# or submit itself to any jurisdiction.
11+
12+
o2physics_add_dpl_workflow(event-shape-coex
13+
SOURCES eventShapeCoex.cxx
14+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
15+
COMPONENT_NAME Analysis)
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file eventShapeCoex.cxx
13+
/// \brief Per-collision forward/backward sub-event quantities of the mid-rapidity tracks.
14+
/// \author Cristian Andrei <Cristian.Andrei@cern.ch>
15+
///
16+
/// First O2Physics task of the AliPhysics PWGLF/SPECTRA/MultEvShape analyses.
17+
18+
#include "PWGLF/DataModel/LFEventTopologyTables.h"
19+
20+
#include "Common/CCDB/EventSelectionParams.h"
21+
#include "Common/DataModel/EventSelection.h"
22+
#include "Common/DataModel/Multiplicity.h"
23+
#include "Common/DataModel/TrackSelectionTables.h"
24+
25+
#include <Framework/ASoA.h>
26+
#include <Framework/AnalysisDataModel.h>
27+
#include <Framework/AnalysisTask.h>
28+
#include <Framework/Configurable.h>
29+
#include <Framework/InitContext.h>
30+
#include <Framework/Logger.h>
31+
#include <Framework/O2DatabasePDGPlugin.h>
32+
#include <Framework/runDataProcessing.h>
33+
34+
#include <cmath>
35+
#include <cstdint>
36+
37+
using namespace o2;
38+
using namespace o2::framework;
39+
using namespace o2::framework::expressions;
40+
41+
namespace
42+
{
43+
/// Sums over one sub-event, shared by the reconstructed and generated levels.
44+
struct SubEventSums {
45+
uint32_t n = 0;
46+
double sumPt = 0.;
47+
double sumPt2 = 0.;
48+
double qx2 = 0., qy2 = 0.;
49+
double qx4 = 0., qy4 = 0.;
50+
51+
void add(double pt, float phi)
52+
{
53+
// phi stays float, as stored in the AOD
54+
const double c = std::cos(phi);
55+
const double s = std::sin(phi);
56+
const double cos2 = c * c - s * s;
57+
const double sin2 = 2. * s * c;
58+
++n;
59+
sumPt += pt;
60+
sumPt2 += pt * pt;
61+
qx2 += cos2;
62+
qy2 += sin2;
63+
qx4 += cos2 * cos2 - sin2 * sin2;
64+
qy4 += 2. * sin2 * cos2;
65+
}
66+
67+
float meanPt() const { return (n > 0) ? static_cast<float>(sumPt / n) : std::nanf(""); }
68+
};
69+
} // namespace
70+
71+
struct EventShapeCoex {
72+
Produces<aod::EvShapeCoex> coex;
73+
Produces<aod::EvShapeCoexGen> coexGen;
74+
Produces<aod::EvShapeCoexMcLabels> coexMcLabels;
75+
76+
Service<o2::framework::O2DatabasePDG> pdg;
77+
78+
Configurable<float> vtxZCut{"vtxZCut", 10.0f, "Max |PV z| (cm)"};
79+
Configurable<float> ptMin{"ptMin", 0.15f, "Minimum track pT (GeV/c)"};
80+
Configurable<float> ptMax{"ptMax", 2.0f, "Maximum track pT (GeV/c)"};
81+
Configurable<float> etaMax{"etaMax", 0.8f, "Max |eta| (mid-rapidity measurement region)"};
82+
Configurable<float> gapHalf{"gapHalf", 0.2f, "Central-gap half-width: |eta| <= gapHalf excluded from F/B"};
83+
Configurable<float> etaFwdAMin{"etaFwdAMin", 3.5f, "FT0-A proxy: lower eta edge (generator level)"};
84+
Configurable<float> etaFwdAMax{"etaFwdAMax", 4.9f, "FT0-A proxy: upper eta edge (generator level)"};
85+
Configurable<float> etaFwdCMin{"etaFwdCMin", -3.3f, "FT0-C proxy: lower eta edge (generator level)"};
86+
Configurable<float> etaFwdCMax{"etaFwdCMax", -2.1f, "FT0-C proxy: upper eta edge (generator level)"};
87+
88+
Filter trackFilter = (aod::track::pt > ptMin) && (aod::track::pt < ptMax) && (nabs(aod::track::eta) < etaMax) && requireGlobalTrackInFilter();
89+
90+
using MyCollisions = soa::Join<aod::Collisions, aod::EvSels, aod::FT0Mults>;
91+
using MyCollisionsMc = soa::Join<MyCollisions, aod::McCollisionLabels>;
92+
using MyTracks = soa::Filtered<soa::Join<aod::Tracks, aod::TracksExtra, aod::TrackSelection>>;
93+
94+
void init(InitContext const&)
95+
{
96+
if (doprocessReco && doprocessRecoMC) {
97+
LOGF(fatal, "processReco and processRecoMC both fill EvShapeCoex; enable only one of them.");
98+
}
99+
if (doprocessRecoMC && !doprocessMC) {
100+
LOGF(fatal, "processRecoMC links to EvShapeCoexGen rows and requires processMC in the same job.");
101+
}
102+
}
103+
104+
/// Fills one EvShapeCoex row; returns false if the collision is rejected.
105+
template <typename TCollision>
106+
bool fillReco(TCollision const& coll, MyTracks const& tracks)
107+
{
108+
if (!coll.sel8() || std::abs(coll.posZ()) > vtxZCut) {
109+
return false;
110+
}
111+
112+
const float g = gapHalf;
113+
SubEventSums fwd, bwd;
114+
uint32_t nGap = 0, nPlus = 0, nMinus = 0, nPVC = 0;
115+
for (const auto& track : tracks) {
116+
if (track.isPVContributor()) {
117+
++nPVC;
118+
}
119+
const float eta = track.eta();
120+
if (eta > g) {
121+
fwd.add(track.pt(), track.phi());
122+
} else if (eta < -g) {
123+
bwd.add(track.pt(), track.phi());
124+
} else {
125+
++nGap;
126+
continue;
127+
}
128+
if (track.sign() > 0) {
129+
++nPlus;
130+
} else if (track.sign() < 0) {
131+
++nMinus;
132+
}
133+
}
134+
135+
// bit i of qaBits = QaBitOrder[i]
136+
static constexpr int NQaBits = 12;
137+
static constexpr o2::aod::evsel::EventSelectionFlags QaBitOrder[NQaBits] = {
138+
o2::aod::evsel::kNoSameBunchPileup, o2::aod::evsel::kIsGoodZvtxFT0vsPV,
139+
o2::aod::evsel::kIsVertexITSTPC, o2::aod::evsel::kIsVertexTOFmatched,
140+
o2::aod::evsel::kNoCollInTimeRangeNarrow, o2::aod::evsel::kNoCollInTimeRangeStrict,
141+
o2::aod::evsel::kNoCollInTimeRangeStandard, o2::aod::evsel::kNoCollInRofStrict,
142+
o2::aod::evsel::kNoCollInRofStandard, o2::aod::evsel::kNoHighMultCollInPrevRof,
143+
o2::aod::evsel::kNoITSROFrameBorder, o2::aod::evsel::kNoTimeFrameBorder};
144+
uint16_t qaBits = 0;
145+
for (int i = 0; i < NQaBits; ++i) {
146+
if (coll.selection_bit(QaBitOrder[i])) {
147+
qaBits |= static_cast<uint16_t>(1u << i);
148+
}
149+
}
150+
151+
const auto& bc = coll.template bc_as<aod::BCs>();
152+
153+
coex(static_cast<int>(coll.globalIndex()), bc.runNumber(), bc.globalBC(), coll.posZ(),
154+
coll.multFT0A(), coll.multFT0C(),
155+
static_cast<uint16_t>(fwd.n), static_cast<uint16_t>(bwd.n), static_cast<uint16_t>(nGap),
156+
fwd.meanPt(), bwd.meanPt(), static_cast<float>(fwd.sumPt2), static_cast<float>(bwd.sumPt2),
157+
static_cast<float>(fwd.qx2), static_cast<float>(fwd.qy2),
158+
static_cast<float>(bwd.qx2), static_cast<float>(bwd.qy2),
159+
static_cast<float>(fwd.qx4), static_cast<float>(fwd.qy4),
160+
static_cast<float>(bwd.qx4), static_cast<float>(bwd.qy4),
161+
static_cast<uint16_t>(nPlus), static_cast<uint16_t>(nMinus),
162+
qaBits, coll.trackOccupancyInTimeRange(), coll.ft0cOccupancyInTimeRange(),
163+
coll.numContrib(), coll.collisionTimeRes(), static_cast<uint16_t>(nPVC));
164+
return true;
165+
}
166+
167+
void processReco(MyCollisions::iterator const& coll, MyTracks const& tracks, aod::BCs const&)
168+
{
169+
fillReco(coll, tracks);
170+
}
171+
PROCESS_SWITCH(EventShapeCoex, processReco, "Reconstructed-level reduction (EvShapeCoex)", true);
172+
173+
void processRecoMC(MyCollisionsMc::iterator const& coll, MyTracks const& tracks, aod::BCs const&)
174+
{
175+
if (fillReco(coll, tracks)) {
176+
// EvShapeCoexGen has one row per McCollision, in order: the McCollision index is its row index
177+
coexMcLabels(coll.mcCollisionId());
178+
}
179+
}
180+
PROCESS_SWITCH(EventShapeCoex, processRecoMC, "Reconstructed-level reduction with MC labels (EvShapeCoex + EvShapeCoexMcLabels)", false);
181+
182+
void processMC(aod::McCollision const& mcCollision, aod::McParticles const& particles)
183+
{
184+
static constexpr double ChargeTolerance = 1.e-3;
185+
186+
const float g = gapHalf;
187+
const float em = etaMax;
188+
SubEventSums fwd, bwd;
189+
uint32_t nFwdA = 0, nFwdC = 0, nGap = 0, nPlus = 0, nMinus = 0;
190+
for (const auto& particle : particles) {
191+
if (!particle.isPhysicalPrimary()) {
192+
continue;
193+
}
194+
const auto* pdgParticle = pdg->GetParticle(particle.pdgCode());
195+
if (pdgParticle == nullptr) {
196+
continue; // unknown PDG code, charge undetermined
197+
}
198+
const double charge = pdgParticle->Charge();
199+
if (std::abs(charge) < ChargeTolerance) {
200+
continue;
201+
}
202+
const float eta = particle.eta();
203+
// forward counts: no pT window
204+
if (eta > etaFwdAMin && eta < etaFwdAMax) {
205+
++nFwdA;
206+
}
207+
if (eta > etaFwdCMin && eta < etaFwdCMax) {
208+
++nFwdC;
209+
}
210+
const float pt = particle.pt();
211+
if (pt <= ptMin || pt >= ptMax || std::abs(eta) >= em) {
212+
continue;
213+
}
214+
if (eta > g) {
215+
fwd.add(pt, particle.phi());
216+
} else if (eta < -g) {
217+
bwd.add(pt, particle.phi());
218+
} else {
219+
++nGap;
220+
continue;
221+
}
222+
if (charge > 0.) {
223+
++nPlus;
224+
} else {
225+
++nMinus;
226+
}
227+
}
228+
229+
coexGen(static_cast<int>(mcCollision.globalIndex()), mcCollision.posZ(),
230+
static_cast<uint16_t>(nFwdA), static_cast<uint16_t>(nFwdC),
231+
static_cast<uint16_t>(fwd.n), static_cast<uint16_t>(bwd.n), static_cast<uint16_t>(nGap),
232+
fwd.meanPt(), bwd.meanPt(), static_cast<float>(fwd.sumPt2), static_cast<float>(bwd.sumPt2),
233+
static_cast<float>(fwd.qx2), static_cast<float>(fwd.qy2),
234+
static_cast<float>(bwd.qx2), static_cast<float>(bwd.qy2),
235+
static_cast<float>(fwd.qx4), static_cast<float>(fwd.qy4),
236+
static_cast<float>(bwd.qx4), static_cast<float>(bwd.qy4),
237+
static_cast<uint16_t>(nPlus), static_cast<uint16_t>(nMinus));
238+
}
239+
PROCESS_SWITCH(EventShapeCoex, processMC, "Generator-level reduction (EvShapeCoexGen)", false);
240+
};
241+
242+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
243+
{
244+
return WorkflowSpec{adaptAnalysisTask<EventShapeCoex>(cfgc)};
245+
}

0 commit comments

Comments
 (0)