@@ -55,6 +55,7 @@ namespace o2::aod
5555using FemtoFullCollision = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Ms>::iterator;
5656using FemtoFullCollisionMC = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Ms, aod::McCollisionLabels>::iterator;
5757using FemtoFullCollision_noCent_MC = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::McCollisionLabels>::iterator;
58+ using FemtoFullCollision_CentPbPb = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Ms, aod::CentFT0Cs, aod::CentFV0As, aod::QvectorFT0CVecs>::iterator;
5859
5960using FemtoFullTracks = soa::Join<aod::FullTracks, aod::TracksDCA,
6061 aod::pidTPCFullEl, aod::pidTPCFullMu, aod::pidTPCFullPi, aod::pidTPCFullKa,
@@ -66,6 +67,7 @@ using FemtoFullTracks = soa::Join<aod::FullTracks, aod::TracksDCA,
6667struct femtoDreamProducerReducedTask {
6768
6869 Produces<aod::FDCollisions> outputCollision;
70+ Produces<aod::FDExtQnCollisions> outputExtQnCollision;
6971 Produces<aod::FDParticles> outputParts;
7072 Produces<aod::FDMCParticles> outputPartsMC;
7173 Produces<aod::FDExtParticles> outputDebugParts;
@@ -104,14 +106,39 @@ struct femtoDreamProducerReducedTask {
104106 Configurable<std::vector<float >> ConfTrkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName (femtoDreamTrackSelection::kITSnClsIbMin , " ConfTrk" ), std::vector<float >{-1 .f , 1 .f }, FemtoDreamTrackSelection::getSelectionHelper (femtoDreamTrackSelection::kITSnClsIbMin , " Track selection: " )};
105107 Configurable<std::vector<float >> ConfTrkDCAxyMax{FemtoDreamTrackSelection::getSelectionName (femtoDreamTrackSelection::kDCAxyMax , " ConfTrk" ), std::vector<float >{0 .1f , 0 .5f }, FemtoDreamTrackSelection::getSelectionHelper (femtoDreamTrackSelection::kDCAxyMax , " Track selection: " )}; // / here we need an open cut to do the DCA fits later on!
106108 Configurable<std::vector<float >> ConfTrkDCAzMax{FemtoDreamTrackSelection::getSelectionName (femtoDreamTrackSelection::kDCAzMax , " ConfTrk" ), std::vector<float >{0 .2f , 0 .5f }, FemtoDreamTrackSelection::getSelectionHelper (femtoDreamTrackSelection::kDCAzMax , " Track selection: " )};
107- Configurable<std::vector<float >> ConfTrkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName (femtoDreamTrackSelection::kPIDnSigmaMax , " Conf " ), std::vector<float >{3 .5f , 3 .f , 2 .5f }, FemtoDreamTrackSelection::getSelectionHelper (femtoDreamTrackSelection::kPIDnSigmaMax , " Track selection: " )};
109+ Configurable<std::vector<float >> ConfTrkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName (femtoDreamTrackSelection::kPIDnSigmaMax , " ConfTrk " ), std::vector<float >{3 .5f , 3 .f , 2 .5f }, FemtoDreamTrackSelection::getSelectionHelper (femtoDreamTrackSelection::kPIDnSigmaMax , " Track selection: " )};
108110 // off set the center of the nsigma distribution to deal with bad TPC/TOF calibration
109111 Configurable<float > ConfTrkPIDnSigmaOffsetTPC{" ConfTrkPIDnSigmaOffsetTPC" , 0 ., " Offset for TPC nSigma because of bad calibration" };
110112 Configurable<float > ConfTrkPIDnSigmaOffsetTOF{" ConfTrkPIDnSigmaOffsetTOF" , 0 ., " Offset for TOF nSigma because of bad calibration" };
111113 Configurable<std::vector<int >> ConfTrkPIDspecies{" ConfTrkPIDspecies" , std::vector<int >{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, " Trk sel: Particles species for PID" };
112114
115+ struct : o2::framework::ConfigurableGroup {
116+ Configurable<bool > ConfgFlowCalculate{" ConfgFlowCalculate" , false , " Evt sel: Cumulant of flow" }; // To do
117+ Configurable<bool > ConfgQnSeparation{" ConfgQnSeparation" , false , " Evt sel: Qn of event" };
118+ Configurable<std::vector<float >> ConfQnBinSeparator{" ConfQnBinSeparator" , std::vector<float >{-999 .f , -999 .f , -999 .f }, " Qn bin separator" };
119+ Configurable<float > ConfCentralityMax{" ConfCentralityMax" , 80 .f , " Evt sel: Maximum Centrality cut" };
120+ Configurable<float > ConfCentBinWidth{" ConfCentBinWidth" , 1 .f , " Centrality bin length for qn separator" };
121+ Configurable<int > ConfQnBinMin{" ConfQnBinMin" , 0 , " Minimum qn bin" };
122+ Configurable<int > ConfQnBinMax{" ConfQnBinMax" , 10 , " Maximum qn bin" };
123+ } qnCal;
124+
125+ struct : o2::framework::ConfigurableGroup {
126+ Configurable<bool > ConfIsPbPb{" ConfIsPbPb" , false , " Running on Run3 or Run2" }; // Choose if running on PbPb data
127+ Configurable<bool > ConfIsUsePileUp{" ConfIsUsePileUp" , false , " Required for choosing whether to run the pile-up cuts" };
128+ Configurable<bool > ConfEvNoSameBunchPileup{" ConfEvNoSameBunchPileup" , false , " Require kNoSameBunchPileup selection on Events." };
129+ Configurable<bool > ConfEvIsGoodZvtxFT0vsPV{" ConfEvIsGoodZvtxFT0vsPV" , false , " Require kIsGoodZvtxFT0vsPV selection on Events." };
130+ Configurable<bool > ConfEvIsGoodITSLayersAll{" ConfEvIsGoodITSLayersAll" , false , " Require kIsGoodITSLayersAll selection on Events." };
131+ Configurable<bool > ConfEvNoCollInRofStandard{" ConfEvNoCollInRofStandard" , false , " Require kNoCollInRofStandard selection on Events." };
132+ Configurable<bool > ConfEvNoHighMultCollInPrevRof{" ConfEvNoHighMultCollInPrevRof" , false , " Require kNoHighMultCollInPrevRof selection on Events." };
133+ Configurable<bool > ConfEvNoCollInTimeRangeStandard{" ConfEvNoCollInTimeRangeStandard" , false , " Require kNoCollInTimeRangeStandard selection on Events." };
134+ Configurable<bool > ConfEvIsVertexITSTPC{" ConfEvIsVertexITSTPC" , false , " Require kIsVertexITSTPC selection on Events" };
135+ Configurable<int > ConfTPCOccupancyMin{" ConfTPCOccupancyMin" , 0 , " Minimum value for TPC Occupancy selection" };
136+ Configurable<int > ConfTPCOccupancyMax{" ConfTPCOccupancyMax" , 1000 , " Maximum value for TPC Occupancy selection" };
137+ } evtSel_PbPb;
138+
113139 HistogramRegistry qaRegistry{" QAHistos" , {}, OutputObjHandlingPolicy::AnalysisObject};
114140 HistogramRegistry Registry{" Tracks" , {}, OutputObjHandlingPolicy::AnalysisObject};
141+ HistogramRegistry FlowRegistry{" QnandFlowInfo" , {}, OutputObjHandlingPolicy::AnalysisObject};
115142
116143 int mRunNumber ;
117144 float mMagField ;
@@ -144,6 +171,11 @@ struct femtoDreamProducerReducedTask {
144171 trackCuts.init <aod::femtodreamparticle::ParticleType::kTrack ,
145172 aod::femtodreamparticle::TrackType::kNoChild ,
146173 aod::femtodreamparticle::cutContainerType>(&qaRegistry, &Registry);
174+
175+ if (qnCal.ConfgFlowCalculate ){
176+ colCuts.initFlow (&FlowRegistry, qnCal.ConfgQnSeparation );
177+ }
178+
147179 mRunNumber = 0 ;
148180 mMagField = 0.0 ;
149181 // / Initializing CCDB
@@ -330,8 +362,166 @@ struct femtoDreamProducerReducedTask {
330362 }
331363 }
332364
333- void
334- processData (aod::FemtoFullCollision const & col, aod::BCsWithTimestamps const &, aod::FemtoFullTracks const & tracks)
365+ // Centrality (Multiplicity percentile) obtained from FT0C
366+ // Pile-up rejection involved
367+ template <bool isMC, bool useCentrality, typename CollisionType, typename TrackType>
368+ void fillCollisionsAndTracks_PbPb (CollisionType const & col, TrackType const & tracks)
369+ {
370+ const auto vtxZ = col.posZ ();
371+ const auto spher = colCuts.computeSphericity (col, tracks);
372+ int mult = 0 ;
373+ int multNtr = 0 ;
374+ if (ConfIsRun3) {
375+ if constexpr (useCentrality) {
376+ mult = col.centFT0C ();
377+ } else {
378+ mult = 0 .;
379+ }
380+ multNtr = col.multNTracksPV ();
381+ } else {
382+ mult = 1 ; // multiplicity percentile is known in Run 2
383+ multNtr = col.multTracklets ();
384+ }
385+ if (ConfEvtUseTPCmult) {
386+ multNtr = col.multTPC ();
387+ }
388+ colCuts.fillQA (col, mult);
389+
390+ // / First thing to do is to check whether the basic event selection criteria are fulfilled
391+ // / That includes checking if there are any usable tracks in a collision
392+ if (!colCuts.isSelectedCollision (col)) {
393+ return ;
394+ }
395+ if (colCuts.isEmptyCollision (col, tracks, trackCuts)) {
396+ return ;
397+ }
398+
399+ // Pileup rejection in PbPb data
400+ if (evtSel_PbPb.ConfIsPbPb && evtSel_PbPb.ConfIsUsePileUp &&
401+ !colCuts.isPileUpCollisionPbPb (col, evtSel_PbPb.ConfEvNoSameBunchPileup , evtSel_PbPb.ConfEvIsGoodZvtxFT0vsPV ,
402+ evtSel_PbPb.ConfEvIsGoodITSLayersAll , evtSel_PbPb.ConfEvNoCollInRofStandard ,
403+ evtSel_PbPb.ConfEvNoHighMultCollInPrevRof , evtSel_PbPb.ConfEvNoCollInTimeRangeStandard ,
404+ evtSel_PbPb.ConfEvIsVertexITSTPC ,
405+ evtSel_PbPb.ConfTPCOccupancyMin , evtSel_PbPb.ConfTPCOccupancyMax )) {
406+ return ;
407+ }
408+ // now the table is filled
409+ outputCollision (vtxZ, mult, multNtr, spher, mMagField );
410+
411+ // these IDs are necessary to keep track of the children
412+ // since this producer only produces the tables for tracks, there are no children
413+ std::vector<int > childIDs = {0 , 0 };
414+ for (auto & track : tracks) {
415+ // / if the most open selection criteria are not fulfilled there is no point looking further at the track
416+ if (!trackCuts.isSelectedMinimal (track)) {
417+ continue ;
418+ }
419+ trackCuts.fillQA <aod::femtodreamparticle::ParticleType::kTrack , aod::femtodreamparticle::TrackType::kNoChild >(track);
420+ // an array of two bit-wise containers of the systematic variations is obtained
421+ // one container for the track quality cuts and one for the PID cuts
422+ auto cutContainer = trackCuts.getCutContainer <true , aod::femtodreamparticle::cutContainerType>(track, track.pt (), track.eta (), sqrtf (powf (track.dcaXY (), 2 .f ) + powf (track.dcaZ (), 2 .f )));
423+
424+ // now the table is filled
425+ outputParts (outputCollision.lastIndex (),
426+ track.pt (),
427+ track.eta (),
428+ track.phi (),
429+ aod::femtodreamparticle::ParticleType::kTrack ,
430+ cutContainer.at (femtoDreamTrackSelection::TrackContainerPosition::kCuts ),
431+ cutContainer.at (femtoDreamTrackSelection::TrackContainerPosition::kPID ),
432+ track.dcaXY (), childIDs, 0 , 0 );
433+ if constexpr (isMC) {
434+ fillMCParticle (col, track, o2::aod::femtodreamparticle::ParticleType::kTrack );
435+ }
436+
437+ if (ConfIsDebug) {
438+ outputDebugParts (track.sign (),
439+ (uint8_t )track.tpcNClsFound (),
440+ track.tpcNClsFindable (),
441+ (uint8_t )track.tpcNClsCrossedRows (),
442+ track.tpcNClsShared (),
443+ track.tpcInnerParam (),
444+ track.itsNCls (),
445+ track.itsNClsInnerBarrel (),
446+ track.dcaXY (),
447+ track.dcaZ (),
448+ track.tpcSignal (),
449+ track.tpcNSigmaEl (),
450+ track.tpcNSigmaPi (),
451+ track.tpcNSigmaKa (),
452+ track.tpcNSigmaPr (),
453+ track.tpcNSigmaDe (),
454+ track.tpcNSigmaTr (),
455+ track.tpcNSigmaHe (),
456+ track.tofNSigmaEl (),
457+ track.tofNSigmaPi (),
458+ track.tofNSigmaKa (),
459+ track.tofNSigmaPr (),
460+ track.tofNSigmaDe (),
461+ track.tofNSigmaTr (),
462+ track.tofNSigmaHe (),
463+ -1 ,
464+ track.itsNSigmaEl (),
465+ track.itsNSigmaPi (),
466+ track.itsNSigmaKa (),
467+ track.itsNSigmaPr (),
468+ track.itsNSigmaDe (),
469+ track.itsNSigmaTr (),
470+ track.itsNSigmaHe (),
471+ -999 ., -999 ., -999 ., -999 ., -999 ., -999 .,
472+ -999 ., -999 ., -999 ., -999 ., -999 ., -999 ., -999 .);
473+ }
474+ }
475+ }
476+
477+ // Calculate and separate qn bins
478+ // Do and fill cumulant in qn bins
479+ template <bool isMC, typename CollisionType, typename TrackType>
480+ void fillCollisionsFlow (CollisionType const & col, TrackType const & tracks)
481+ {
482+ // get magnetic field for run
483+
484+ const auto spher = colCuts.computeSphericity (col, tracks);
485+ int multNtr = 0 ;
486+ if (ConfIsRun3) {
487+ multNtr = col.multNTracksPV ();
488+ } else {
489+ multNtr = col.multTracklets ();
490+ }
491+ if (ConfEvtUseTPCmult) {
492+ multNtr = col.multTPC ();
493+ }
494+
495+ // / First thing to do is to check whether the basic event selection criteria are fulfilled
496+ // / That includes checking if there are any usable tracks in a collision
497+ if (!colCuts.isSelectedCollision (col)) {
498+ return ;
499+ }
500+ if (colCuts.isEmptyCollision (col, tracks, trackCuts)) {
501+ return ;
502+ }
503+
504+ // Pileup rejection in PbPb data
505+ if (evtSel_PbPb.ConfIsPbPb && evtSel_PbPb.ConfIsUsePileUp &&
506+ !colCuts.isPileUpCollisionPbPb (col, evtSel_PbPb.ConfEvNoSameBunchPileup , evtSel_PbPb.ConfEvIsGoodZvtxFT0vsPV ,
507+ evtSel_PbPb.ConfEvIsGoodITSLayersAll , evtSel_PbPb.ConfEvNoCollInRofStandard ,
508+ evtSel_PbPb.ConfEvNoHighMultCollInPrevRof , evtSel_PbPb.ConfEvNoCollInTimeRangeStandard ,
509+ evtSel_PbPb.ConfEvIsVertexITSTPC ,
510+ evtSel_PbPb.ConfTPCOccupancyMin , evtSel_PbPb.ConfTPCOccupancyMax )) {
511+ return ;
512+ }
513+
514+ // Calculate and fill qnBins
515+ auto qnBin = colCuts.myqnBin (col, qnCal.ConfCentralityMax , qnCal.ConfQnBinSeparator , spher, multNtr, 1 .f );
516+ if (qnBin < qnCal.ConfQnBinMin || qnBin > qnCal.ConfQnBinMax ){
517+ qnBin = -999 ;
518+ }
519+ colCuts.fillCumulants (col, tracks);
520+ colCuts.doCumulants (col, qnCal.ConfgQnSeparation , qnBin);
521+ outputExtQnCollision (qnBin);
522+ }
523+
524+ void processData (aod::FemtoFullCollision const & col, aod::BCsWithTimestamps const &, aod::FemtoFullTracks const & tracks)
335525 {
336526 // get magnetic field for run
337527 getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
@@ -370,8 +560,24 @@ struct femtoDreamProducerReducedTask {
370560 fillCollisionsAndTracks<true , false >(col, tracksWithItsPid);
371561 }
372562 PROCESS_SWITCH (femtoDreamProducerReducedTask, processMC_noCentrality, " Provide MC data" , false );
563+
564+ void processData_FlowCalc (aod::FemtoFullCollision_CentPbPb const & col,
565+ aod::BCsWithTimestamps const &,
566+ aod::FemtoFullTracks const & tracks)
567+ {
568+ // get magnetic field for run
569+ getMagneticFieldTesla (col.bc_as <aod::BCsWithTimestamps>());
570+ auto tracksWithItsPid = soa::Attach<aod::FemtoFullTracks, aod::pidits::ITSNSigmaEl, aod::pidits::ITSNSigmaPi, aod::pidits::ITSNSigmaKa,
571+ aod::pidits::ITSNSigmaPr, aod::pidits::ITSNSigmaDe, aod::pidits::ITSNSigmaTr, aod::pidits::ITSNSigmaHe>(tracks);
572+ // fill the tables
573+ fillCollisionsAndTracks_PbPb<false , true >(col, tracksWithItsPid);
574+ if (qnCal.ConfgQnSeparation ){
575+ fillCollisionsFlow<false >(col, tracksWithItsPid);
576+ }
577+ }
578+ PROCESS_SWITCH (femtoDreamProducerReducedTask, processData_FlowCalc,
579+ " Provide experimental data with cumulant flow calculation" , false );
373580};
374-
375581WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
376582{
377583 WorkflowSpec workflow{adaptAnalysisTask<femtoDreamProducerReducedTask>(cfgc)};
0 commit comments