16 #include "TGraphErrors.h"
22 #include "GaudiKernel/SystemOfUnits.h"
23 #include "GaudiKernel/PhysicalConstants.h"
38 #include "CLHEP/Vector/LorentzVector.h"
40 #include "GaudiKernel/IInterface.h"
48 template <
typename ForwardIterator,
typename T>
50 sequentialFill(ForwardIterator
beg,
const ForwardIterator
stop,
T value,
const T inc){
59 template <
typename Iterator,
typename T,
typename Compare=std::less<T>>
61 findLevel(
const Iterator
beg,
const Iterator
stop,
T value, Compare op=std::less<T>()){
69 return (
v >= lo) and (
v<=hi);
82 m_triggerChainName(
"NoTriggerSelection")
103 return StatusCode::SUCCESS;
137 Double_t phiBins[10]{};
139 Double_t curvatureDiffBins[6]{};
142 sequentialFill(curvatureDiffBins,
std::end(curvatureDiffBins), -0.001,0.0004);
143 m_mass =
new TH1F(
"ks_mass",
"Invariant mass of K^{0}_{S} candidate", 60, 0.45, 0.55);
144 m_mass->SetYTitle(
"K^{0}_{S} Candidates");
145 m_mass->SetXTitle(
"Mass (Gev / c^{2})");
146 m_mass->SetMarkerStyle(20);
149 m_mass_scaled =
new TH1F(
"ks_mass_scaled",
"Invariant mass of K^{0}_{S} candidate scaled to per event", 60, 0.45, 0.55);
156 m_massVsPhi =
new TH2F(
"ks_massVsPhi",
"Invariant mass - world average of K^{0}_{S} candidate", 10, (-1.0*
M_PI),
M_PI, 50, -.5, .5);
158 m_massVsPhi->SetYTitle(
"Mass (Gev / c^{2}) - World Average [MeV]");
161 m_pt =
new TH1F(
"ks_pt",
"p_{T} of K^{0}_{S} candidate", 100, 0., 10.);
162 m_pt->SetYTitle(
"K^{0}_{S} Candidates");
163 m_pt->SetXTitle(
"p_{T} (Gev / c)");
164 m_pt->SetMarkerStyle(20);
167 m_radiusVsZ_secVertex =
new TH2F(
"secVertex_radiusVsZ",
"all sec.vertices (reco);z [mm];Decay radius [mm]",180, -600., 600.,180.,0.,180.);
170 m_YVsX_secVertex =
new TH2F(
"secVertex_YVsX",
"all sec. vertices (reco);x [mm];y [mm]",200, -150.,150., 200, -150., 150.);
173 m_radiusVsZ_secVertex_sel =
new TH2F(
"secVertex_radiusVsZ_sel",
"all sec.vertices (reco);z [mm];Decay radius [mm]",180, -600., 600.,180.,0.,180.);
176 m_YVsX_secVertex_sel =
new TH2F(
"secVertex_YVsX_sel",
"all sec. vertices (reco);x [mm];y [mm]",200, -150.,150., 200, -150., 150.);
179 m_radiusVsZ_secVertex_Ks =
new TH2F(
"secVertex_radiusVsZ_Ks",
"sec.vertices (reco) of K^{0}_{S} candidates;z [mm];Decay radius [mm]",180, -600., 600.,180.,0.,180.);
182 m_YVsX_secVertex_Ks =
new TH2F(
"secVertex_YVsX_Ks",
"sec. vertices (reco) of K^{0}_{S} candidates;x [mm];y [mm]",200, -150.,150., 200, -150., 150.);
191 m_YVsX_primVertex =
new TH2F(
"primVertex_YVsX",
"all primary vertices (reco);PV x [mm];PV y [mm]",300, -1.5,1.5, 300, -1.5, 1.5);
194 m_XVsZ_primVertex =
new TH2F(
"primVertex_XVsZ",
"all primary vertices (reco);PV z [mm];PV x [mm]",200, -350.,350, 300, -1.5, 1.5);
197 m_YVsZ_primVertex =
new TH2F(
"primVertex_YVsZ",
"all primary vertices (reco);PV z [mm];PV y [mm]",200, -350.,350., 100, -1.5, 1.5);
200 m_YVsX_primVertex_Ks =
new TH2F(
"primVertex_YVsX_Ks",
"all primary vertices (reco);PV x [mm];PV y [mm]",300, -1.5,1.5, 300, -1.5, 1.5);
203 m_XVsZ_primVertex_Ks =
new TH2F(
"primVertex_XVsZ_Ks",
"all primary vertices (reco);PV z [mm];PV x [mm]",200, -350.,350, 300, -1.5, 1.5);
206 m_YVsZ_primVertex_Ks =
new TH2F(
"primVertex_YVsZ_Ks",
"all primary vertices (reco);PV z [mm];PV y [mm]",200, -350.,350., 100, -1.5, 1.5);
209 m_radius =
new TH1F(
"ks_radius",
"Decay radius of K^{0}_{S} candidate", 100, 0., 300.);
210 m_radius->SetYTitle(
"K^{0}_{S} Candidates");
211 m_radius->SetXTitle(
"Decay Radius (mm)");
216 m_eta =
new TH1F(
"ks_eta",
"#eta of K^{0}_{S} candidate", 10, -2.5, 2.5);
217 m_eta->SetYTitle(
"K^{0}_{S} Candidates");
218 m_eta->SetXTitle(
"#eta");
219 m_eta->SetMarkerStyle(20);
221 m_phi =
new TH1F(
"ks_phi",
"#phi of K^{0}_{S} candidate", 10, (-1.0*
M_PI),
M_PI);
222 m_phi->SetYTitle(
"K^{0}_{S} Candidates");
223 m_phi->SetXTitle(
"#phi");
224 m_phi->SetMarkerStyle(20);
228 auto quickSet=[](
TH1F *
h){
229 h->SetXTitle(
"Mass (Gev / c^{2})");
230 h->SetYTitle(
"K^{0}_{S} Candidates");
231 h->SetMarkerStyle(20);
235 for(
int quickInit=0;quickInit<
m_nBinsPt;quickInit++) {
236 TString tempName =
"MassVptBin";
237 TString tempTitle =
"Mass, p_{T} = ";
238 tempName += quickInit;
239 tempTitle += ((Double_t)((quickInit*100)+500))/1000;
247 TString tempName =
"MassVptBinFitted";
248 TString tempTitle =
"Fitted Mass, p_{T} = ";
249 tempName += quickInit;
250 tempTitle += ptBins[quickInit];
257 TString tempName =
"MassVradiusBin";
258 TString tempTitle =
"Mass, Decay Radius = ";
259 tempName += quickInit;
260 tempTitle += quickInit*10;
267 TString tempName =
"MassVradiusBinFitted";
268 TString tempTitle =
"Fitted Mass, Decay Radius = ";
269 tempName += quickInit;
270 tempTitle += radiusBins[quickInit];
276 for(
int quickInit=0;quickInit<10;quickInit++) {
277 TString tempName =
"MassVEtaBin";
278 TString tempTitle =
"Mass, #eta = ";
279 tempName += quickInit;
280 tempTitle +=
etaBins[quickInit];
285 tempName =
"MassVPhiBin";
286 tempTitle =
"Mass, #phi = ";
287 tempName += quickInit;
288 tempTitle += ((Double_t)((Int_t)(phiBins[quickInit]*100)))/100;
294 for(
int quickInit=0;quickInit<6;quickInit++) {
295 TString tempName =
"MassVCurvatureDiffBin";
296 TString tempTitle =
"Mass, CurvatureDiff = ";
297 tempName += quickInit;
298 tempTitle += curvatureDiffBins[quickInit];
326 m_Nevents =
new TH1F(
"Nevents",
"Number of events processed",1,-.5,.5);
337 return StatusCode::SUCCESS;
344 if (
sc.isFailure() ) {
352 if (
sc.isFailure() ) {
360 if (
sc.isFailure() ) {
371 if (
sc.isFailure()) {
373 return StatusCode::SUCCESS;
382 return StatusCode::FAILURE;
389 return StatusCode::SUCCESS;
397 return StatusCode::FAILURE;
404 return StatusCode::SUCCESS;
408 double ksMassPDG = 497.648;
411 ATH_MSG_DEBUG(
"@todo >> V0UnconstrVerices container size >> " << SecVxContainer->
size());
413 std::array<float, 5> curvatureBinning{};
414 sequentialFill(curvatureBinning.begin(), curvatureBinning.end(),-0.0008, 0.0004);
416 std::array<double,10> ksPhiBinning{};
417 sequentialFill(ksPhiBinning.begin(), ksPhiBinning.end(), -
M_PI,
M_PI * 0.2);
419 std::array<double,10> ksEtaBinning{};
420 sequentialFill(ksEtaBinning.begin(), ksEtaBinning.end(),-2.5, 0.5);
422 std::array<double,4> ksPtBinning{1600,2100, 2800,3900};
424 std::array<double,6> radiusBinning{30,40, 60,80,100,140};
426 for (
const auto* secVx_elem : *SecVxContainer) {
433 double ksMass = Kshort_massAcc(*secVx_elem);
434 double ksPt = pTAcc(*secVx_elem);
435 double ksPx = pxAcc(*secVx_elem);
436 double ksPy = pyAcc(*secVx_elem);
437 double ksPz = pzAcc(*secVx_elem);
438 ATH_MSG_DEBUG(
" mass : "<<ksMass <<
" pt : "<< ksPt <<
" px : "<< ksPx <<
" py : "<< ksPy <<
" pz : "<< ksPz);
439 CLHEP::Hep3Vector ksMomentumVector = CLHEP::Hep3Vector(ksPx,ksPy,ksPz);
440 double ksMomentum = ksMomentumVector.mag();
441 double transverseFlightDistance, totalFlightDistance;
443 const auto & secVxPosition(secVx_elem->position());
447 const auto & position (primaryVertex->
position());
452 auto vert = secVx_elem->position()-primaryVertex->
position();
453 double dx = vert.x();
454 double dy = vert.y();
457 transverseFlightDistance =dxy;
461 ATH_MSG_DEBUG(
"dx : "<<
dx<<
" dy: "<<
dy<<
" dxy: "<<dxy<<
"flight distance (total): "<<totalFlightDistance);
464 transverseFlightDistance = secVxPosition.perp();
466 totalFlightDistance =
vertex.mag();
472 double flightX = flightVector.x();
473 double flightY = flightVector.y();
474 double cosThetaPointing = (ksPx*flightX+ksPy*flightY)/std::sqrt(ksPx*ksPx+ksPy*ksPy)/std::sqrt(flightX*flightX+flightY*flightY);
475 int trackPos_nSVTHits = 0;
476 int trackNeg_nSVTHits = 0;
477 double trackPos_d0 = 0;
478 double trackPos_d0_wrtPV = 0;
479 double trackNeg_d0 = 0;
480 double trackNeg_d0_wrtPV = 0;
485 ntrk = secVx_elem->nTrackParticles();
486 ATH_MSG_DEBUG(
"track particles associated to vertex : "<<ntrk );
488 auto tpLinks = secVx_elem->trackParticleLinks();
489 for (
const auto& link: tpLinks){
490 Info(
"execute()",
"V0: TP link = %d %s ", link.isValid(), link.dataID().c_str() );
493 if( (*link)->charge() > 0. ) {
497 else if( (*link)->charge() < 0. ){
503 if(trackPos!=
nullptr) {
506 trackPos_d0 = trackPos->
d0();
512 if(trackNeg!=
nullptr) {
515 trackNeg_d0 = trackNeg->
d0();
518 int selectorValue = 0;
519 ATH_MSG_DEBUG(
"ksTau = " << properDecayTime <<
" Lxy = " <<transverseFlightDistance<<
" cosTheta = " << cosThetaPointing );
520 ATH_MSG_DEBUG(
"trackPos nSVThits = " << trackPos_nSVTHits <<
" trackNeg nSVThits = " << trackNeg_nSVTHits );
523 double secVertex_radius = RxyAcc(*secVx_elem);
524 ATH_MSG_DEBUG(
"secondary vertex radius : " << secVertex_radius);
529 ATH_MSG_DEBUG(
"trackneg d0 : " << trackNeg_d0 <<
" trackpos d0 : "<< trackPos_d0);
530 ATH_MSG_DEBUG(
"trackneg d0 (PV): " << trackNeg_d0_wrtPV <<
" trackpos d0 (PV) : "<< trackPos_d0_wrtPV);
531 if(secVx_elem->chiSquared()/secVx_elem->numberDoF() < 4.5
533 && abs(trackNeg_d0_wrtPV) > 5.
534 && abs(trackPos_d0_wrtPV) > 5.
535 && trackPos_nSVTHits > 2
536 && trackNeg_nSVTHits > 2
537 && secVertex_radius > 20.
547 && properDecayTime > 0.004
548 && transverseFlightDistance > 12.
549 && cosThetaPointing > 0.998
550 && ksMass>400.&&ksMass<600.
551 && trackPos_nSVTHits > 2 && trackNeg_nSVTHits > 2
553 if(selectorValue != 1)
continue;
559 m_mass->Fill(ksMass*0.001);
560 double ksEta = ksMomentumVector.pseudoRapidity();
561 double ksPhi = ksMomentumVector.phi();
562 double piPlusPt = trackPos->
p4().Perp();
563 double piMinusPt = trackNeg->
p4().Perp();
565 m_pt->Fill(ksPt*0.001);
568 Float_t curvatureDiff = (1./(piPlusPt)) - (1./(piMinusPt));
569 const auto fillValue(ksMass*0.001);
570 auto curvatureIdx = findLevel(curvatureBinning.begin(), curvatureBinning.end(),curvatureDiff);
573 auto ksPhiIdx = findLevel(ksPhiBinning.begin(), ksPhiBinning.end(), ksPhi, std::less_equal<double>());
576 if (ksEta>=-2.5 and ksEta<2.5){
577 auto ksEtaIdx = findLevel(ksEtaBinning.begin(), ksEtaBinning.end(), ksEta, std::less_equal<double>());
581 auto ksPtIdx = findLevel(ksPtBinning.begin(), ksPtBinning.end(), ksPt, std::less_equal<double>());
585 if (ksPt<500) ksPt = 500;
586 if (ksPt>5000) ksPt=5000;
587 Int_t quickBin = (Int_t)ksPt;
588 quickBin -= quickBin%100;
592 double radius = RxyAcc(*secVx_elem);
595 auto radiusIdx = findLevel(radiusBinning.begin(), radiusBinning.end(),
radius, std::less_equal<double>());
599 Int_t radiusTemp = (Int_t)
radius;
600 radiusTemp -= radiusTemp%10;
603 return StatusCode::SUCCESS;
614 TF1 *func =
new TF1(
"func",
"gaus(0)+expo(3)",0.450,0.550);
615 func->SetLineColor(4);
616 func->SetParameters(10.,0.500,0.010,2.,-.001);
617 func->SetParLimits(0,0.,10000.);
618 func->SetParLimits(1,0.450,0.550);
619 func->SetParLimits(2,0.,0.100);
620 func->SetParLimits(3,0.,10000.);
621 func->SetParLimits(4,-1000.,0.);
622 func->SetParNames(
"Constant",
"Mean",
"Width",
"Constant",
"Slope");
625 Double_t ptBins[nPtBinsHisto] = {0.5,1.6,2.1,2.8,3.9,5.1};
627 massBins[binFill] = func->GetParameter(1);
628 massErrorBins[binFill] = func->GetParError(1);
629 widthBins[binFill] = func->GetParameter(2);
630 widthErrorBins[binFill] = func->GetParError(2);
632 const Double_t* ptBinsFinal = ptBins;
633 const Double_t* massBinsFinal = massBins;
634 const Double_t* massErrorBinsFinal = massErrorBins;
635 const Double_t* widthBinsFinal = widthBins;
636 const Double_t* widthErrorBinsFinal = widthErrorBins;
638 auto setYTitleAndMarker =[](
TH1F * theHist,
const bool mass){
640 theHist->SetYTitle(
"Mass (Gev / c^{2})");
642 theHist->SetYTitle(
"Width (Gev / c^{2})");
644 theHist->SetMarkerStyle(20);
647 auto fillFromSource = [](
const double *
source,
const double * uncertainty,
TH1F *
target,
unsigned int nbins){
650 double binError = uncertainty[
bin];
651 target->SetBinContent(
bin+1, binContent);
655 constexpr
bool massTitle{
true};
656 constexpr
bool widthTitle{
false};
672 Double_t radiusBins[nRadiusBinsHisto] = {0.,30.,40.,60.,80.,100.,140.,230};
674 massVradiusBins[binFill] = func->GetParameter(1);
675 massVradiusErrorBins[binFill] = func->GetParError(1);
676 widthVradiusBins[binFill] = func->GetParameter(2);
677 widthVradiusErrorBins[binFill] = func->GetParError(2);
680 const Double_t* radiusBinsFinal = radiusBins;
681 const Double_t* massVradiusBinsFinal = massVradiusBins;
682 const Double_t* massVradiusErrorBinsFinal = massVradiusErrorBins;
683 const Double_t* widthVradiusBinsFinal = widthVradiusBins;
684 const Double_t* widthVradiusErrorBinsFinal = widthVradiusErrorBins;
699 Double_t
etaBins[11] = {-2.5,-2.0,-1.5,-1.0,-0.5,0.0,0.5,1.0,1.5,2.0,2.5};
700 Double_t massVetaBins[10], massVetaErrorBins[10], widthVetaBins[10], widthVetaErrorBins[10];
701 for(
int binFill=0;binFill<10;binFill++) {
702 massVetaBins[binFill] = func->GetParameter(1);
703 massVetaErrorBins[binFill] = func->GetParError(1);
704 widthVetaBins[binFill] = func->GetParameter(2);
705 widthVetaErrorBins[binFill] = func->GetParError(2);
717 Double_t phiBins[11]{};
718 sequentialFill(phiBins, phiBins+11, -
M_PI,
M_PI/5.);
719 Double_t massVphiBins[10], massVphiErrorBins[10], widthVphiBins[10], widthVphiErrorBins[10];
720 for(
int binFill=0;binFill<10;binFill++) {
721 massVphiBins[binFill] = func->GetParameter(1);
722 massVphiErrorBins[binFill] = func->GetParError(1);
723 widthVphiBins[binFill] = func->GetParameter(2);
724 widthVphiErrorBins[binFill] = func->GetParError(2);
736 Double_t curvatureDiffBins[7] = {-0.0012,-0.0008,-0.0004,0.0000,0.0004,0.0008,0.0012};
737 Double_t massVcurvatureDiffBins[6], massVcurvatureDiffErrorBins[6], widthVcurvatureDiffBins[6], widthVcurvatureDiffErrorBins[6];
738 for(
int binFill=0;binFill<6;binFill++) {
739 massVcurvatureDiffBins[binFill] = func->GetParameter(1);
740 massVcurvatureDiffErrorBins[binFill] = func->GetParError(1);
741 widthVcurvatureDiffBins[binFill] = func->GetParameter(2);
742 widthVcurvatureDiffErrorBins[binFill] = func->GetParError(2);
756 return StatusCode::SUCCESS;