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"
49 template <
typename ForwardIterator,
typename T>
51 sequentialFill(ForwardIterator
beg,
const ForwardIterator
stop,
T value,
const T inc){
60 template <
typename Iterator,
typename T,
typename Compare=std::less<T>>
62 findLevel(
const Iterator
beg,
const Iterator
stop,
T value, Compare op=std::less<T>()){
70 return (
v >= lo) and (
v<=hi);
83 m_triggerChainName(
"NoTriggerSelection")
104 return StatusCode::SUCCESS;
138 Double_t phiBins[10]{};
140 Double_t curvatureDiffBins[6]{};
143 sequentialFill(curvatureDiffBins,
std::end(curvatureDiffBins), -0.001,0.0004);
144 m_mass =
new TH1F(
"ks_mass",
"Invariant mass of K^{0}_{S} candidate", 60, 0.45, 0.55);
145 m_mass->SetYTitle(
"K^{0}_{S} Candidates");
146 m_mass->SetXTitle(
"Mass (Gev / c^{2})");
147 m_mass->SetMarkerStyle(20);
150 m_mass_scaled =
new TH1F(
"ks_mass_scaled",
"Invariant mass of K^{0}_{S} candidate scaled to per event", 60, 0.45, 0.55);
157 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);
159 m_massVsPhi->SetYTitle(
"Mass (Gev / c^{2}) - World Average [MeV]");
162 m_pt =
new TH1F(
"ks_pt",
"p_{T} of K^{0}_{S} candidate", 100, 0., 10.);
163 m_pt->SetYTitle(
"K^{0}_{S} Candidates");
164 m_pt->SetXTitle(
"p_{T} (Gev / c)");
165 m_pt->SetMarkerStyle(20);
168 m_radiusVsZ_secVertex =
new TH2F(
"secVertex_radiusVsZ",
"all sec.vertices (reco);z [mm];Decay radius [mm]",180, -600., 600.,180.,0.,180.);
171 m_YVsX_secVertex =
new TH2F(
"secVertex_YVsX",
"all sec. vertices (reco);x [mm];y [mm]",200, -150.,150., 200, -150., 150.);
174 m_radiusVsZ_secVertex_sel =
new TH2F(
"secVertex_radiusVsZ_sel",
"all sec.vertices (reco);z [mm];Decay radius [mm]",180, -600., 600.,180.,0.,180.);
177 m_YVsX_secVertex_sel =
new TH2F(
"secVertex_YVsX_sel",
"all sec. vertices (reco);x [mm];y [mm]",200, -150.,150., 200, -150., 150.);
180 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.);
183 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.);
192 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);
195 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);
198 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);
201 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);
204 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);
207 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);
210 m_radius =
new TH1F(
"ks_radius",
"Decay radius of K^{0}_{S} candidate", 100, 0., 300.);
211 m_radius->SetYTitle(
"K^{0}_{S} Candidates");
212 m_radius->SetXTitle(
"Decay Radius (mm)");
217 m_eta =
new TH1F(
"ks_eta",
"#eta of K^{0}_{S} candidate", 10, -2.5, 2.5);
218 m_eta->SetYTitle(
"K^{0}_{S} Candidates");
219 m_eta->SetXTitle(
"#eta");
220 m_eta->SetMarkerStyle(20);
222 m_phi =
new TH1F(
"ks_phi",
"#phi of K^{0}_{S} candidate", 10, (-1.0*
M_PI),
M_PI);
223 m_phi->SetYTitle(
"K^{0}_{S} Candidates");
224 m_phi->SetXTitle(
"#phi");
225 m_phi->SetMarkerStyle(20);
229 auto quickSet=[](
TH1F *
h){
230 h->SetXTitle(
"Mass (Gev / c^{2})");
231 h->SetYTitle(
"K^{0}_{S} Candidates");
232 h->SetMarkerStyle(20);
236 for(
int quickInit=0;quickInit<
m_nBinsPt;quickInit++) {
237 TString tempName =
"MassVptBin";
238 TString tempTitle =
"Mass, p_{T} = ";
239 tempName += quickInit;
240 tempTitle += ((Double_t)((quickInit*100)+500))/1000;
248 TString tempName =
"MassVptBinFitted";
249 TString tempTitle =
"Fitted Mass, p_{T} = ";
250 tempName += quickInit;
251 tempTitle += ptBins[quickInit];
258 TString tempName =
"MassVradiusBin";
259 TString tempTitle =
"Mass, Decay Radius = ";
260 tempName += quickInit;
261 tempTitle += quickInit*10;
268 TString tempName =
"MassVradiusBinFitted";
269 TString tempTitle =
"Fitted Mass, Decay Radius = ";
270 tempName += quickInit;
271 tempTitle += radiusBins[quickInit];
277 for(
int quickInit=0;quickInit<10;quickInit++) {
278 TString tempName =
"MassVEtaBin";
279 TString tempTitle =
"Mass, #eta = ";
280 tempName += quickInit;
281 tempTitle +=
etaBins[quickInit];
286 tempName =
"MassVPhiBin";
287 tempTitle =
"Mass, #phi = ";
288 tempName += quickInit;
289 tempTitle += ((Double_t)((Int_t)(phiBins[quickInit]*100)))/100;
295 for(
int quickInit=0;quickInit<6;quickInit++) {
296 TString tempName =
"MassVCurvatureDiffBin";
297 TString tempTitle =
"Mass, CurvatureDiff = ";
298 tempName += quickInit;
299 tempTitle += curvatureDiffBins[quickInit];
327 m_Nevents =
new TH1F(
"Nevents",
"Number of events processed",1,-.5,.5);
338 return StatusCode::SUCCESS;
345 if (
sc.isFailure() ) {
353 if (
sc.isFailure() ) {
361 if (
sc.isFailure() ) {
372 if (
sc.isFailure()) {
374 return StatusCode::SUCCESS;
383 return StatusCode::FAILURE;
390 return StatusCode::SUCCESS;
398 return StatusCode::FAILURE;
405 return StatusCode::SUCCESS;
412 ATH_MSG_DEBUG(
"@todo >> V0UnconstrVerices container size >> " << SecVxContainer->
size());
414 std::array<float, 5> curvatureBinning{};
415 sequentialFill(curvatureBinning.begin(), curvatureBinning.end(),-0.0008, 0.0004);
417 std::array<double,10> ksPhiBinning{};
418 sequentialFill(ksPhiBinning.begin(), ksPhiBinning.end(), -
M_PI,
M_PI * 0.2);
420 std::array<double,10> ksEtaBinning{};
421 sequentialFill(ksEtaBinning.begin(), ksEtaBinning.end(),-2.5, 0.5);
423 std::array<double,4> ksPtBinning{1600,2100, 2800,3900};
425 std::array<double,6> radiusBinning{30,40, 60,80,100,140};
427 for (
const auto* secVx_elem : *SecVxContainer) {
434 double ksMass = Kshort_massAcc(*secVx_elem);
435 double ksPt = pTAcc(*secVx_elem);
436 double ksPx = pxAcc(*secVx_elem);
437 double ksPy = pyAcc(*secVx_elem);
438 double ksPz = pzAcc(*secVx_elem);
439 ATH_MSG_DEBUG(
" mass : "<<ksMass <<
" pt : "<< ksPt <<
" px : "<< ksPx <<
" py : "<< ksPy <<
" pz : "<< ksPz);
440 CLHEP::Hep3Vector ksMomentumVector = CLHEP::Hep3Vector(ksPx,ksPy,ksPz);
441 double ksMomentum = ksMomentumVector.mag();
442 double transverseFlightDistance, totalFlightDistance;
444 const auto & secVxPosition(secVx_elem->position());
448 const auto & position (primaryVertex->
position());
453 auto vert = secVx_elem->position()-primaryVertex->
position();
454 double dx = vert.x();
455 double dy = vert.y();
458 transverseFlightDistance =dxy;
462 ATH_MSG_DEBUG(
"dx : "<<
dx<<
" dy: "<<
dy<<
" dxy: "<<dxy<<
"flight distance (total): "<<totalFlightDistance);
465 transverseFlightDistance = secVxPosition.perp();
467 totalFlightDistance =
vertex.mag();
473 double flightX = flightVector.x();
474 double flightY = flightVector.y();
475 double cosThetaPointing = (ksPx*flightX+ksPy*flightY)/std::sqrt(ksPx*ksPx+ksPy*ksPy)/std::sqrt(flightX*flightX+flightY*flightY);
476 int trackPos_nSVTHits = 0;
477 int trackNeg_nSVTHits = 0;
478 double trackPos_d0 = 0;
479 double trackPos_d0_wrtPV = 0;
480 double trackNeg_d0 = 0;
481 double trackNeg_d0_wrtPV = 0;
486 ntrk = secVx_elem->nTrackParticles();
487 ATH_MSG_DEBUG(
"track particles associated to vertex : "<<ntrk );
489 auto tpLinks = secVx_elem->trackParticleLinks();
490 for (
const auto& link: tpLinks){
491 Info(
"execute()",
"V0: TP link = %d %s ", link.isValid(), link.dataID().c_str() );
494 if( (*link)->charge() > 0. ) {
498 else if( (*link)->charge() < 0. ){
504 if(trackPos!=
nullptr) {
507 trackPos_d0 = trackPos->
d0();
513 if(trackNeg!=
nullptr) {
516 trackNeg_d0 = trackNeg->
d0();
519 int selectorValue = 0;
520 ATH_MSG_DEBUG(
"ksTau = " << properDecayTime <<
" Lxy = " <<transverseFlightDistance<<
" cosTheta = " << cosThetaPointing );
521 ATH_MSG_DEBUG(
"trackPos nSVThits = " << trackPos_nSVTHits <<
" trackNeg nSVThits = " << trackNeg_nSVTHits );
524 double secVertex_radius = RxyAcc(*secVx_elem);
525 ATH_MSG_DEBUG(
"secondary vertex radius : " << secVertex_radius);
530 ATH_MSG_DEBUG(
"trackneg d0 : " << trackNeg_d0 <<
" trackpos d0 : "<< trackPos_d0);
531 ATH_MSG_DEBUG(
"trackneg d0 (PV): " << trackNeg_d0_wrtPV <<
" trackpos d0 (PV) : "<< trackPos_d0_wrtPV);
532 if(secVx_elem->chiSquared()/secVx_elem->numberDoF() < 4.5
534 && abs(trackNeg_d0_wrtPV) > 5.
535 && abs(trackPos_d0_wrtPV) > 5.
536 && trackPos_nSVTHits > 2
537 && trackNeg_nSVTHits > 2
538 && secVertex_radius > 20.
548 && properDecayTime > 0.004
549 && transverseFlightDistance > 12.
550 && cosThetaPointing > 0.998
551 && ksMass>400.&&ksMass<600.
552 && trackPos_nSVTHits > 2 && trackNeg_nSVTHits > 2
554 if(selectorValue != 1)
continue;
560 m_mass->Fill(ksMass*0.001);
561 double ksEta = ksMomentumVector.pseudoRapidity();
562 double ksPhi = ksMomentumVector.phi();
563 double piPlusPt = trackPos->
p4().Perp();
564 double piMinusPt = trackNeg->
p4().Perp();
566 m_pt->Fill(ksPt*0.001);
569 Float_t curvatureDiff = (1./(piPlusPt)) - (1./(piMinusPt));
570 const auto fillValue(ksMass*0.001);
571 auto curvatureIdx = findLevel(curvatureBinning.begin(), curvatureBinning.end(),curvatureDiff);
574 auto ksPhiIdx = findLevel(ksPhiBinning.begin(), ksPhiBinning.end(), ksPhi, std::less_equal<double>());
577 if (ksEta>=-2.5 and ksEta<2.5){
578 auto ksEtaIdx = findLevel(ksEtaBinning.begin(), ksEtaBinning.end(), ksEta, std::less_equal<double>());
582 auto ksPtIdx = findLevel(ksPtBinning.begin(), ksPtBinning.end(), ksPt, std::less_equal<double>());
586 if (ksPt<500) ksPt = 500;
587 if (ksPt>5000) ksPt=5000;
588 Int_t quickBin = (Int_t)ksPt;
589 quickBin -= quickBin%100;
593 double radius = RxyAcc(*secVx_elem);
596 auto radiusIdx = findLevel(radiusBinning.begin(), radiusBinning.end(),
radius, std::less_equal<double>());
600 Int_t radiusTemp = (Int_t)
radius;
601 radiusTemp -= radiusTemp%10;
604 return StatusCode::SUCCESS;
615 TF1 *func =
new TF1(
"func",
"gaus(0)+expo(3)",0.450,0.550);
616 func->SetLineColor(4);
617 func->SetParameters(10.,0.500,0.010,2.,-.001);
618 func->SetParLimits(0,0.,10000.);
619 func->SetParLimits(1,0.450,0.550);
620 func->SetParLimits(2,0.,0.100);
621 func->SetParLimits(3,0.,10000.);
622 func->SetParLimits(4,-1000.,0.);
623 func->SetParNames(
"Constant",
"Mean",
"Width",
"Constant",
"Slope");
626 Double_t ptBins[nPtBinsHisto] = {0.5,1.6,2.1,2.8,3.9,5.1};
628 massBins[binFill] = func->GetParameter(1);
629 massErrorBins[binFill] = func->GetParError(1);
630 widthBins[binFill] = func->GetParameter(2);
631 widthErrorBins[binFill] = func->GetParError(2);
633 const Double_t* ptBinsFinal = ptBins;
634 const Double_t* massBinsFinal = massBins;
635 const Double_t* massErrorBinsFinal = massErrorBins;
636 const Double_t* widthBinsFinal = widthBins;
637 const Double_t* widthErrorBinsFinal = widthErrorBins;
639 auto setYTitleAndMarker =[](
TH1F * theHist,
const bool mass){
641 theHist->SetYTitle(
"Mass (Gev / c^{2})");
643 theHist->SetYTitle(
"Width (Gev / c^{2})");
645 theHist->SetMarkerStyle(20);
648 auto fillFromSource = [](
const double *
source,
const double * uncertainty,
TH1F *
target,
unsigned int nbins){
651 double binError = uncertainty[
bin];
652 target->SetBinContent(
bin+1, binContent);
656 constexpr
bool massTitle{
true};
657 constexpr
bool widthTitle{
false};
673 Double_t radiusBins[nRadiusBinsHisto] = {0.,30.,40.,60.,80.,100.,140.,230};
675 massVradiusBins[binFill] = func->GetParameter(1);
676 massVradiusErrorBins[binFill] = func->GetParError(1);
677 widthVradiusBins[binFill] = func->GetParameter(2);
678 widthVradiusErrorBins[binFill] = func->GetParError(2);
681 const Double_t* radiusBinsFinal = radiusBins;
682 const Double_t* massVradiusBinsFinal = massVradiusBins;
683 const Double_t* massVradiusErrorBinsFinal = massVradiusErrorBins;
684 const Double_t* widthVradiusBinsFinal = widthVradiusBins;
685 const Double_t* widthVradiusErrorBinsFinal = widthVradiusErrorBins;
700 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};
701 Double_t massVetaBins[10], massVetaErrorBins[10], widthVetaBins[10], widthVetaErrorBins[10];
702 for(
int binFill=0;binFill<10;binFill++) {
703 massVetaBins[binFill] = func->GetParameter(1);
704 massVetaErrorBins[binFill] = func->GetParError(1);
705 widthVetaBins[binFill] = func->GetParameter(2);
706 widthVetaErrorBins[binFill] = func->GetParError(2);
718 Double_t phiBins[11]{};
719 sequentialFill(phiBins, phiBins+11, -
M_PI,
M_PI/5.);
720 Double_t massVphiBins[10], massVphiErrorBins[10], widthVphiBins[10], widthVphiErrorBins[10];
721 for(
int binFill=0;binFill<10;binFill++) {
722 massVphiBins[binFill] = func->GetParameter(1);
723 massVphiErrorBins[binFill] = func->GetParError(1);
724 widthVphiBins[binFill] = func->GetParameter(2);
725 widthVphiErrorBins[binFill] = func->GetParError(2);
737 Double_t curvatureDiffBins[7] = {-0.0012,-0.0008,-0.0004,0.0000,0.0004,0.0008,0.0012};
738 Double_t massVcurvatureDiffBins[6], massVcurvatureDiffErrorBins[6], widthVcurvatureDiffBins[6], widthVcurvatureDiffErrorBins[6];
739 for(
int binFill=0;binFill<6;binFill++) {
740 massVcurvatureDiffBins[binFill] = func->GetParameter(1);
741 massVcurvatureDiffErrorBins[binFill] = func->GetParError(1);
742 widthVcurvatureDiffBins[binFill] = func->GetParameter(2);
743 widthVcurvatureDiffErrorBins[binFill] = func->GetParError(2);
757 return StatusCode::SUCCESS;