88// In applying this license CERN does not waive the privileges and immunities
99// granted to it by virtue of its status as an Intergovernmental Organization
1010// or submit itself to any jurisdiction.
11+
1112// / \file FactorialMomentsTask.cxx
1213// / \brief This task is for Normalized Factorial Moments Analysis: Hwa and Yang, Phys. Rev. C 85, 044914 (2012)
1314// / \author Salman Malik
@@ -53,6 +54,11 @@ using namespace o2::framework;
5354using namespace o2 ::framework::expressions;
5455
5556struct FactorialMomentsTask {
57+ Configurable<bool > useDcaCut{" useDcaCut" , true , " Enable DCA cut" };
58+ Configurable<bool > usePVContributor{" usePVContributor" , true ,
59+ " Require the track to contribute to the primary-vertex fit (Run 3)" };
60+ Configurable<bool > useTPCChi2{" useTPCChi2" , true , " Enable TPC chi2 cut" };
61+ Configurable<bool > useTPCCluster{" useTPCCluster" , false , " Select tracks with TPCCluster" };
5662 Configurable<bool > useITS{" useITS" , false , " Select tracks with ITS" };
5763 Configurable<bool > useTPC{" useTPC" , false , " Select tracks with TPC" };
5864 Configurable<bool > useGlobal{" useGlobal" , true , " Select global tracks" };
@@ -66,7 +72,7 @@ struct FactorialMomentsTask {
6672 Configurable<float > ptMin{" ptMin" , 0 .2f , " lower pT cut" };
6773 Configurable<float > dcaXY{" dcaXY" , 0 .1f , " DCA xy cut" };
6874 Configurable<float > dcaZ{" dcaZ" , 1 .0f , " DCA z cut" };
69- Configurable<float > maxTPCChi2NCl{" maxTPCChi2NCl" , 2 . 5f , " Maximum TPCchi2NCl" };
75+ Configurable<float > maxTPCChi2NCl{" maxTPCChi2NCl" , 4 . 0f , " Maximum TPCchi2NCl" };
7076 Configurable<float > maxITSChi2NCl{" maxITSChi2NCl" , 40 .0f , " Maximum ITSchi2NCl" };
7177 Configurable<float > minTPCNCls{" minTPCNCls" , 70 .0f , " minimum number of TPC clusters" };
7278 Configurable<std::vector<int >> centLimits{" centLimits" , {0 , 5 }, " centrality min and max" };
@@ -85,9 +91,9 @@ struct FactorialMomentsTask {
8591 Configurable<bool > includeITSTracks{" includeITSTracks" , false , " ITS Tracks" };
8692 Configurable<int > nSlots{" nSlots" , 1250 , " Number of hash slots for merge-safe subsampling (slot = splitmix64(globalBC) % nSlots); must be identical for every job" };
8793 Configurable<bool > useMC{" useMC" , false , " Use MC information" };
88- Configurable<bool > useGlobalTrack{ " useGlobalTrack " , true , " Require global track in filter " };
94+ Configurable<bool > useCrossedRows{ " useCrossedRows " , true , " Require minimum number of TPC crossed rows " };
8995 Configurable<int > minITSClusters{" minITSClusters" , 6 , " Minimum Number of ITS cluster" };
90- Configurable<int > minTPCClusters{" minTPCClusters" , 80 , " Minimum Number of TPC cluster" };
96+ Configurable<int > minTPCClusters{" minTPCClusters" , 70 , " Minimum Number of TPC cluster" };
9197 Configurable<int > minTPCCrossedRows{" minTPCCrossedRows" , 70 , " Minimum Number of TPC crossed-rows" };
9298 Configurable<float > minTPCCrossedRowsOverFindableCls{" minTPCCrossedRowsOverFindableCls" , 0.8 , " Minimum ratio of crossed rows over findable clusters TPC" };
9399 Configurable<int > reduceOutput{" reduceOutput" , 0 , " Suppress info level output (0 = all output, 1 = per collision, 2 = none)" };
@@ -133,23 +139,28 @@ struct FactorialMomentsTask {
133139 OutputObjHandlingPolicy::AnalysisObject,
134140 true };
135141 float collisionZ = 0 .f;
136- static constexpr double kDcaXY0 = 0.0105 ;
137- static constexpr double kDcaXY1 = 0.035 ;
138- static constexpr double kDcaXY2 = 1.1 ;
142+ static constexpr double DcaXY0 = 0.0105 ;
143+ static constexpr double DcaXY1 = 0.035 ;
144+ static constexpr double DcaXY2 = 1.1 ;
139145 static const int nBins = 52 ;
140- static constexpr double kMinCharge = 1e-6 ;
146+ static const int nCentLim = 2 ;
147+ static const int nPtVal = 2 ;
148+ static const int nVertexXYZ = 3 ;
149+ static constexpr int NPt = 5 ;
150+ static constexpr double MinCharge = 1e-6 ;
151+ static constexpr int MaxSlots = 1000000 ;
141152 static const int nfqOrder = 6 ;
142- static constexpr int kEvAll = 1 ;
143- static constexpr int kEvSel8 = 2 ;
144- static constexpr int kEvITSROFrame = 3 ;
145- static constexpr int kEvTimeFrame = 4 ;
146- static constexpr int kEvSameBunch = 5 ;
147- static constexpr int kEvGoodITS = 6 ;
148- static constexpr int kEvGoodZvtx = 7 ;
149- static constexpr int kEvVertexITSTPC = 8 ;
150- static constexpr int kEvCent = 9 ;
151- static constexpr int kEvAccepted = 10 ;
152- static constexpr int kNEventSteps = 10 ;
153+ static constexpr int EvAll = 1 ;
154+ static constexpr int EvSel8 = 2 ;
155+ static constexpr int EvITSROFrame = 3 ;
156+ static constexpr int EvTimeFrame = 4 ;
157+ static constexpr int EvSameBunch = 5 ;
158+ static constexpr int EvGoodITS = 6 ;
159+ static constexpr int EvGoodZvtx = 7 ;
160+ static constexpr int EvVertexITSTPC = 8 ;
161+ static constexpr int EvCent = 9 ;
162+ static constexpr int EvAccepted = 10 ;
163+ static constexpr int NEventSteps = 10 ;
153164 std::array<int , nBins> binningM{};
154165 std::array<int , 5 > countTracks{};
155166 std::array<std::array<std::array<double , nBins>, 5 >, nfqOrder> fqEvent{};
@@ -170,18 +181,18 @@ struct FactorialMomentsTask {
170181
171182 void init (o2::framework::InitContext&)
172183 {
173- if (numPt.value < 1 || numPt.value > 5 ) {
174- LOG (fatal) << " numPt must be between 1 and 5 , got " << numPt.value ;
184+ if (numPt.value < 1 || numPt.value > NPt ) {
185+ LOG (fatal) << " numPt must be between 1 and " << NPt << " , got " << numPt.value ;
175186 }
176- if (static_cast <int >(ptCuts.value .size ()) < 2 * numPt.value ) {
177- LOG (fatal) << " ptCuts needs " << 2 * numPt.value << " values for numPt=" << numPt.value
187+ if (static_cast <int >(ptCuts.value .size ()) < nPtVal * numPt.value ) {
188+ LOG (fatal) << " ptCuts needs " << nPtVal * numPt.value << " values for numPt=" << numPt.value
178189 << " , got " << ptCuts.value .size ();
179190 }
180- if (nSlots.value < 1 || nSlots.value > 1000000 ) {
181- LOG (fatal) << " nSlots must be in [1, 1000000 ], got " << nSlots.value ;
191+ if (nSlots.value < 1 || nSlots.value > MaxSlots ) {
192+ LOG (fatal) << " nSlots must be in [1, " << MaxSlots << " ], got " << nSlots.value ;
182193 }
183- if (centLimits.value .size () != 2 || vertexXYZ.value .size () != 3 ) {
184- LOG (fatal) << " centLimits needs 2 and vertexXYZ needs 3 values" ;
194+ if (centLimits.value .size () != nCentLim || vertexXYZ.value .size () != nVertexXYZ ) {
195+ LOG (fatal) << " centLimits needs " << nCentLim << " and vertexXYZ needs " << nVertexXYZ << " values" ;
185196 }
186197 if (applyCheckPtForRec.value == applyCheckPtForMC.value ) {
187198 LOG (fatal) << " exactly one of applyCheckPtForRec / applyCheckPtForMC must be enabled" ;
@@ -194,10 +205,16 @@ struct FactorialMomentsTask {
194205 for (int i = 0 ; i < static_cast <int >(ptCuts.value .size ()); i++) {
195206 cfg += Form (" %s%g" , i > 0 ? " ," : " " , ptCuts.value [i]);
196207 }
208+ cfg += Form (" useDcaCut=%d usePVContributor=%d useTPCChi2=%d useTPCCluster=%d useCrossedRows=%d" ,
209+ useDcaCut.value ? 1 : 0 , usePVContributor.value ? 1 : 0 , useTPCChi2.value ? 1 : 0 ,
210+ useTPCCluster.value ? 1 : 0 , useCrossedRows.value ? 1 : 0 );
211+ cfg += Form (" useITS=%d useTPC=%d useGlobal=%d maxTPCChi2NCl=%g minTPCClusters=%d minTPCCrossedRows=%d" ,
212+ useITS.value ? 1 : 0 , useTPC.value ? 1 : 0 , useGlobal.value ? 1 : 0 ,
213+ maxTPCChi2NCl.value , minTPCClusters.value , minTPCCrossedRows.value );
197214 histos.add (" metaConfig" , cfg.Data (), HistType::kTH1D , {{1 , 0.5 , 1.5 }});
198- auto mEventSelected = std::get<std::shared_ptr<TH1 >>(histos.add (" mEventSelected" , " eventSelected" , HistType::kTH1D , {{kNEventSteps , 0.5 , kNEventSteps + 0.5 }}));
199- const std::array<const char *, kNEventSteps > evLabels = {" all" , " sel8" , " kNoITSROFrameBorder" , " kNoTimeFrameBorder" , " kNoSameBunchPileup" , " kIsGoodITSLayersAll" , " kIsGoodZvtxFT0vsPV" , " kIsVertexITSTPC" , " centrality" , " accepted" };
200- for (int iStep = 0 ; iStep < kNEventSteps ; ++iStep) {
215+ auto mEventSelected = std::get<std::shared_ptr<TH1 >>(histos.add (" mEventSelected" , " eventSelected" , HistType::kTH1D , {{NEventSteps , 0.5 , NEventSteps + 0.5 }}));
216+ const std::array<const char *, NEventSteps > evLabels = {" all" , " sel8" , " kNoITSROFrameBorder" , " kNoTimeFrameBorder" , " kNoSameBunchPileup" , " kIsGoodITSLayersAll" , " kIsGoodZvtxFT0vsPV" , " kIsVertexITSTPC" , " centrality" , " accepted" };
217+ for (int iStep = 0 ; iStep < NEventSteps ; ++iStep) {
201218 mEventSelected ->GetXaxis ()->SetBinLabel (iStep + 1 , evLabels[iStep]);
202219 }
203220 // merge-safe slot output: additive per-slot sums, hadd-exact (see slotpool.C)
@@ -326,7 +343,7 @@ struct FactorialMomentsTask {
326343 template <typename T>
327344 bool passDcaCut (const T& track) const
328345 {
329- return std::fabs (track.dcaXY ()) < (kDcaXY0 + kDcaXY1 / std::pow (track.pt (), kDcaXY2 ));
346+ return std::fabs (track.dcaXY ()) < (DcaXY0 + DcaXY1 / std::pow (track.pt (), DcaXY2 ));
330347 }
331348
332349 template <typename T>
@@ -368,7 +385,7 @@ struct FactorialMomentsTask {
368385 double charge = pdgInfo->Charge ();
369386 double physCharge = charge / 3.0 ;
370387 histos.fill (HIST (" mChargeBefore" ), physCharge);
371- if (mc.isPhysicalPrimary () && std::abs (mc.eta ()) < centralEta && std::abs (physCharge) >= kMinCharge ) {
388+ if (mc.isPhysicalPrimary () && std::abs (mc.eta ()) < centralEta && std::abs (physCharge) >= MinCharge ) {
372389 histos.fill (HIST (" mChargeAfter" ), physCharge);
373390 histos.fill (HIST (" mEta" ), mc.eta ());
374391 histos.fill (HIST (" mPt" ), mc.pt ());
@@ -383,66 +400,96 @@ struct FactorialMomentsTask {
383400 template <typename T>
384401 bool selectEventRun3 (const T& coll)
385402 {
386- histos.fill (HIST (" mEventSelected" ), kEvAll );
403+ histos.fill (HIST (" mEventSelected" ), EvAll );
387404 if (!coll.sel8 ()) {
388405 return false ;
389406 }
390- histos.fill (HIST (" mEventSelected" ), kEvSel8 );
407+ histos.fill (HIST (" mEventSelected" ), EvSel8 );
391408 if (evSelNoITSROFrameBorder && !(coll.selection_bit (o2::aod::evsel::kNoITSROFrameBorder ))) {
392409 return false ;
393410 }
394- histos.fill (HIST (" mEventSelected" ), kEvITSROFrame );
411+ histos.fill (HIST (" mEventSelected" ), EvITSROFrame );
395412 if (evSelNoTimeFrameBorder && !(coll.selection_bit (o2::aod::evsel::kNoTimeFrameBorder ))) {
396413 return false ;
397414 }
398- histos.fill (HIST (" mEventSelected" ), kEvTimeFrame );
415+ histos.fill (HIST (" mEventSelected" ), EvTimeFrame );
399416 if (evSelNoSameBunchPileup && !coll.selection_bit (o2::aod::evsel::kNoSameBunchPileup )) {
400417 return false ;
401418 }
402- histos.fill (HIST (" mEventSelected" ), kEvSameBunch );
419+ histos.fill (HIST (" mEventSelected" ), EvSameBunch );
403420 if (evSelGoodITSLayersAll && !(coll.selection_bit (o2::aod::evsel::kIsGoodITSLayersAll ))) {
404421 return false ;
405422 }
406- histos.fill (HIST (" mEventSelected" ), kEvGoodITS );
423+ histos.fill (HIST (" mEventSelected" ), EvGoodITS );
407424 if (evSelGoodZvtxFT0vsPV && !coll.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV )) {
408425 return false ;
409426 }
410- histos.fill (HIST (" mEventSelected" ), kEvGoodZvtx );
427+ histos.fill (HIST (" mEventSelected" ), EvGoodZvtx );
411428 if (coll.centFT0C () < centLimits.value [0 ] || coll.centFT0C () > centLimits.value [1 ]) {
412429 return false ;
413430 }
414431 collisionZ = coll.posZ ();
415- histos.fill (HIST (" mEventSelected" ), kEvCent );
416- histos.fill (HIST (" mEventSelected" ), kEvAccepted );
432+ histos.fill (HIST (" mEventSelected" ), EvCent );
433+ histos.fill (HIST (" mEventSelected" ), EvAccepted );
417434 return true ;
418435 }
419436
420437 template <typename T>
421438 bool selectEventMCRec (const T& coll)
422439 {
423- histos.fill (HIST (" mEventSelected" ), kEvAll );
440+ histos.fill (HIST (" mEventSelected" ), EvAll );
424441 if (!coll.sel8 ()) {
425442 return false ;
426443 }
427- histos.fill (HIST (" mEventSelected" ), kEvSel8 );
444+ histos.fill (HIST (" mEventSelected" ), EvSel8 );
428445 if (evSelNoSameBunchPileup && !coll.selection_bit (o2::aod::evsel::kNoSameBunchPileup )) {
429446 return false ;
430447 }
431- histos.fill (HIST (" mEventSelected" ), kEvSameBunch );
448+ histos.fill (HIST (" mEventSelected" ), EvSameBunch );
432449 if (evSelGoodZvtxFT0vsPV && !coll.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV )) {
433450 return false ;
434451 }
435- histos.fill (HIST (" mEventSelected" ), kEvGoodZvtx );
452+ histos.fill (HIST (" mEventSelected" ), EvGoodZvtx );
436453 if (evSelVertexITSTPC && !coll.selection_bit (o2::aod::evsel::kIsVertexITSTPC )) {
437454 return false ;
438455 }
439- histos.fill (HIST (" mEventSelected" ), kEvVertexITSTPC );
456+ histos.fill (HIST (" mEventSelected" ), EvVertexITSTPC );
440457 if (coll.centFT0C () < centLimits.value [0 ] || coll.centFT0C () > centLimits.value [1 ]) {
441458 return false ;
442459 }
443460 collisionZ = coll.posZ ();
444- histos.fill (HIST (" mEventSelected" ), kEvCent );
445- histos.fill (HIST (" mEventSelected" ), kEvAccepted );
461+ histos.fill (HIST (" mEventSelected" ), EvCent);
462+ histos.fill (HIST (" mEventSelected" ), EvAccepted);
463+ return true ;
464+ }
465+
466+ template <typename T>
467+ bool selectTrack (const T& track)
468+ {
469+ if (useITS && !track.hasITS ()) {
470+ return false ;
471+ }
472+ if (useTPC && !track.hasTPC ()) {
473+ return false ;
474+ }
475+ if (useGlobal && !track.isGlobalTrack ()) {
476+ return false ;
477+ }
478+ if (useCrossedRows && track.tpcNClsCrossedRows () < minTPCCrossedRows) {
479+ return false ;
480+ }
481+ if (useDcaCut && !passDcaCut (track)) {
482+ return false ;
483+ }
484+ if (usePVContributor && !track.isPVContributor ()) {
485+ return false ;
486+ }
487+ if (useTPCChi2 && track.tpcChi2NCl () > maxTPCChi2NCl) {
488+ return false ;
489+ }
490+ if (useTPCCluster && track.tpcNClsFound () < minTPCClusters) {
491+ return false ;
492+ }
446493 return true ;
447494 }
448495
@@ -488,16 +535,7 @@ struct FactorialMomentsTask {
488535 histos.fill (HIST (" mCentFT0C" ), coll.centFT0C ());
489536 beginEvent ();
490537 for (auto const & track : tracks) {
491- if (useITS && !track.hasITS ()) {
492- continue ;
493- }
494- if (useTPC && !track.hasTPC ()) {
495- continue ;
496- }
497- if (useGlobal && !track.isGlobalTrack ()) {
498- continue ;
499- }
500- if (!passDcaCut (track)) {
538+ if (!selectTrack (track)) {
501539 continue ;
502540 }
503541 fillTrackQA (track);
@@ -523,16 +561,7 @@ struct FactorialMomentsTask {
523561 histos.fill (HIST (" mCentFT0C" ), coll.centFT0C ());
524562 beginEvent ();
525563 for (auto const & track : colltracks) {
526- if (useITS && !track.hasITS ()) {
527- continue ;
528- }
529- if (useTPC && !track.hasTPC ()) {
530- continue ;
531- }
532- if (useGlobal && !track.isGlobalTrack ()) {
533- continue ;
534- }
535- if (!passDcaCut (track)) {
564+ if (!selectTrack (track)) {
536565 continue ;
537566 }
538567 fillTrackQA (track);
@@ -572,7 +601,7 @@ struct FactorialMomentsTask {
572601 beginEvent ();
573602 for (auto const & track : tracks) {
574603 double recoCharge = (track.sign () != 0 ) ? track.sign () : 0 .;
575- if (std::abs (track.eta ()) < centralEta && track.isGlobalTrack () && std::abs (recoCharge) >= kMinCharge ) {
604+ if (std::abs (track.eta ()) < centralEta && track.isGlobalTrack () && std::abs (recoCharge) >= MinCharge ) {
576605 fillTrackQA (track);
577606 if (applyCheckPtForRec && !applyCheckPtForMC) {
578607 checkpT (track);
0 commit comments