Skip to content

[PWGHF] Added trigger for Sc-proton correlation#14786

Open
singhra1994 wants to merge 10 commits intoAliceO2Group:masterfrom
singhra1994:master
Open

[PWGHF] Added trigger for Sc-proton correlation#14786
singhra1994 wants to merge 10 commits intoAliceO2Group:masterfrom
singhra1994:master

Conversation

@singhra1994
Copy link
Collaborator

I have modified the block trigger SigmaCPPK in such a way that both SigmaCPPK and SigmaCP can be filled in the same block

Added parameters for Sigma_C trigger selection and updated event tagging logic for SigmaC candidates.
Added support for SigmaC particle selection in the HfFilterHelper class.
[Trigger,PWGHF] Please consider the following formatting changes to AliceO2Group#14786
Copy link
Collaborator

@fgrosa fgrosa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @singhra1994 I still didn't look into the helper functions, but I already spotted several issues in the logic of the filter itself. Please implement the suggestions, and then I will take a look at the helper functions as well.

float deltaEta = std::abs(RecoDecay::eta(pVecSigmaC) - track.eta() && pt3Prong < 3.0);
if (configSigmaC.isTrigSigmaCP && isTrackProton && deltaEta < 1.0) {

auto tagBDT = helper.isBDTSelected(scores[2], thresholdBDTScores[5]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

be careful that this only works if thresholdBDTScores[5] is tighter than thresholdBDTScores[4]

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, I assumed that BDT cut on 3 prong creators should be looser, I only need stronger BDT on sigmaCpr trigger if there is the problem in reaching required selectivity

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok! Please put it separately, as cut for your trigger only to avoid confusion (since as it is now in the configurables, it seems that it is applied for all SigmaC states).

Copy link
Collaborator

@fgrosa fgrosa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @singhra1994, thanks for addressing my comments! The code looks correct to me now, but I would like to ask @mfaggin also to check that I didn't overlook any other bug that might affect the SigmaC-K triggers.
Please also address my remaining comments and then as discussed in the trigger meeting, verify that the output of the task is identical for the other triggers before and after your changes, so that we can then merge it. Thanks!

Comment on lines +159 to +162
Configurable<float> minMassSigmaCCorr{"minMassSigmaCCorr", 0.15, "minimum mass of SigmaC for correlation with proton"};
Configurable<float> maxMassSigmaCCorr{"maxMassSigmaCCorr", 0.19, "maximum mass of SigmaC for correlation with proton"};
Configurable<float> minPtSigmaC{"minPtSigmaC", 4.99, "minimum pT of SigmaC for correlation with proton"};
Configurable<float> maxPtSigmaC{"maxPtSigmaC", 12.0, "maximum pT of SigmaC for correlation with proton"};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put these configurables in the labelled array with masses and pT cuts for resonances (cutsPtDeltaMassCharmReso), adding more columns (and a meaningful name for the label, e.g. SigmaCForPrCorr or something similar)

Configurable<LabeledArray<double>> thresholdBDTScoreDSToPiKK{"thresholdBDTScoreDSToPiKK", {hf_cuts_bdt_multiclass::Cuts[0], hf_cuts_bdt_multiclass::NBinsPt, hf_cuts_bdt_multiclass::NCutBdtScores, hf_cuts_bdt_multiclass::labelsPt, hf_cuts_bdt_multiclass::labelsCutBdt}, "Threshold values for BDT output scores of Ds+ candidates"};
Configurable<LabeledArray<double>> thresholdBDTScoreLcToPiKP{"thresholdBDTScoreLcToPiKP", {hf_cuts_bdt_multiclass::Cuts[0], hf_cuts_bdt_multiclass::NBinsPt, hf_cuts_bdt_multiclass::NCutBdtScores, hf_cuts_bdt_multiclass::labelsPt, hf_cuts_bdt_multiclass::labelsCutBdt}, "Threshold values for BDT output scores of Lc+ candidates"};
Configurable<LabeledArray<double>> thresholdBDTScoreXicToPiKP{"thresholdBDTScoreXicToPiKP", {hf_cuts_bdt_multiclass::Cuts[0], hf_cuts_bdt_multiclass::NBinsPt, hf_cuts_bdt_multiclass::NCutBdtScores, hf_cuts_bdt_multiclass::labelsPt, hf_cuts_bdt_multiclass::labelsCutBdt}, "Threshold values for BDT output scores of Xic+ candidates"};
Configurable<LabeledArray<double>> thresholdBDTScoreScLcToPiKP{"thresholdBDTScoreScLcToPiKP", {hf_cuts_bdt_multiclass::Cuts[0], hf_cuts_bdt_multiclass::NBinsPt, hf_cuts_bdt_multiclass::NCutBdtScores, hf_cuts_bdt_multiclass::labelsPt, hf_cuts_bdt_multiclass::labelsCutBdt}, "Threshold values for BDT output scores of Lc<--Sc candidates"};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put this separately, in the cuts for your trigger only

Comment on lines +152 to +158
Configurable<std::vector<int>> trkPIDspecies{"trkPIDspecies", std::vector<int>{o2::track::PID::Proton, o2::track::PID::Pion, o2::track::PID::Kaon}, "Trk sel: Particles species for PID, proton, pion, kaon"};
Configurable<std::vector<float>> pidTPCMax{"pidTPCMax", std::vector<float>{3., 0., 0.}, "maximum nSigma TPC"};
Configurable<std::vector<float>> pidTOFMax{"pidTOFMax", std::vector<float>{3., 0., 0.}, "maximum nSigma TOF"};
Configurable<bool> forceTOF{"forceTOF", false, "fill PID information for associated tracks"};
Configurable<float> tofPIDThreshold{"tofPIDThreshold", 1.0, "minimum pT after which TOF PID is applicable"};
Configurable<float> minPtProton{"minPtProton", 0.39, "minimum pT for associated proton"};
Configurable<float> maxPtProton{"maxPtProton", 4.51, "maximum pT for associated proton"};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't put a prefix to your configurable group, it will be impossible to understand what these configurables refer to. Please either add a suffix, or even better use a LabeledArray containing the cuts for your trigger as done for the others, so that it is easier to configure.


// array of BDT thresholds
std::array<LabeledArray<double>, kNCharmParticles> thresholdBDTScores;
std::array<LabeledArray<double>, kNCharmParticles + 1> thresholdBDTScores;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please put it separately

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this comment: leave your BDT fully independent from the others which are general for the triggers.

float deltaEta = std::abs(RecoDecay::eta(pVecSigmaC) - track.eta() && pt3Prong < 3.0);
if (configSigmaC.isTrigSigmaCP && isTrackProton && deltaEta < 1.0) {

auto tagBDT = helper.isBDTSelected(scores[2], thresholdBDTScores[5]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok! Please put it separately, as cut for your trigger only to avoid confusion (since as it is now in the configurables, it seems that it is applied for all SigmaC states).

}
}
}
return true; // Passed all checks
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before returning true, I suggest you to fill an histogram of Nsigma Vs Pt to monitor that you are indeed selecting what you want

return false;
}

for (size_t speciesIndex = 0; speciesIndex < mPIDspecies.value.size(); ++speciesIndex) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it needed to iterate over the PID hypotheses? Can't you simply test the proton PID since this is the only trigger foreseen?


/// Delta mass selection on SigmaC candidates for correlation
template <typename T, typename H2>
inline bool HfFilterHelper::selectionSigmaCForScPCorr(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const T& pTrackSoftPi, const float ptSigmaC, const int8_t isSelectedLc, H2 hMassVsPt, const int& activateQA, float mDeltaMassMinSigmaC, float mDeltaMassMaxSigmaC, float mPtMinSigmaC, float mPtMaxSigmaC)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need another function? Can't this be included in the already existing one (isSelectedSigmaCInDeltaMassRange) adding new bits?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can use a single function but I am afraid it need lot of input in the function, ex.

template <int charge = -1, typename T, typename H2>
inline int8_t HfFilterHelper::isSelectedSigmaCInDeltaMassRange(
  const T& pTrackSameChargeFirst,
  const T& pTrackSameChargeSecond,
  const T& pTrackOppositeCharge,
  const T& pTrackSoftPi,
  const float ptSigmaC,
  const int8_t isSelectedLc,
  H2 hMassVsPt,
  const int& activateQA,
  bool useInvMassforScPr,
  float mDeltaMassMinSigmaC,
  float mDeltaMassMaxSigmaC,
  float mPtMinSigmaC,
  float mPtMaxSigmaC)
{}

or I can define some variable as a private member of class and then pass a function to initialize these variables, but as of now I think it would be commit and in second version I can optimize the code

}
}
float deltaEta = std::abs(RecoDecay::eta(pVecSigmaC) - track.eta());
if (!keepEvent[kSigmaCPr] && (isTrackProton && deltaEta < 1.0 && pt3Prong > 3.0)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you have an hard-coded cut on the pt3Prong? Can't you put a configurable?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Fabrizio for mentioning it, this is even irrelevant cut , I will remove it. This was a check, I was thinking that that pT Lc and pT Sc are correlated and by applying pTLc cut as a function of pTSc, I will be able to reduce the background. Though, I was wrong, I checked it and found that in the selected invariant mass of Sc, pT of Lc is always remain in the range pTSc -2 to pTSc +0.5. Therefore, from the current version, let me just remove it online.

Copy link
Collaborator

@mfaggin mfaggin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @fgrosa @singhra1994 I tried to go through the modifications and I posted some comments. It looks to me that the already existing trigger Sc-K is not affected by the proposed modifications, but I have a couple of warnings/comments for the Sc-p part.

std::array<std::shared_ptr<TH1>, kNCharmParticles> hCharmDeuteronKstarDistr{};
std::array<std::shared_ptr<TH2>, nTotBeautyParts> hMassVsPtB{};
std::array<std::shared_ptr<TH2>, kNCharmParticles + 23> hMassVsPtC{}; // +9 for resonances (D*+, D*0, Ds*+, Ds1+, Ds2*+, Xic+* right sign, Xic+* wrong sign, Xic0* right sign, Xic0* wrong sign) +2 for SigmaC (SigmaC++, SigmaC0) +2 for SigmaCK pairs (SigmaC++K-, SigmaC0K0s) +3 for charm baryons (Xi+Pi, Xi+Ka, Xi+Pi+Pi) + JPsi + 4 for charm baryons (D0+p, D0+pWrongSign, D*0p, D*0+pWrongSign)
std::array<std::shared_ptr<TH2>, kNCharmParticles + 24> hMassVsPtC{}; // +9 for resonances (D*+, D*0, Ds*+, Ds1+, Ds2*+, Xic+* right sign, Xic+* wrong sign, Xic0* right sign, Xic0* wrong sign) +2 for SigmaC (SigmaC++, SigmaC0) +2 for SigmaCK pairs (SigmaC++K-, SigmaC0K0s) +3 for charm baryons (Xi+Pi, Xi+Ka, Xi+Pi+Pi) + JPsi + 4 for charm baryons (D0+p, D0+pWrongSign, D*0p, D*0+pWrongSign)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(very very minor) update also the comment

bool isTrackProton = helper.isSelectedTrack4Corr(track, configSigmaC.trkPIDspecies, configSigmaC.pidTPCMax, configSigmaC.pidTOFMax, configSigmaC.minPtProton, configSigmaC.maxPtProton, configSigmaC.tofPIDThreshold, configSigmaC.forceTOF);

if ((!keepEvent[kSigmaCPPK] || !keepEvent[kSigmaCPr]) && is3Prong[2] > 0 && is3ProngInMass[2] > 0 && isSignalTagged[2] > 0 && (isTrackKaon || isTrackProton)) {
// we need a candidate Lc->pKpi and a candidate soft kaon
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(minor) also here update the comment to improve the readibility (this is valid a bit everywhere)

// check the mass of the SigmaC++,0 candidate
auto pVecSigmaC = RecoDecay::pVec(pVecFirst, pVecSecond, pVecThird, pVecSoftPi);
auto ptSigmaC = RecoDecay::pt(pVecSigmaC);
int8_t whichSigmaC = helper.isSelectedSigmaCInDeltaMassRange<2>(pVecFirst, pVecThird, pVecSecond, pVecSoftPi, ptSigmaC, is3Prong[2], hMassVsPtC[kNCharmParticles + 9], activateQA);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a warning here: the function helper.isSelectedSigmaCInDeltaMassRange<2> does a selection around the Sigmac++ mass only (note the <2> template parameter, which refers to the Sigmac charge). This is what we wanted for the already-existing triggers (Sc-K), but in your case you want correlations for both Sc0 and Sc++.

Mine is just a warning just because the masses of Sc0 and Sc++ are very very similar and this should be pretty harmless, but for your interest I suggest you to cross-check once more if there are other charge-dependent selections/functions that might not hold for your use-case.

@@ -1560,51 +1577,59 @@ struct HfFilter { // Main struct for HF triggers
/// - it is in the correct mass range

// check the charge for SigmaC++K- candidates
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again: update the comment. At this stage not only the Sc-K total charge is checked, but also the Sc one

}
}
}
float deltaEta = std::abs(RecoDecay::eta(pVecSigmaC) - track.eta());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, at this stage it might be useful to have a comment of what you are doing, i.e. the fact that now you want to check the Sc-p correlation etc etc


// array of BDT thresholds
std::array<LabeledArray<double>, kNCharmParticles> thresholdBDTScores;
std::array<LabeledArray<double>, kNCharmParticles + 1> thresholdBDTScores;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this comment: leave your BDT fully independent from the others which are general for the triggers.

template <typename T1, typename T2, typename H2>
bool isSelectedTrack4Femto(const T1& track, const T2& trackPar, const int& activateQA, H2 hTPCPID, H2 hTOFPID, const int& trackSpecies);
template <typename Atrack, typename SpeciesContainer, typename T1, typename T2>
bool isSelectedTrack4Corr(Atrack const& track, SpeciesContainer const mPIDspecies, T1 const maxTPC, T2 const maxTOF, float minPt = 0.39, float maxPt = 4.6, float ptThreshold = 1.0, bool tofForced = false);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

personally, I'd avoid default parameter values here

template <int charge, typename T, typename H2>
int8_t isSelectedSigmaCInDeltaMassRange(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const T& pTrackSoftPi, const float ptSigmaC, const int8_t isSelectedLc, H2 hMassVsPt, const int& activateQA);
template <typename T, typename H2>
bool selectionSigmaCForScPCorr(const T& pTrackSameChargeFirst, const T& pTrackSameChargeSecond, const T& pTrackOppositeCharge, const T& pTrackSoftPi, const float ptSigmaC, const int8_t isSelectedLc, H2 hMassVsPt, const int& activateQA, float mDeltaMassMinSigmaC = 0.155, float mDeltaMassMaxSigmaC = 0.2, float mPtMinSigmaC = 4.99, float mPtMaxSigmaC = 12.0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

personally, I'd avoid default parameter values here

Comment on lines +933 to +942
/// Basic selection of proton or deuteron candidates
/// \param track is a track
/// \param mPIDspecies is a vector of different particle species
/// \param activateQA flag to activate the filling of QA histos
/// \param maxTPC is a vector of max TPCnSigma for different particle species
/// \param maxTOF is a vector of max TOFnSigma for different particle species
/// \param hProtonTPCPID histo with NsigmaTPC vs. p
/// \param hProtonTOFPID histo with NsigmaTOF vs. p
/// \return true if track passes all cuts
template <typename Atrack, typename SpeciesContainer, typename T1, typename T2>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this description is not consistent, and confusing. For example, during my review I was looking for an explanation of ptThreshold, which as far as I understand is the minimum pt at which you want to force the TOF for the proton (right?).

Please fix the description and possibly give meanigful names to the variables

Comment on lines +1010 to +1033
if (speciesIndex == 0) { // First species logic

if (std::abs(nSigmaTPC) > maxTPC->at(speciesIndex)) {
return false; // TPC check failed
}
if (track.hasTOF()) {
auto nSigmaTOF = o2::aod::pidutils::tofNSigma(pid, track);
if (std::abs(nSigmaTOF) > maxTOF->at(speciesIndex)) {
return false; // TOF check failed
}
}
} else { // Other species logic
if (std::abs(nSigmaTPC) < maxTPC->at(speciesIndex)) { // Check TPC nSigma first
if (track.hasTOF()) {
auto nSigmaTOF = o2::aod::pidutils::tofNSigma(pid, track);
if (std::abs(nSigmaTOF) < maxTOF->at(speciesIndex)) {
return false; // Reject if both TPC and TOF are within thresholds
}
} else {
return false; // Reject if only TPC is within threshold and TOF is unavailable
}
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I have a few questions

  1. I agree with Fabrizio's comment, I do not understand why you loop over species and not just proton. Do you need to check other species (kaon, pion) because you want to apply a kaon and/or pion PID rejection? This is what I grasp from the code, but comments would help the reader

  2. Why you treat differently the case speciesIndex == 0 from the others (once more: comment the code for the sake of readability)? Is it because the case speciesIndex == 0 corresponds to the proton hypothesis, and this is a special case for you (i.e. the "signal" one), while the others are used for PID rejection? If yes, then I find the solution of having the proton hypothesis as the 1st entry of a Configurable vector a bit error-prone (I'm referring to Configurable<std::vector<int>> trkPIDspecies). In case you want a PID rejection for other species, then I'd remove the proton from the Configurable vector, and use this vector only for the species you want to use for the PID rejection (in other words: if by mistake one configures the vector with the order e.g. ka-pi-pr your logic is fully broken, but you can easily remove this possible mistake dedicateing the Configurable vector for the species to be rejected).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mfaggin I have defined this function in this way in HFCL analysis so that every one can use it for each combination of particle selection and rejection
Here, now I am not thinking to use piK rejection and hence code will be modified accordingly

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I see. It's not up to me to decide, but since the definition of the trigger program is not like the final analysis, if I were you I'd just keep the piece of code that you need (i.e. treat just the proton case for your trigger) and if somebody else will come then he/she will take care of adding the new functionalities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

4 participants