@@ -278,7 +278,7 @@ struct HfFilter { // Main struct for HF triggers
278278
279279 // parameters for ML application with ONNX
280280 Configurable<bool > applyML{" applyML" , false , " Flag to enable or disable ML application" };
281- Configurable<std::string> onnxFile2ProngConf{" onnxFile2ProngConf" , " /cvmfs/alice.cern.ch/data/analysis/2022/vAN-20220119 /PWGHF/o2/trigger/XGBoostModel_D0ToKPi.onnx" , " ONNX file for ML model for charm 2-prong candidates" };
281+ Configurable<std::string> onnxFile2ProngConf{" onnxFile2ProngConf" , " /cvmfs/alice.cern.ch/data/analysis/2022/vAN-20220124 /PWGHF/o2/trigger/XGBoostModel_D0ToKPi.onnx" , " ONNX file for ML model for charm 2-prong candidates" };
282282 Configurable<float > thresholdBkgScore2Prong{" thresholdBkgScore2Prong" , 0.4 , " Threshold value for BDT output score on background candidates" };
283283 Configurable<float > thresholdPromptScore2Prong{" thresholdPromptScore2Prong" , 0.5 , " Threshold value for BDT output score on prompt candidates" };
284284 Configurable<float > thresholdNonpromptScore2Prong{" thresholdNonpromptScore2Prong" , 0.1 , " Threshold value for BDT output score on nonprompt candidates" };
@@ -290,8 +290,8 @@ struct HfFilter { // Main struct for HF triggers
290290 std::shared_ptr<TH1 > hN2ProngCharmCand, hN3ProngCharmCand;
291291 std::array<std::shared_ptr<TH1 >, kNCharmParticles > hCharmHighPt{};
292292 std::array<std::shared_ptr<TH1 >, kNCharmParticles > hCharmProtonKstarDistr{};
293- std::array<std::shared_ptr<TH1 >, kNBeautyParticles > hMassB {};
294- std::array<std::shared_ptr<TH1 >, kNCharmParticles + 1 > hMassC {};
293+ std::array<std::shared_ptr<TH2 >, kNBeautyParticles > hMassVsPtB {};
294+ std::array<std::shared_ptr<TH2 >, kNCharmParticles + 1 > hMassVsPtC {};
295295 std::shared_ptr<TH2 > hProtonTPCPID, hProtonTOFPID;
296296 std::array<std::shared_ptr<TH1 >, kNCharmParticles > hBDTScoreBkg{};
297297 std::array<std::shared_ptr<TH1 >, kNCharmParticles > hBDTScorePrompt{};
@@ -322,16 +322,16 @@ struct HfFilter { // Main struct for HF triggers
322322 for (int iCharmPart{0 }; iCharmPart < kNCharmParticles ; ++iCharmPart) {
323323 hCharmHighPt[iCharmPart] = registry.add <TH1 >(Form (" f%sHighPt" , charmParticleNames[iCharmPart].data ()), Form (" #it{p}_{T} distribution of triggered high-#it{p}_{T} %s candidates;#it{p}_{T} (GeV/#it{c});counts" , charmParticleNames[iCharmPart].data ()), HistType::kTH1F , {{100 , 0 ., 50 .}});
324324 hCharmProtonKstarDistr[iCharmPart] = registry.add <TH1 >(Form (" f%sProtonKstarDistr" , charmParticleNames[iCharmPart].data ()), Form (" #it{k}* distribution of triggered p#minus%s pairs;#it{k}* (GeV/#it{c});counts" , charmParticleNames[iCharmPart].data ()), HistType::kTH1F , {{100 , 0 ., 1 .}});
325- hMassC [iCharmPart] = registry.add <TH1 >(Form (" fMass %s" , charmParticleNames[iCharmPart].data ()), Form (" #it{M} distribution of triggered %s candidates;#it{M} (GeV/#it{c}^{2});counts" , charmParticleNames[iCharmPart].data ()), HistType::kTH1F , {{300 , 1.60 , 2.60 }});
325+ hMassVsPtC [iCharmPart] = registry.add <TH2 >(Form (" fMassVsPt %s" , charmParticleNames[iCharmPart].data ()), Form (" #it{M} vs. #it{p}_{T} distribution of triggered %s candidates;#it{p}_{T} (GeV/#it{c});#it{ M} (GeV/#it{c}^{2});counts" , charmParticleNames[iCharmPart].data ()), HistType::kTH2F , {{ 100 , 0 ., 50 .}, {300 , 1.60 , 2.60 }});
326326 if (applyML) {
327327 hBDTScoreBkg[iCharmPart] = registry.add <TH1 >(Form (" f%sBDTScoreBkgDistr" , charmParticleNames[iCharmPart].data ()), Form (" BDT background score distribution for %s;BDT background score;counts" , charmParticleNames[iCharmPart].data ()), HistType::kTH1F , {{100 , 0 ., 1 .}});
328328 hBDTScorePrompt[iCharmPart] = registry.add <TH1 >(Form (" f%sBDTScorePromptDistr" , charmParticleNames[iCharmPart].data ()), Form (" BDT prompt score distribution for %s;BDT prompt score;counts" , charmParticleNames[iCharmPart].data ()), HistType::kTH1F , {{100 , 0 ., 1 .}});
329329 hBDTScoreNonPrompt[iCharmPart] = registry.add <TH1 >(Form (" f%sBDTScoreNonPromptDistr" , charmParticleNames[iCharmPart].data ()), Form (" BDT nonprompt score distribution for %s;BDT nonprompt score;counts" , charmParticleNames[iCharmPart].data ()), HistType::kTH1F , {{100 , 0 ., 1 .}});
330330 }
331331 }
332- hMassC [kNCharmParticles ] = registry.add <TH1 >(" fMassDStar " , " #it{M} distribution of triggered DStar candidates;#it{M} (GeV/#it{c}^{2});counts" , HistType::kTH1F , {{300 , 1.60 , 2.60 }});
332+ hMassVsPtC [kNCharmParticles ] = registry.add <TH2 >(" fMassVsPtDStar " , " #it{M} vs. #it{p}_{T} distribution of triggered DStar candidates;#it{p}_{T} (GeV/#it{c});#it{ M} (GeV/#it{c}^{2});counts" , HistType::kTH2F , {{ 100 , 0 ., 50 .}, {300 , 1.60 , 2.60 }});
333333 for (int iBeautyPart{0 }; iBeautyPart < kNBeautyParticles ; ++iBeautyPart) {
334- hMassB [iBeautyPart] = registry.add <TH1 >(Form (" fMass %s" , beautyParticleNames[iBeautyPart].data ()), Form (" #it{M} distribution of triggered %s candidates;#it{M} (GeV/#it{c}^{2});counts" , beautyParticleNames[iBeautyPart].data ()), HistType::kTH1F , {{220 , 4.9 , 6.0 }});
334+ hMassVsPtB [iBeautyPart] = registry.add <TH2 >(Form (" fMassVsPt %s" , beautyParticleNames[iBeautyPart].data ()), Form (" #it{M} vs. #it{p}_{T} distribution of triggered %s candidates;#it{p}_{T} (GeV/#it{c});#it{ M} (GeV/#it{c}^{2});counts" , beautyParticleNames[iBeautyPart].data ()), HistType::kTH2F , {{ 100 , 0 ., 50 .}, {220 , 4.9 , 6.0 }});
335335 }
336336 hProtonTPCPID = registry.add <TH2 >(" fProtonTPCPID" , " #it{N}_{#sigma}^{TPC} vs. #it{p} for selected protons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TPC}" , HistType::kTH2F , {{100 , 0 ., 10 .}, {200 , -10 ., 10 .}});
337337 hProtonTOFPID = registry.add <TH2 >(" fProtonTOFPID" , " #it{N}_{#sigma}^{TOF} vs. #it{p} for selected protons;#it{p} (GeV/#it{c});#it{N}_{#sigma}^{TOF}" , HistType::kTH2F , {{100 , 0 ., 10 .}, {200 , -10 ., 10 .}});
@@ -424,16 +424,17 @@ struct HfFilter { // Main struct for HF triggers
424424 // / Basic additional selection of D0 candidates
425425 // / \param pTrackPos is the positive track momentum
426426 // / \param pTrackNeg is the negative track momentum
427+ // / \param ptD is the pt of the D0 meson candidate
427428 // / \return 1 for D0, 2 for D0bar, 3 for both
428429 template <typename T>
429- int isSelectedD0InMassRange (const T& pTrackPos, const T& pTrackNeg)
430+ int isSelectedD0InMassRange (const T& pTrackPos, const T& pTrackNeg, const float & ptD )
430431 {
431432 auto invMassD0 = RecoDecay::M (std::array{pTrackPos, pTrackNeg}, std::array{massPi, massK});
432433 auto invMassD0bar = RecoDecay::M (std::array{pTrackPos, pTrackNeg}, std::array{massK, massPi});
433434
434435 if (activateQA) {
435- hMassC [kD0 ]->Fill (invMassD0);
436- hMassC [kD0 ]->Fill (invMassD0bar);
436+ hMassVsPtC [kD0 ]->Fill (ptD, invMassD0);
437+ hMassVsPtC [kD0 ]->Fill (ptD, invMassD0bar);
437438 }
438439
439440 int retValue = 0 ;
@@ -447,17 +448,18 @@ struct HfFilter { // Main struct for HF triggers
447448 return retValue;
448449 }
449450
450- // / Basic additional selection of D0 candidates
451+ // / Basic additional selection of D+ candidates
451452 // / \param pTrackSameChargeFirst is the first same-charge track momentum
452453 // / \param pTrackSameChargeFirst is the second same-charge track momentum
453454 // / \param pTrackSameChargeFirst is the opposite charge track momentum
455+ // / \param ptD is the pt of the D+ meson candidate
454456 // / \return true for D+
455457 template <typename T>
456- bool isSelectedDplusInMassRange (const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge)
458+ bool isSelectedDplusInMassRange (const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float & ptD )
457459 {
458460 auto invMassDplus = RecoDecay::M (std::array{pTrackSameChargeFirst, pTrackSameChargeSecond, pTrackOppositeCharge}, std::array{massPi, massPi, massK});
459461 if (activateQA) {
460- hMassC [kDplus ]->Fill (invMassDplus);
462+ hMassVsPtC [kDplus ]->Fill (ptD, invMassDplus);
461463 }
462464
463465 if (std::abs (invMassDplus - massDPlus) > 0.04 ) {
@@ -467,13 +469,14 @@ struct HfFilter { // Main struct for HF triggers
467469 return true ;
468470 }
469471
470- // / Basic additional selection of D0 candidates
472+ // / Basic additional selection of Ds candidates
471473 // / \param pTrackSameChargeFirst is the first same-charge track momentum
472474 // / \param pTrackSameChargeFirst is the second same-charge track momentum
473475 // / \param pTrackSameChargeFirst is the opposite charge track momentum
476+ // / \param ptD is the pt of the Ds meson candidate
474477 // / \return BIT(0) for KKpi, BIT(1) for piKK, BIT(2) for phipi, BIT(3) for piphi
475478 template <typename T>
476- int isSelectedDsInMassRange (const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge)
479+ int isSelectedDsInMassRange (const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float & ptD )
477480 {
478481 auto invMassKKFirst = RecoDecay::M (std::array{pTrackSameChargeFirst, pTrackOppositeCharge}, std::array{massK, massK});
479482 auto invMassKKSecond = RecoDecay::M (std::array{pTrackSameChargeSecond, pTrackOppositeCharge}, std::array{massK, massK});
@@ -482,8 +485,8 @@ struct HfFilter { // Main struct for HF triggers
482485 auto invMassDsToPiKK = RecoDecay::M (std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massPi, massK, massK});
483486
484487 if (activateQA) {
485- hMassC [kDs ]->Fill (invMassDsToKKPi);
486- hMassC [kDs ]->Fill (invMassDsToPiKK);
488+ hMassVsPtC [kDs ]->Fill (ptD, invMassDsToKKPi);
489+ hMassVsPtC [kDs ]->Fill (ptD, invMassDsToPiKK);
487490 }
488491
489492 int retValue = 0 ;
@@ -503,20 +506,21 @@ struct HfFilter { // Main struct for HF triggers
503506 return retValue;
504507 }
505508
506- // / Basic additional selection of D0 candidates
509+ // / Basic additional selection of Lc candidates
507510 // / \param pTrackSameChargeFirst is the first same-charge track momentum
508511 // / \param pTrackSameChargeFirst is the second same-charge track momentum
509512 // / \param pTrackSameChargeFirst is the opposite charge track momentum
513+ // / \param ptLc is the pt of the D0 meson candidate
510514 // / \return 1 for pKpi, 2 for piKp, 3 for both
511515 template <typename T>
512- int isSelectedLcInMassRange (const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge)
516+ int isSelectedLcInMassRange (const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float & ptLc )
513517 {
514518 auto invMassLcToPKPi = RecoDecay::M (std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massProton, massK, massPi});
515519 auto invMassLcToPiKP = RecoDecay::M (std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massPi, massK, massProton});
516520
517521 if (activateQA) {
518- hMassC [kLc ]->Fill (invMassLcToPKPi);
519- hMassC [kLc ]->Fill (invMassLcToPiKP);
522+ hMassVsPtC [kLc ]->Fill (ptLc, invMassLcToPKPi);
523+ hMassVsPtC [kLc ]->Fill (ptLc, invMassLcToPiKP);
520524 }
521525
522526 int retValue = 0 ;
@@ -530,20 +534,21 @@ struct HfFilter { // Main struct for HF triggers
530534 return retValue;
531535 }
532536
533- // / Basic additional selection of D0 candidates
537+ // / Basic additional selection of Xic candidates
534538 // / \param pTrackSameChargeFirst is the first same-charge track momentum
535539 // / \param pTrackSameChargeFirst is the second same-charge track momentum
536540 // / \param pTrackSameChargeFirst is the opposite charge track momentum
541+ // / \param ptXic is the pt of the D0 meson candidate
537542 // / \return 1 for pKpi, 2 for piKp, 3 for both
538543 template <typename T>
539- int isSelectedXicInMassRange (const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge)
544+ int isSelectedXicInMassRange (const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const float & ptXic )
540545 {
541546 auto invMassXicToPKPi = RecoDecay::M (std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massProton, massK, massPi});
542547 auto invMassXicToPiKP = RecoDecay::M (std::array{pTrackSameChargeFirst, pTrackOppositeCharge, pTrackSameChargeSecond}, std::array{massPi, massK, massProton});
543548
544549 if (activateQA) {
545- hMassC [kXic ]->Fill (invMassXicToPKPi);
546- hMassC [kXic ]->Fill (invMassXicToPiKP);
550+ hMassVsPtC [kXic ]->Fill (ptXic, invMassXicToPKPi);
551+ hMassVsPtC [kXic ]->Fill (ptXic, invMassXicToPiKP);
547552 }
548553
549554 int retValue = 0 ;
@@ -613,7 +618,7 @@ struct HfFilter { // Main struct for HF triggers
613618 // apply ML models
614619 if (applyML) {
615620 // TODO: add more feature configurations
616- std::vector<float > inputFeatures2P{trackPos.pt (), trackPos.dcaXY (), trackNeg. dcaXY (), trackNeg.pt (), trackPos. dcaZ (), trackNeg.dcaZ ()}; // FIXME: order of variables once new model uploaded
621+ std::vector<float > inputFeatures2P{trackPos.pt (), trackPos.dcaXY (), trackPos. dcaZ (), trackNeg.pt (), trackNeg. dcaXY (), trackNeg.dcaZ ()};
617622 std::vector<Ort::Value> inputTensor2P;
618623 inputTensor2P.push_back (Ort::Experimental::Value::CreateTensor<float >(inputFeatures2P.data (), inputFeatures2P.size (), inputShapesML2P[0 ]));
619624
@@ -650,10 +655,11 @@ struct HfFilter { // Main struct for HF triggers
650655 continue ;
651656 }
652657
653- auto selD0 = isSelectedD0InMassRange (pVecPos, pVecNeg);
654-
655658 auto pVec2Prong = RecoDecay::PVec (pVecPos, pVecNeg);
656659 auto pt2Prong = RecoDecay::Pt (pVec2Prong);
660+
661+ auto selD0 = isSelectedD0InMassRange (pVecPos, pVecNeg, pt2Prong);
662+
657663 if (pt2Prong >= pTThreshold2Prong) {
658664 keepEvent[kHighPt ] = true ;
659665 if (activateQA) {
@@ -676,14 +682,16 @@ struct HfFilter { // Main struct for HF triggers
676682 if (!keepEvent[kBeauty ] && isBeautyTagged) {
677683 if (isSelectedTrackForBeauty (track, kBeauty3Prong ) && (((selD0 == 1 || selD0 == 3 ) && track.signed1Pt () < 0 ) || (selD0 >= 2 && track.signed1Pt () > 0 ))) {
678684 auto massCand = RecoDecay::M (std::array{pVec2Prong, pVecThird}, std::array{massD0, massPi});
685+ auto pVecBeauty3Prong = RecoDecay::PVec (pVec2Prong, pVecThird);
686+ auto ptCand = RecoDecay::Pt (pVecBeauty3Prong);
679687 if (std::abs (massCand - massBPlus) <= deltaMassBPlus) {
680688 keepEvent[kBeauty ] = true ;
681689 if (activateQA) {
682- hMassB [kBplus ]->Fill (massCand);
690+ hMassVsPtB [kBplus ]->Fill (ptCand, massCand);
683691 }
684692 } else if (std::abs (massCand - massDStar) <= deltaMassDStar) { // additional check for B0->D*pi polarization studies
685693 if (activateQA) {
686- hMassC [kNCharmParticles ]->Fill (massCand);
694+ hMassVsPtC [kNCharmParticles ]->Fill (ptCand, massCand);
687695 }
688696 for (const auto & trackB : tracks) { // start loop over tracks
689697 if (track.signed1Pt () * trackB.signed1Pt () < 0 && isSelectedTrackForBeauty (trackB, kBeauty3Prong )) {
@@ -692,7 +700,9 @@ struct HfFilter { // Main struct for HF triggers
692700 if (std::abs (massCandB0 - massB0) <= deltaMassB0) {
693701 keepEvent[kBeauty ] = true ;
694702 if (activateQA) {
695- hMassB[kB0toDStar ]->Fill (massCandB0);
703+ auto pVecBeauty4Prong = RecoDecay::PVec (pVec2Prong, pVecThird, pVecFourth);
704+ auto ptCandBeauty4Prong = RecoDecay::Pt (pVecBeauty4Prong);
705+ hMassVsPtB[kB0toDStar ]->Fill (ptCandBeauty4Prong, massCandB0);
696706 }
697707 }
698708 }
@@ -735,30 +745,31 @@ struct HfFilter { // Main struct for HF triggers
735745 std::array<float , 3 > pVecSecond = {trackSecond.px (), trackSecond.py (), trackSecond.pz ()};
736746 std::array<float , 3 > pVecThird = {trackThird.px (), trackThird.py (), trackThird.pz ()};
737747
748+ float sign3Prong = trackFirst.signed1Pt () * trackSecond.signed1Pt () * trackThird.signed1Pt ();
749+
750+ // TODO: add ML selections here
751+ n3Prongs++;
752+
753+ auto pVec3Prong = RecoDecay::PVec (pVecFirst, pVecSecond, pVecThird);
754+ auto pt3Prong = RecoDecay::Pt (pVec3Prong);
755+
738756 bool isDPlusInMass = false ;
739757 int isDsInMass = 0 ;
740758 int isLcInMass = 0 ;
741759 int isXicInMass = 0 ;
742760 if (isDPlus) {
743- isDPlusInMass = isSelectedDplusInMassRange (pVecFirst, pVecThird, pVecSecond);
761+ isDPlusInMass = isSelectedDplusInMassRange (pVecFirst, pVecThird, pVecSecond, pt3Prong );
744762 }
745763 if (isDs) {
746- isDsInMass = isSelectedDsInMassRange (pVecFirst, pVecThird, pVecSecond);
764+ isDsInMass = isSelectedDsInMassRange (pVecFirst, pVecThird, pVecSecond, pt3Prong );
747765 }
748766 if (isLc) {
749- isLcInMass = isSelectedLcInMassRange (pVecFirst, pVecThird, pVecSecond);
767+ isLcInMass = isSelectedLcInMassRange (pVecFirst, pVecThird, pVecSecond, pt3Prong );
750768 }
751769 if (isXic) {
752- isXicInMass = isSelectedXicInMassRange (pVecFirst, pVecThird, pVecSecond);
770+ isXicInMass = isSelectedXicInMassRange (pVecFirst, pVecThird, pVecSecond, pt3Prong );
753771 }
754772
755- float sign3Prong = trackFirst.signed1Pt () * trackSecond.signed1Pt () * trackThird.signed1Pt ();
756-
757- // TODO: add ML selections here
758- n3Prongs++;
759-
760- auto pVec3Prong = RecoDecay::PVec (pVecFirst, pVecSecond, pVecThird);
761- auto pt3Prong = RecoDecay::Pt (pVec3Prong);
762773 if (pt3Prong >= pTThreshold3Prong) {
763774 keepEvent[kHighPt ] = true ;
764775 if (activateQA) {
@@ -797,7 +808,9 @@ struct HfFilter { // Main struct for HF triggers
797808 if (std::abs (massCandB - massBeautyHypos[iHypo]) <= deltaMassHypos[iHypo]) {
798809 keepEvent[kBeauty ] = true ;
799810 if (activateQA) {
800- hMassB[iHypo + 2 ]->Fill (massCandB);
811+ auto pVecBeauty4Prong = RecoDecay::PVec (pVec3Prong, pVecFourth);
812+ auto ptCandBeauty4Prong = RecoDecay::Pt (pVecBeauty4Prong);
813+ hMassVsPtB[iHypo + 2 ]->Fill (ptCandBeauty4Prong, massCandB);
801814 }
802815 }
803816 }
0 commit comments