2020// / This task can also be configured to produce a table with reduced information used for correlation studies for track selection
2121// /
2222
23+ #include " qaEventTrack.h"
24+
2325#include " Framework/AnalysisTask.h"
2426#include " Framework/HistogramRegistry.h"
27+ #include " Framework/runDataProcessing.h"
28+ #include " Framework/AnalysisDataModel.h"
2529#include " ReconstructionDataFormats/DCA.h"
2630#include " Common/Core/trackUtilities.h"
27-
28- #include " Framework/AnalysisDataModel.h"
2931#include " Common/DataModel/EventSelection.h"
3032#include " Common/DataModel/TrackSelectionTables.h"
3133#include " Common/Core/TrackSelection.h"
3436using namespace o2 ;
3537using namespace o2 ::framework;
3638using namespace o2 ::framework::expressions;
37-
38- void customize (std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
39- {
40- std::vector<ConfigParamSpec> options{{" lite" , VariantType::Int, 0 , {" Run on skimmed DPG tracks" }}};
41- std::swap (workflowOptions, options);
42- }
43-
44- #include " Framework/runDataProcessing.h"
45-
46- using namespace o2 ::framework;
4739using namespace o2 ::dataformats;
4840
4941// TODO: add PID wagons as dependency + include impact parameter studies (same or separate task in workflow??)
5042
51- // --------------------------------------------------------------------------------------------------
52- // --------------------------------------------------------------------------------------------------
53- // Output table declaration
54- // --------------------------------------------------------------------------------------------------
55- // --------------------------------------------------------------------------------------------------
56- namespace o2 ::aod
57- {
58-
59- namespace dpgcollision
60- {
61- DECLARE_SOA_INDEX_COLUMN (BC, bc);
62- DECLARE_SOA_COLUMN (IsEventReject, isEventReject, int );
63- DECLARE_SOA_COLUMN (RunNumber, runNumber, int );
64- } // namespace dpgcollision
65-
66- DECLARE_SOA_TABLE (DPGCollisions, " AOD" , " DPGCollisions" , // ! Table of the DPG collisions
67- collision::PosZ,
68- dpgcollision::IsEventReject,
69- dpgcollision::RunNumber);
70-
71- namespace dpgtrack
72- {
73- DECLARE_SOA_INDEX_COLUMN (DPGCollision, dpgCollision); // ! Index to move from track to collision
74- DECLARE_SOA_COLUMN (Pt, pt, float ); // ! Pt
75- DECLARE_SOA_COLUMN (Eta, eta, float ); // ! Eta
76- DECLARE_SOA_COLUMN (Phi, phi, float ); // ! Phi
77- DECLARE_SOA_COLUMN (PtReso, ptReso, float ); // ! Pt resolution
78- DECLARE_SOA_COLUMN (Sign, sign, short ); // ! Sign
79- DECLARE_SOA_COLUMN (HasITS, hasITS, bool ); // ! Track has the ITS
80- DECLARE_SOA_COLUMN (HasTPC, hasTPC, bool ); // ! Track has the TPC
81- DECLARE_SOA_COLUMN (HasTRD, hasTRD, bool ); // ! Track has the TRD
82- DECLARE_SOA_COLUMN (HasTOF, hasTOF, bool ); // ! Track has the TOF
83- DECLARE_SOA_COLUMN (TPCNClsFound, tpcNClsFound, int16_t ); // ! Clusters found in TPC
84- DECLARE_SOA_COLUMN (TPCNClsCrossedRows, tpcNClsCrossedRows, int16_t ); // ! Crossed rows found in TPC
85- DECLARE_SOA_COLUMN (TPCCrossedRowsOverFindableCls, tpcCrossedRowsOverFindableCls, float ); // ! Crossed rows over findable clusters in TPC
86- DECLARE_SOA_COLUMN (TPCFoundOverFindableCls, tpcFoundOverFindableCls, float ); // ! Found over findable clusters in TPC
87- DECLARE_SOA_COLUMN (TPCFractionSharedCls, tpcFractionSharedCls, float ); // ! Fraction of shared clusters in TPC
88- DECLARE_SOA_COLUMN (ITSNCls, itsNCls, uint8_t ); // ! Clusters found in ITS
89- DECLARE_SOA_COLUMN (ITSNClsInnerBarrel, itsNClsInnerBarrel, uint8_t ); // ! Clusters found in the inner barrel of the ITS
90-
91- } // namespace dpgtrack
92-
93- DECLARE_SOA_TABLE (DPGTracks, " AOD" , " DPGTracks" , // ! Table of the DPG tracks
94- dpgtrack::DPGCollisionId,
95- dpgtrack::Pt, dpgtrack::Eta, dpgtrack::Phi, dpgtrack::PtReso,
96- track::Flags, dpgtrack::Sign,
97- track::DcaXY, track::DcaZ, track::Length,
98- track::ITSClusterMap,
99- track::ITSChi2NCl, track::TPCChi2NCl, track::TRDChi2, track::TOFChi2,
100- dpgtrack::HasITS, dpgtrack::HasTPC, dpgtrack::HasTRD, dpgtrack::HasTOF,
101- dpgtrack::TPCNClsFound, dpgtrack::TPCNClsCrossedRows,
102- dpgtrack::TPCCrossedRowsOverFindableCls, dpgtrack::TPCFoundOverFindableCls, dpgtrack::TPCFractionSharedCls,
103- dpgtrack::ITSNCls, dpgtrack::ITSNClsInnerBarrel);
104-
105- namespace dpgparticles
106- {
107- DECLARE_SOA_COLUMN (PtMC, ptMC, float ); // ! Pt MC
108- DECLARE_SOA_COLUMN (EtaMC, etaMC, float ); // ! Eta MC
109- DECLARE_SOA_COLUMN (PhiMC, phiMC, float ); // ! Phi MC
110- DECLARE_SOA_COLUMN (ProductionMode, productionMode, int ); // ! ProductionMode i.e. non matched (-1), physical primary (0), weak decay product (1) or material (2)
111-
112- } // namespace dpgparticles
113-
114- DECLARE_SOA_TABLE (DPGRecoParticles, " AOD" , " DPGRecoPart" , // ! Table of the DPG reconstructed particles
115- dpgparticles::PtMC, dpgparticles::EtaMC, dpgparticles::PhiMC,
116- mcparticle::PdgCode, dpgparticles::ProductionMode);
117-
118- DECLARE_SOA_TABLE (DPGNonRecoParticles, " AOD" , " DPGNonRecoPart" , // ! Table of the DPG particles
119- dpgparticles::PtMC, dpgparticles::EtaMC, dpgparticles::PhiMC,
120- mcparticle::PdgCode, dpgparticles::ProductionMode,
121- mcparticle::Vx, mcparticle::Vy, mcparticle::Vz);
122- } // namespace o2::aod
123-
12443// --------------------------------------------------------------------------------------------------
12544// --------------------------------------------------------------------------------------------------
12645// Task declaration
@@ -273,7 +192,7 @@ struct qaEventTrack {
273192 if (!collision.has_mcCollision ()) {
274193 return ;
275194 }
276- const auto particlesInCollision = particles.sliceBy (aod::mcparticle::mcCollisionId, collision.mcCollision ().globalIndex ());
195+ const auto & particlesInCollision = particles.sliceBy (aod::mcparticle::mcCollisionId, collision.mcCollision ().globalIndex ());
277196 tableNonRecoParticles.reserve (particlesInCollision.size () - nTracks);
278197 for (const auto & particle : particlesInCollision) {
279198 const auto partReconstructed = std::find (recoPartIndices.begin (), recoPartIndices.end (), particle.globalIndex ()) != recoPartIndices.end ();
@@ -295,197 +214,9 @@ struct qaEventTrack {
295214 }
296215};
297216
298- struct qaEventTrackLite { // Lite version of the QA task to run on skimmed dataset
299- ConfigurableAxis binsPt{" binsPt" , {VARIABLE_WIDTH, 0.0 , 0.1 , 0.2 , 0.3 , 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 , 1.0 , 1.1 , 1.2 , 1.3 , 1.4 , 1.5 , 2.0 , 5.0 , 10.0 , 20.0 , 50.0 }, " " };
300- ConfigurableAxis binsImpPar{" binsImpPar" , {200 , -0.15 , 0.15 }, " Impact parameter binning (cm)" };
301-
302- HistogramRegistry histos;
303-
304- Configurable<bool > bItsStandalone{" bItsStandalone" , false , " Select only ITS standalone DPG tracks" };
305- Configurable<bool > bTpcOnly{" bTpcOnly" , false , " Select only TPC only DPG tracks" };
306- Configurable<bool > bItsTpcMatched{" bItsTpcMatched" , false , " Select ITS-TPC matched DPG tracks" };
307- // Kinematic selections
308- Configurable<float > ptMin{" ptMin" , 0 ., " Minimum track pt" };
309- Configurable<float > etaMin{" etaMin" , -10 ., " Minimum eta for DPG tracks" };
310- Configurable<float > etaMax{" etaMax" , 10 ., " Maximum eta for DPG tracks" };
311- // ITS selections
312- Configurable<float > chi2ItsMin{" chi2ItsMin" , -1001 .f , " Max ITS chi2" };
313- Configurable<float > chi2ItsMax{" chi2ItsMax" , 1000 .f , " Max ITS chi2" };
314- // TPC selections
315- Configurable<int > nClusterTpcMin{" nClusterTpcMin" , -1001 , " Minimum number of TPC clusters" };
316- Configurable<int > nCrossedRowsTpcMin{" nCrossedRowsTpcMin" , -1001 , " Minimum number of TPC crossed rows" };
317- Configurable<float > nCrossedRowsTpcOverFindableClustersTpcMin{" nCrossedRowsTpcOverFindableClustersTpcMin" , -1 , " Minimum ratio between TPC crossed rows and findable clusters" };
318- Configurable<float > chi2TpcMin{" chi2TpcMin" , -1001 .f , " Max TPC chi2" };
319- Configurable<float > chi2TpcMax{" chi2TpcMax" , 1000 .f , " Max TPC chi2" };
320- // TOF selections
321- Configurable<float > chi2TofMin{" chi2TofMin" , -1001 .f , " Max TOF chi2" };
322- Configurable<float > lengthMin{" lengthMin" , -1001 .f , " Min length" };
323-
324- void init (InitContext const &)
325- {
326- const AxisSpec axisPt{binsPt, " #it{p}_{T} [GeV/c]" };
327-
328- // kine histograms
329- histos.add (" Tracks/VertexPositionZ" , " " , kTH1D , {{100 , -20 .f , 20 .f , " Vertex Z [cm]" }});
330- histos.add (" Tracks/Kine/pt" , " #it{p}_{T};#it{p}_{T} [GeV/c]" , kTH1D , {{axisPt}});
331- histos.add (" Tracks/Kine/eta" , " #eta;#eta" , kTH1D , {{800 , -2 ., 2 .}});
332- histos.add (" Tracks/Kine/phi" , " #phi;#phi [rad]" , kTH1D , {{180 , 0 ., 2 * M_PI}});
333- histos.add (" Tracks/length" , " track length in cm;#it{Length} [cm];" , kTH1D , {{400 , 0 , 1000 }});
334- const AxisSpec axisImpParRPhi{binsImpPar, " #it{d}_{r#it{#varphi}} (#cm)" };
335- const AxisSpec axisImpParZAxis{binsImpPar, " #it{d}_{z} (#cm)" };
336- histos.add (" Tracks/dcaXY" , " distance of closest approach in #it{xy} plane" , kTH1D , {axisImpParRPhi});
337- histos.add (" Tracks/dcaZ" , " distance of closest approach in #it{z}" , kTH1D , {axisImpParZAxis});
338- histos.add (" Tracks/dcaXYvsPt" , " d_#it{xy} vs. #it{p}_{T}" , kTH2D , {axisPt, axisImpParRPhi});
339- histos.add (" Tracks/dcaZvsPt" , " d_#it{z} vs. #it{p}_{T}" , kTH2D , {axisPt, axisImpParRPhi});
340-
341- // its histograms
342- histos.add (" Tracks/ITS/itsChi2NCl" , " chi2 per ITS cluster;chi2 / cluster ITS" , kTH1D , {{100 , 0 , 40 }});
343- histos.add (" Tracks/ITS/itsNCl" , " ITS number of clusters;# clusters ITS" , kTH1D , {{8 , -0.5 , 7.5 }});
344- histos.add (" Tracks/ITS/itsNClvsItsHitmap" , " ITS number of clusters vs. ITS hitmap;# clusters ITS; ITS hitmap" , kTH2D , {{8 , -0.5 , 7.5 , " # clusters ITS" }, {128 , 0 , 128 , " ITS hitmap" }});
345- // tpc histograms
346- histos.add (" Tracks/TPC/tpcChi2NCl" , " chi2 per cluster in TPC;chi2 / cluster TPC" , kTH1D , {{100 , 0 , 10 }});
347- histos.add (" Tracks/TPC/tpcNClsFound" , " number of found TPC clusters;# clusters TPC" , kTH1D , {{165 , -0.5 , 164.5 }});
348- histos.add (" Tracks/TPC/tpcCrossedRows" , " number of crossed TPC rows;# crossed rows TPC" , kTH1D , {{165 , -0.5 , 164.5 }});
349- histos.add (" Tracks/TPC/tpcCrossedRowsOverFindableCls" , " crossed TPC rows over findable clusters;crossed rows / findable clusters TPC" , kTH1D , {{60 , 0.7 , 1.3 }});
350- histos.add (" Tracks/TPC/tpcNClsFoundvsPt" , " " , kTH2D , {axisPt, {165 , -0.5 , 164.5 , " # clusters TPC" }});
351- histos.add (" Tracks/TPC/tpcCrossedRowsvsPt" , " " , kTH2D , {axisPt, {165 , -0.5 , 164.5 , " # crossed rows TPC" }});
352- histos.add (" Tracks/TPC/tpcCrossedRowsOverFindableClsvsPt" , " " , kTH2D , {axisPt, {60 , 0.7 , 1.3 , " crossed rows / findable clusters TPC" }});
353- // trd histograms
354- histos.add (" Tracks/TRD/trdChi2" , " chi2 in TRD" , kTH1D , {{100 , 0 , 10 , " chi2 / cluster TRD" }});
355- // tof histograms
356- histos.add (" Tracks/TOF/tofChi2" , " chi2 in TOF" , kTH1D , {{100 , 0 , 10 , " chi2 / cluster TOF" }});
357- // matching histogram
358- histos.add (" Tracks/matchedDet" , " matched detectors" , kTH1D , {{4 , 0.5 , 4.5 , " " }});
359- histos.get <TH1>(HIST (" Tracks/matchedDet" ))->GetXaxis ()->SetBinLabel (1 , " hasTPC" );
360- histos.get <TH1>(HIST (" Tracks/matchedDet" ))->GetXaxis ()->SetBinLabel (2 , " hasITS" );
361- histos.get <TH1>(HIST (" Tracks/matchedDet" ))->GetXaxis ()->SetBinLabel (3 , " hasTRD" );
362- histos.get <TH1>(HIST (" Tracks/matchedDet" ))->GetXaxis ()->SetBinLabel (4 , " hasTOF" );
363- // kinematics
364- histos.add (" Tracks/relativeResoPt" , " relative #it{p}_{T} resolution;#sigma(#it{p}_{T})/#it{p}_{T};#it{p}_{T};" , kTH2D , {{axisPt, {500 , 0 ., 1 , " #sigma{#it{p}}/#it{p}_{T}" }}});
365- histos.add (" Tracks/relativeResoPtMean" , " mean relative #it{p}_{T} resolution;#LT(#it{p}_{T})/#it{p}_{T}#GT;#it{p}_{T};" , kTProfile , {axisPt});
366-
367- // MC histograms
368- if (doprocessMCLite) {
369- histos.add (" Particle/PDGs" , " Particle PDGs;PDG Code" , kTH1D , {{100 , 0 .f , 100 .f }});
370- }
371- }
372-
373- // /////////////
374- // / Filters ///
375- // /////////////
376- // Kinematics
377- Filter ptCut = o2::aod::dpgtrack::pt > ptMin;
378- Filter etaCut = etaMin < o2::aod::dpgtrack::eta && o2::aod::dpgtrack::eta < etaMax;
379- // Detector matching
380- Filter itsStandaloneTracks = (bItsStandalone.node() == false ) || (o2::aod::dpgtrack::hasITS == true && o2::aod::dpgtrack::hasTPC == false );
381- Filter tpcOnlyTracks = (bTpcOnly.node() == false ) || (o2::aod::dpgtrack::hasITS == false && o2::aod::dpgtrack::hasTPC == true );
382- Filter itsTpcMatchedTracks = (bItsTpcMatched.node() == false ) || (o2::aod::dpgtrack::hasITS == true && o2::aod::dpgtrack::hasTPC == true );
383- // ITS
384- Filter itsChi2 = (bTpcOnly.node() == true ) || (chi2ItsMin < o2::aod::track::itsChi2NCl && o2::aod::track::itsChi2NCl < chi2ItsMax);
385- // TPC
386- Filter tpcChi2s = (bItsStandalone.node() == true ) || (chi2TpcMin < o2::aod::track::tpcChi2NCl && o2::aod::track::tpcChi2NCl < chi2TpcMax);
387- Filter tpcNclusters = (bItsStandalone.node() == true ) || (o2::aod::dpgtrack::tpcNClsFound > (int16_t )nClusterTpcMin);
388- Filter tpcNcrossedRows = (bItsStandalone.node() == true ) || (o2::aod::dpgtrack::tpcNClsCrossedRows > (int16_t )nCrossedRowsTpcMin);
389- Filter tpcNcrossedRowsOverFindableClusters = (bItsStandalone.node() == true ) || (o2::aod::dpgtrack::tpcCrossedRowsOverFindableCls > nCrossedRowsTpcOverFindableClustersTpcMin);
390- // TOF
391- Filter tofChi = o2::aod::track::tofChi2 > chi2TofMin;
392- Filter length = o2::aod::track::length > lengthMin;
393-
394- // Process data
395- void processDataLite (o2::soa::Filtered<aod::DPGTracks> const & tracks, aod::DPGCollisions const &)
396- {
397- for (const auto & track : tracks) {
398- histos.fill (HIST (" Tracks/VertexPositionZ" ), track.dpgCollision ().posZ ());
399- histos.fill (HIST (" Tracks/Kine/pt" ), track.pt ());
400- histos.fill (HIST (" Tracks/Kine/eta" ), track.eta ());
401- histos.fill (HIST (" Tracks/Kine/phi" ), track.phi ());
402- histos.fill (HIST (" Tracks/dcaXY" ), track.dcaXY ());
403- histos.fill (HIST (" Tracks/dcaZ" ), track.dcaZ ());
404- histos.fill (HIST (" Tracks/dcaXYvsPt" ), track.pt (), track.dcaXY ());
405- histos.fill (HIST (" Tracks/dcaZvsPt" ), track.pt (), track.dcaZ ());
406- histos.fill (HIST (" Tracks/length" ), track.length ());
407- histos.fill (HIST (" Tracks/ITS/itsChi2NCl" ), track.itsChi2NCl ());
408- histos.fill (HIST (" Tracks/ITS/itsNCl" ), track.itsNCls ());
409- histos.fill (HIST (" Tracks/ITS/itsNClvsItsHitmap" ), track.itsNCls (), track.itsClusterMap ());
410- histos.fill (HIST (" Tracks/TPC/tpcChi2NCl" ), track.tpcChi2NCl ());
411- histos.fill (HIST (" Tracks/TPC/tpcNClsFound" ), track.tpcNClsFound ());
412- histos.fill (HIST (" Tracks/TPC/tpcCrossedRows" ), track.tpcNClsCrossedRows ());
413- histos.fill (HIST (" Tracks/TPC/tpcCrossedRowsOverFindableCls" ), track.tpcCrossedRowsOverFindableCls ());
414- histos.fill (HIST (" Tracks/TPC/tpcNClsFoundvsPt" ), track.pt (), track.tpcNClsFound ());
415- histos.fill (HIST (" Tracks/TPC/tpcCrossedRowsvsPt" ), track.pt (), track.tpcNClsCrossedRows ());
416- histos.fill (HIST (" Tracks/TPC/tpcCrossedRowsOverFindableClsvsPt" ), track.pt (), track.tpcCrossedRowsOverFindableCls ());
417- histos.fill (HIST (" Tracks/TRD/trdChi2" ), track.trdChi2 ());
418- histos.fill (HIST (" Tracks/TOF/tofChi2" ), track.tofChi2 ());
419- if (track.hasTPC ()) {
420- histos.fill (HIST (" Tracks/matchedDet" ), 1 );
421- }
422- if (track.hasITS ()) {
423- histos.fill (HIST (" Tracks/matchedDet" ), 2 );
424- }
425- if (track.hasTRD ()) {
426- histos.fill (HIST (" Tracks/matchedDet" ), 3 );
427- }
428- if (track.hasTOF ()) {
429- histos.fill (HIST (" Tracks/matchedDet" ), 4 );
430- }
431- histos.fill (HIST (" Tracks/relativeResoPt" ), track.pt (), track.ptReso ());
432- histos.fill (HIST (" Tracks/relativeResoPtMean" ), track.pt (), track.ptReso ());
433- }
434- }
435- PROCESS_SWITCH (qaEventTrackLite, processDataLite, " process data lite" , true );
436-
437- // Process MC
438- void processMCLite (o2::soa::Filtered<soa::Join<aod::DPGTracks, aod::DPGNonRecoParticles>> const & tracks, aod::DPGCollisions const &)
439- {
440- for (const auto & track : tracks) {
441- if (track.productionMode () == 0 ) {
442- histos.get <TH1>(HIST (" Particle/PDGs" ))->Fill (Form (" %i" , track.pdgCode ()), 1 );
443- }
444-
445- histos.fill (HIST (" Tracks/Kine/pt" ), track.pt ());
446- histos.fill (HIST (" Tracks/Kine/eta" ), track.eta ());
447- histos.fill (HIST (" Tracks/Kine/phi" ), track.phi ());
448- histos.fill (HIST (" Tracks/dcaXY" ), track.dcaXY ());
449- histos.fill (HIST (" Tracks/dcaZ" ), track.dcaZ ());
450- histos.fill (HIST (" Tracks/dcaXYvsPt" ), track.pt (), track.dcaXY ());
451- histos.fill (HIST (" Tracks/dcaZvsPt" ), track.pt (), track.dcaZ ());
452- histos.fill (HIST (" Tracks/length" ), track.length ());
453- histos.fill (HIST (" Tracks/ITS/itsChi2NCl" ), track.itsChi2NCl ());
454- histos.fill (HIST (" Tracks/TPC/tpcChi2NCl" ), track.tpcChi2NCl ());
455- histos.fill (HIST (" Tracks/TPC/tpcNClsFound" ), track.tpcNClsFound ());
456- histos.fill (HIST (" Tracks/TPC/tpcCrossedRows" ), track.tpcNClsCrossedRows ());
457- histos.fill (HIST (" Tracks/TPC/tpcCrossedRowsOverFindableCls" ), track.tpcCrossedRowsOverFindableCls ());
458- histos.fill (HIST (" Tracks/TPC/tpcNClsFoundvsPt" ), track.pt (), track.tpcNClsFound ());
459- histos.fill (HIST (" Tracks/TPC/tpcCrossedRowsvsPt" ), track.pt (), track.tpcNClsCrossedRows ());
460- histos.fill (HIST (" Tracks/TPC/tpcCrossedRowsOverFindableClsvsPt" ), track.pt (), track.tpcCrossedRowsOverFindableCls ());
461- histos.fill (HIST (" Tracks/TRD/trdChi2" ), track.trdChi2 ());
462- histos.fill (HIST (" Tracks/TOF/tofChi2" ), track.tofChi2 ());
463- if (track.hasTPC ()) {
464- histos.fill (HIST (" Tracks/matchedDet" ), 1 );
465- }
466- if (track.hasITS ()) {
467- histos.fill (HIST (" Tracks/matchedDet" ), 2 );
468- }
469- if (track.hasTRD ()) {
470- histos.fill (HIST (" Tracks/matchedDet" ), 3 );
471- }
472- if (track.hasTOF ()) {
473- histos.fill (HIST (" Tracks/matchedDet" ), 4 );
474- }
475- }
476- }
477- PROCESS_SWITCH (qaEventTrackLite, processMCLite, " process MC lite" , false );
478- };
479-
480217WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
481218{
482- WorkflowSpec workflow;
483- if (cfgc.options ().get <int >(" lite" )) {
484- workflow.push_back (adaptAnalysisTask<qaEventTrackLite>(cfgc));
485- } else {
486- workflow.push_back (adaptAnalysisTask<qaEventTrack>(cfgc));
487- }
488- return workflow;
219+ return WorkflowSpec{adaptAnalysisTask<qaEventTrack>(cfgc)};
489220}
490221
491222// --------------------------------------------------------------------------------------------------
0 commit comments