diff --git a/PWGHF/Utils/utilsEvSelHf.h b/PWGHF/Utils/utilsEvSelHf.h index b3be162359d..660815ce946 100644 --- a/PWGHF/Utils/utilsEvSelHf.h +++ b/PWGHF/Utils/utilsEvSelHf.h @@ -114,6 +114,7 @@ enum EventRejection { NoCollInTimeRangeStandard, NoCollInRofStandard, UpcEventCut, + UpcZdcNeutronClass, Chi2, PositionZ, NEventRejection @@ -121,9 +122,33 @@ enum EventRejection { using HfCollisionRejectionMask = uint32_t; // 32 bits, in case new ev. selections will be added +enum UpcZdcNeutronClassSelection { + kXn0n = 0, + k0nXn, + kInvalid +}; + const o2::framework::AxisSpec axisEvents = {EventRejection::NEventRejection, -0.5f, +EventRejection::NEventRejection - 0.5f, ""}; const o2::framework::AxisSpec axisUpcEvents = {o2::aod::sgselector::DoubleGap + 1, -0.5f, +o2::aod::sgselector::DoubleGap + 0.5f, ""}; +template +int getUpcZdcNeutronClass(TBc const& bc, const float zdcTimeMin, const float zdcTimeMax) +{ + if (!bc.has_zdc()) { + return UpcZdcNeutronClassSelection::kInvalid; + } + const auto zdc = bc.zdc(); + const bool isZNAinTime = zdc.timeZNA() >= zdcTimeMin && zdc.timeZNA() <= zdcTimeMax; + const bool isZNCinTime = zdc.timeZNC() >= zdcTimeMin && zdc.timeZNC() <= zdcTimeMax; + if (isZNAinTime && !isZNCinTime) { + return UpcZdcNeutronClassSelection::kXn0n; + } + if (!isZNAinTime && isZNCinTime) { + return UpcZdcNeutronClassSelection::k0nXn; + } + return UpcZdcNeutronClassSelection::kInvalid; +} + /// \brief Function to put labels on monitoring histogram /// \param hRejection monitoring histogram /// \param softwareTriggerLabel bin label for software trigger rejection @@ -140,6 +165,7 @@ void setEventRejectionLabels(Histo& hRejection, std::string const& softwareTrigg hRejection->GetXaxis()->SetBinLabel(EventRejection::TimeFrameBorderCut + 1, "TF border"); hRejection->GetXaxis()->SetBinLabel(EventRejection::ItsRofBorderCut + 1, "ITS ROF border"); hRejection->GetXaxis()->SetBinLabel(EventRejection::UpcEventCut + 1, "UPC event"); + hRejection->GetXaxis()->SetBinLabel(EventRejection::UpcZdcNeutronClass + 1, "UPC ZDC 0nXn/Xn0n"); hRejection->GetXaxis()->SetBinLabel(EventRejection::IsGoodZvtxFT0vsPV + 1, "PV #it{z} consistency FT0 timing"); hRejection->GetXaxis()->SetBinLabel(EventRejection::NoSameBunchPileup + 1, "No same-bunch pile-up"); // POTENTIALLY BAD FOR BEAUTY ANALYSES hRejection->GetXaxis()->SetBinLabel(EventRejection::Occupancy + 1, "Occupancy"); @@ -185,6 +211,8 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { o2::framework::Configurable rctCheckZDC{"rctCheckZDC", false, "RCT flag to check whether the ZDC is present or not"}; o2::framework::Configurable rctTreatLimitedAcceptanceAsBad{"rctTreatLimitedAcceptanceAsBad", false, "RCT flag to reject events with limited acceptance for selected detectors"}; o2::framework::Configurable irSource{"irSource", "", "Estimator of the interaction rate (Empty: automatically set. Otherwise recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; + o2::framework::Configurable upcZdcTimeMin{"upcZdcTimeMin", -2.f, "Minimum ZDC time for UPC neutron class selection (ns)"}; + o2::framework::Configurable upcZdcTimeMax{"upcZdcTimeMax", 2.f, "Maximum ZDC time for UPC neutron class selection (ns)"}; // SG selector SGSelector sgSelector; @@ -435,6 +463,10 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { if (upcEventType > o2::aod::sgselector::DoubleGap) { SETBIT(rejectionMaskWithUpc, EventRejection::UpcEventCut); } else { + const auto upcZdcNeutronClass = getUpcZdcNeutronClass(*sgSelectionResult.bc, upcZdcTimeMin, upcZdcTimeMax); + if (upcZdcNeutronClass != UpcZdcNeutronClassSelection::kXn0n && upcZdcNeutronClass != UpcZdcNeutronClassSelection::k0nXn) { + SETBIT(rejectionMaskWithUpc, EventRejection::UpcZdcNeutronClass); + } hUpCollisions->Fill(upcEventType); } }