@@ -43,9 +43,11 @@ struct PhianalysisTHnSparse {
4343
4444 struct : ConfigurableGroup {
4545 Configurable<bool > produceQA{" produceQA" , false , " Produce qa histograms." };
46+ Configurable<bool > produceStats{" produceStats" , false , " Produce statistics histograms." };
4647 Configurable<bool > produceTrue{" produceTrue" , false , " Produce True and Gen histograms." };
4748 Configurable<bool > produceLikesign{" produceLikesign" , false , " Produce Like sign histograms." };
4849 Configurable<std::string> eventMixing{" eventMixing" , " none" , " Produce Event Mixing histograms of type." };
50+ Configurable<bool > produceRotational{" produceRotational" , false , " Produce Rotational histograms." };
4951 } produce;
5052
5153 Configurable<int > daughterPos{" daughterPos" , 3 , " Particle type of the positive dauther according to ReconstructionDataFormats/PID.h (Default = Kaon)" };
@@ -62,7 +64,6 @@ struct PhianalysisTHnSparse {
6264 Configurable<float > ptTOFThreshold{" ptTOFThreshold" , 0 .5f , " Threshold for applying TOF." };
6365 Configurable<float > rapidity{" rapidity" , 0 .5f , " Rapidity cut (maximum)." };
6466 Configurable<float > etatrack{" etatrack" , 0 .8f , " Eta cut for track." };
65- Configurable<float > etapair{" etapair" , 0 .5f , " Eta cut for pair." };
6667 Configurable<float > pt{" pt" , 0 .15f , " Cut: Minimal value of tracks pt." };
6768 Configurable<float > dcaXY{" dcaXY" , 1 .0f , " Cut: Maximal value of tracks DCA XY." };
6869 Configurable<float > dcaZ{" dcaZ" , 1 .0f , " Cut: Maximal value of tracks DCA Z." };
@@ -97,6 +98,9 @@ struct PhianalysisTHnSparse {
9798 ConfigurableAxis axisMultiplicityMixing{" axisMultiplicityMixing" , {5 , 0 , 5000 }, " TPC multiplicity for bin" };
9899 ConfigurableAxis axisCentralityMixing{" axisCentralityMixing" , {10 , 0 , 100 }, " Multiplicity percentil binning for mixing" };
99100
101+ // rotational
102+ Configurable<int > numberofRotations{" numberofRotations" , 1 , " Number of rotations for rotational background estimation." };
103+
100104 // Axes specifications
101105 AxisSpec posZaxis = {400 , -20 ., 20 ., " V_{z} (cm)" };
102106 AxisSpec dcaXYaxis = {800 , -2.0 , 2.0 , " DCA_{xy} (cm)" };
@@ -115,7 +119,7 @@ struct PhianalysisTHnSparse {
115119 double * pointPair = nullptr ;
116120 double * pointSys = nullptr ;
117121 ROOT::Math::PxPyPzMVector d1, d2, mother;
118- bool produceQA, dataQA, MCTruthQA, globalTrack, tpcPidOnly = false ;
122+ bool produceTrue, produceLikesign, produceQA, produceStats, produceRotational , dataQA, MCTruthQA, globalTrack, tpcPidOnly = false ;
119123 float tpcnSigmaPos = 100 .0f ;
120124 float tpcnSigmaNeg = 100 .0f ;
121125 float combinedNSigma = 100 .0f ;
@@ -178,7 +182,11 @@ struct PhianalysisTHnSparse {
178182 std::vector<AxisSpec> allAxesSys = {tpcNClsFoundAxis};
179183
180184 produceQA = static_cast <bool >(produce.produceQA );
185+ produceStats = static_cast <bool >(produce.produceStats );
186+ produceTrue = static_cast <bool >(produce.produceTrue );
187+ produceLikesign = static_cast <bool >(produce.produceLikesign );
181188 mixingType = rsn::mixingTypeName (static_cast <std::string>(produce.eventMixing ));
189+ produceRotational = static_cast <bool >(produce.produceRotational );
182190 tpcnSigmaPos = static_cast <float >(cut.tpcnSigmaPos );
183191 tpcnSigmaNeg = static_cast <float >(cut.tpcnSigmaNeg );
184192 tpcNClsFound = static_cast <int >(cut.tpcNClsFound );
@@ -190,11 +198,12 @@ struct PhianalysisTHnSparse {
190198 pointPair = new double [static_cast <int >(o2::analysis::rsn::PairAxisType::unknown)];
191199 pointSys = new double [static_cast <int >(o2::analysis::rsn::SystematicsAxisType::unknown)];
192200 rsnOutput = new o2::analysis::rsn::OutputSparse ();
193- rsnOutput->init (sparseAxes, allAxes, sysAxes, allAxesSys, static_cast < bool >(produce. produceTrue ) , mixingType, static_cast < bool >(produce. produceLikesign ) , ®istry);
201+ rsnOutput->init (sparseAxes, allAxes, sysAxes, allAxesSys, produceTrue, mixingType, produceLikesign, produceRotational , ®istry);
194202
195203 // Print summary of configuration
196204 LOGF (info, " === PhianalysisTHnSparse configuration summary ===" );
197205 LOGF (info, " produceQA: %s" , produceQA ? " true" : " false" );
206+ LOGF (info, " produceStats: %s" , produceStats ? " true" : " false" );
198207 LOGF (info, " produceTrue: %s" , static_cast <bool >(produce.produceTrue ) ? " true" : " false" );
199208 LOGF (info, " produceLikesign: %s" , static_cast <bool >(produce.produceLikesign ) ? " true" : " false" );
200209 LOGF (info, " eventMixing: %s" , static_cast <std::string>(produce.eventMixing ).c_str ());
@@ -208,14 +217,14 @@ struct PhianalysisTHnSparse {
208217 LOGF (info, " ptTOFThreshold: %.2f" , ptTOFThreshold);
209218 LOGF (info, " rapidity: %.2f" , static_cast <float >(cut.rapidity ));
210219 LOGF (info, " etatrack: %.2f" , static_cast <float >(cut.etatrack ));
211- LOGF (info, " etapair: %.2f" , static_cast <float >(cut.etapair ));
212220 LOGF (info, " pt (min): %.2f" , static_cast <float >(cut.pt ));
213221 LOGF (info, " dcaXY: %.2f" , static_cast <float >(cut.dcaXY ));
214222 LOGF (info, " dcaZ: %.2f" , static_cast <float >(cut.dcaZ ));
215223 LOGF (info, " globalTrack: %s" , globalTrack ? " true" : " false" );
216224 LOGF (info, " tpcNClsFound: %d" , tpcNClsFound);
217225 LOGF (info, " mixingType: %d" , static_cast <int >(mixingType));
218226 LOGF (info, " numberofMixedEvents: %d" , static_cast <int >(numberofMixedEvents));
227+ LOGF (info, " numberofRotations: %d" , static_cast <int >(numberofRotations));
219228 LOGF (info, " sparseAxes: " );
220229 for (const auto & axis : static_cast <std::vector<std::string>>(sparseAxes)) {
221230 LOGF (info, " %s" , axis.c_str ());
@@ -240,18 +249,17 @@ struct PhianalysisTHnSparse {
240249 registry.add (" QAEvent/hMult" , " Multiplicity (amplitude of non-zero channels in the FV0A + FV0C) " , kTH1F , {{300 , 0 ., 30000 .}});
241250
242251 // Track QA
243- registry.add (" QATrack/hSelection" , " Tracks statistics" , kTH1D , {{10 , 0 .0f , 10 .0f }});
252+ registry.add (" QATrack/hSelection" , " Tracks statistics" , kTH1D , {{9 , 0 .0f , 9 .0f }});
244253 auto hTrack = registry.get <TH1>(HIST (" QATrack/hSelection" ));
245254 hTrack->GetXaxis ()->SetBinLabel (1 , " all tracks" );
246255 hTrack->GetXaxis ()->SetBinLabel (2 , " passed pT cut" );
247256 hTrack->GetXaxis ()->SetBinLabel (3 , " passed eta cut" );
248257 hTrack->GetXaxis ()->SetBinLabel (4 , " passed DCA cut" );
249258 hTrack->GetXaxis ()->SetBinLabel (5 , " passed PID cut" );
250- hTrack->GetXaxis ()->SetBinLabel (6 , " passed rapidity cut" );
251- hTrack->GetXaxis ()->SetBinLabel (7 , " passed tpcNClsFound cut" );
252- hTrack->GetXaxis ()->SetBinLabel (8 , " passed isPrimaryTrack cut" );
253- hTrack->GetXaxis ()->SetBinLabel (9 , " passed isPVContributor cut" );
254- hTrack->GetXaxis ()->SetBinLabel (10 , " passed all cuts" );
259+ hTrack->GetXaxis ()->SetBinLabel (6 , " passed tpcNClsFound cut" );
260+ hTrack->GetXaxis ()->SetBinLabel (7 , " passed isPrimaryTrack cut" );
261+ hTrack->GetXaxis ()->SetBinLabel (8 , " passed isPVContributor cut" );
262+ hTrack->GetXaxis ()->SetBinLabel (9 , " passed all cuts" );
255263 hTrack->SetMinimum (0.1 );
256264
257265 registry.add (" QATrack/hRapidity" , " Rapidity distribution of K^{+} and K^{-}" , kTH1F , {{200 , -1 , 1 }});
@@ -369,18 +377,11 @@ struct PhianalysisTHnSparse {
369377 if (produceQA && dataQA)
370378 registry.fill (HIST (" QATrack/hSelection" ), 4.5 );
371379
372- // Apply rapidity cut
373- if (std::abs (track.rapidity (isPositive ? massPos : massNeg)) > static_cast <float >(cut.rapidity )) {
374- return false ;
375- }
376- if (produceQA && dataQA)
377- registry.fill (HIST (" QATrack/hSelection" ), 5.5 );
378-
379380 // Apply tpcNClsFound cut
380381 if (track.tpcNClsFound () < tpcNClsFound)
381382 return false ;
382383 if (produceQA && dataQA)
383- registry.fill (HIST (" QATrack/hSelection" ), 6 .5 );
384+ registry.fill (HIST (" QATrack/hSelection" ), 5 .5 );
384385
385386 if (globalTrack) {
386387 // Apply Global track cuts
@@ -392,16 +393,16 @@ struct PhianalysisTHnSparse {
392393 return false ;
393394 }
394395 if (produceQA && dataQA)
395- registry.fill (HIST (" QATrack/hSelection" ), 7 .5 );
396+ registry.fill (HIST (" QATrack/hSelection" ), 6 .5 );
396397
397398 // Apply PV Contributor cuts
398399 if (!track.isPVContributor ())
399400 return false ;
400401 if (produceQA && dataQA)
401- registry.fill (HIST (" QATrack/hSelection" ), 8 .5 );
402+ registry.fill (HIST (" QATrack/hSelection" ), 7 .5 );
402403
403404 if (produceQA && dataQA)
404- registry.fill (HIST (" QATrack/hSelection" ), 9 .5 );
405+ registry.fill (HIST (" QATrack/hSelection" ), 8 .5 );
405406
406407 return true ;
407408 }
@@ -412,7 +413,7 @@ struct PhianalysisTHnSparse {
412413 d2 = ROOT::Math::PxPyPzMVector (track2.px (), track2.py (), track2.pz (), massNeg);
413414 mother = d1 + d2;
414415
415- if (std::abs (mother.Eta ()) > static_cast <float >(cut.etapair ))
416+ if (std::abs (mother.Rapidity ()) > static_cast <float >(cut.rapidity ))
416417 return false ;
417418
418419 return true ;
@@ -458,15 +459,16 @@ struct PhianalysisTHnSparse {
458459 registry.fill (HIST (" QAEvent/hVtxZ" ), collision.posZ ());
459460 registry.fill (HIST (" QAEvent/hMult" ), getMultiplicity (collision));
460461 registry.fill (HIST (" QAEvent/hCent" ), getCentrality (collision));
461-
462- dataQA = true ;
463- for (const auto & track : posDaughters) {
464- selectedTrack (track, true );
465- }
466- for (const auto & track : negDaughters) {
467- selectedTrack (track, false );
462+ if (produceStats) {
463+ dataQA = true ;
464+ for (const auto & track : posDaughters) {
465+ selectedTrack (track, true );
466+ }
467+ for (const auto & track : negDaughters) {
468+ selectedTrack (track, false );
469+ }
470+ dataQA = false ;
468471 }
469- dataQA = false ;
470472 }
471473
472474 if (static_cast <int >(verbose.verboselevel ) > 0 && static_cast <int >(verbose.refresh ) > 0 && collision.globalIndex () % static_cast <int >(verbose.refresh ) == static_cast <int >(verbose.refreshIndex ))
@@ -526,14 +528,15 @@ struct PhianalysisTHnSparse {
526528 0 );
527529 rsnOutput->fillUnlikepm (pointPair);
528530
529- if (produceQA)
531+ if (produceQA) {
530532 registry.fill (HIST (" QAEvent/hSelection" ), 2.5 );
531- if (n == 0 )
532- registry.fill (HIST (" QAEvent/hSelection" ), 1.5 );
533+ if (n == 0 )
534+ registry.fill (HIST (" QAEvent/hSelection" ), 1.5 );
535+ }
533536 n = n + 1 ;
534537 }
535538
536- if (static_cast < bool >(produce. produceLikesign ) ) {
539+ if (produceLikesign) {
537540
538541 for (const auto & [track1, track2] : combinations (o2::soa::CombinationsStrictlyUpperIndexPolicy (posDaughters, posDaughters))) {
539542 if (!selectedTrack (track1, true )) // both positive
@@ -591,6 +594,46 @@ struct PhianalysisTHnSparse {
591594 rsnOutput->fillLikemm (pointPair);
592595 }
593596 }
597+
598+ if (produceRotational) {
599+ for (const auto & [track1, track2] : combinations (o2::soa::CombinationsFullIndexPolicy (posDaughters, negDaughters))) {
600+
601+ if (!selectedTrack (track1, true ))
602+ continue ;
603+ if (!selectedTrack (track2, false ))
604+ continue ;
605+
606+ d1 = ROOT::Math::PxPyPzMVector (track1.px (), track1.py (), track1.pz (), massPos);
607+ d2 = ROOT::Math::PxPyPzMVector (track2.px (), track2.py (), track2.pz (), massNeg);
608+ mother = d1 + d2;
609+
610+ if (std::abs (mother.Rapidity ()) > static_cast <float >(cut.rapidity ))
611+ continue ;
612+
613+ for (int i = 1 ; i <= static_cast <int >(numberofRotations); i++) {
614+ float angle = i * (360 .0f / (static_cast <int >(numberofRotations) + 1 ));
615+ float px2new = track2.px () * std::cos (angle * TMath::DegToRad ()) - track2.py () * std::sin (angle * TMath::DegToRad ());
616+ float py2new = track2.px () * std::sin (angle * TMath::DegToRad ()) + track2.py () * std::cos (angle * TMath::DegToRad ());
617+ d2 = ROOT::Math::PxPyPzMVector (px2new, py2new, track2.pz (), massNeg);
618+ mother = d1 + d2;
619+
620+ pointPair = fillPointPair (mother.M (),
621+ mother.Pt (),
622+ getMultiplicity (collision),
623+ getCentrality (collision),
624+ track1.tpcNSigmaKa (),
625+ track2.tpcNSigmaKa (),
626+ mother.Eta (),
627+ mother.Rapidity (),
628+ collision.posZ (),
629+ 0 ,
630+ 0 ,
631+ 0 );
632+
633+ rsnOutput->fillRotationpm (pointPair);
634+ }
635+ }
636+ }
594637 }
595638 PROCESS_SWITCH (PhianalysisTHnSparse, processData, " Process Event for Data" , true );
596639
@@ -772,10 +815,10 @@ struct PhianalysisTHnSparse {
772815 auto tracksTuple = std::make_tuple (tracks);
773816
774817 BinningTypeVzCe binningVzCe{{axisVertexMixing, axisCentralityMixing}, true };
775- SameKindPair<EventCandidates, TrackCandidates, BinningTypeVzCe> pairVzCe{binningVzCe, numberofMixedEvents, -1 , collisions, tracksTuple, &cache};
818+ SameKindPair<EventCandidates, TrackCandidates, BinningTypeVzCe> pairVzCe{binningVzCe, static_cast < int >( numberofMixedEvents) , -1 , collisions, tracksTuple, &cache};
776819
777820 BinningTypeVzMu binningVzMu{{axisVertexMixing, axisMultiplicityMixing}, true };
778- SameKindPair<EventCandidates, TrackCandidates, BinningTypeVzMu> pairVzMu{binningVzMu, numberofMixedEvents, -1 , collisions, tracksTuple, &cache};
821+ SameKindPair<EventCandidates, TrackCandidates, BinningTypeVzMu> pairVzMu{binningVzMu, static_cast < int >( numberofMixedEvents) , -1 , collisions, tracksTuple, &cache};
779822
780823 if (mixingType == rsn::MixingType::ce) {
781824 for (const auto & [c1, tracks1, c2, tracks2] : pairVzCe) {
@@ -819,60 +862,6 @@ struct PhianalysisTHnSparse {
819862 rsnOutput->fillMixingpm (pointPair);
820863 }
821864
822- if (static_cast <bool >(produce.produceLikesign )) {
823-
824- for (const auto & [track1, track2] : combinations (o2::soa::CombinationsFullIndexPolicy (posDaughtersc1, posDaughtersc2))) {
825-
826- if (!selectedTrack (track1, true )) // track1 is positive
827- continue ;
828- if (!selectedTrack (track2, true )) // track2 is positive
829- continue ;
830-
831- if (!selectedPair (mother, track1, track2))
832- continue ;
833-
834- pointPair = fillPointPair (mother.M (),
835- mother.Pt (),
836- getMultiplicity (c1),
837- getCentrality (c1),
838- track1.tpcNSigmaKa (),
839- track2.tpcNSigmaKa (),
840- mother.Eta (),
841- mother.Rapidity (),
842- c1.posZ (),
843- getMultiplicity (c2),
844- getCentrality (c2),
845- c2.posZ ());
846-
847- rsnOutput->fillMixingpp (pointPair);
848- }
849-
850- for (const auto & [track1, track2] : combinations (o2::soa::CombinationsFullIndexPolicy (negDaughtersc1, negDaughtersc2))) {
851-
852- if (!selectedTrack (track1, false ))
853- continue ;
854- if (!selectedTrack (track2, false ))
855- continue ;
856-
857- if (!selectedPair (mother, track1, track2))
858- continue ;
859- pointPair = fillPointPair (mother.M (),
860- mother.Pt (),
861- getMultiplicity (c1),
862- getCentrality (c1),
863- track1.tpcNSigmaKa (),
864- track2.tpcNSigmaKa (),
865- mother.Eta (),
866- mother.Rapidity (),
867- c1.posZ (),
868- getMultiplicity (c2),
869- getCentrality (c2),
870- c2.posZ ());
871-
872- rsnOutput->fillMixingmm (pointPair);
873- }
874- }
875-
876865 for (const auto & [track1, track2] : combinations (o2::soa::CombinationsFullIndexPolicy (posDaughtersc2, negDaughtersc1))) {
877866
878867 if (!selectedTrack (track1, true )) // track1 is positive
@@ -943,62 +932,6 @@ struct PhianalysisTHnSparse {
943932 rsnOutput->fillMixingpm (pointPair);
944933 }
945934
946- if (static_cast <bool >(produce.produceLikesign )) {
947-
948- for (const auto & [track1, track2] : combinations (o2::soa::CombinationsFullIndexPolicy (posDaughtersc1, posDaughtersc2))) {
949-
950- if (!selectedTrack (track1, true )) // track1 is positive
951-
952- continue ;
953- if (!selectedTrack (track2, true )) // track2 is positive
954- continue ;
955-
956- if (!selectedPair (mother, track1, track2))
957- continue ;
958-
959- pointPair = fillPointPair (mother.M (),
960- mother.Pt (),
961- getMultiplicity (c1),
962- getCentrality (c1),
963- track1.tpcNSigmaKa (),
964- track2.tpcNSigmaKa (),
965- mother.Eta (),
966- mother.Rapidity (),
967- c1.posZ (),
968- getMultiplicity (c2),
969- getCentrality (c2),
970- c2.posZ ());
971-
972- rsnOutput->fillMixingpp (pointPair);
973- }
974-
975- for (const auto & [track1, track2] : combinations (o2::soa::CombinationsFullIndexPolicy (negDaughtersc1, negDaughtersc2))) {
976-
977- if (!selectedTrack (track1, false ))
978-
979- continue ;
980- if (!selectedTrack (track2, false ))
981- continue ;
982-
983- if (!selectedPair (mother, track1, track2))
984- continue ;
985- pointPair = fillPointPair (mother.M (),
986- mother.Pt (),
987- getMultiplicity (c1),
988- getCentrality (c1),
989- track1.tpcNSigmaKa (),
990- track2.tpcNSigmaKa (),
991- mother.Eta (),
992- mother.Rapidity (),
993- c1.posZ (),
994- getMultiplicity (c2),
995- getCentrality (c2),
996- c2.posZ ());
997-
998- rsnOutput->fillMixingmm (pointPair);
999- }
1000- }
1001-
1002935 for (const auto & [track1, track2] : combinations (o2::soa::CombinationsFullIndexPolicy (posDaughtersc2, negDaughtersc1))) {
1003936
1004937 if (!selectedTrack (track1, true ))
0 commit comments