File indexing completed on 2025-08-06 08:18:19
0001 #include "KshortReconstruction.h"
0002
0003 #include <ffaobjects/EventHeader.h>
0004
0005 #include <trackbase/TrkrDefs.h>
0006 #include <trackbase/ActsGeometry.h>
0007
0008 #include <trackbase_historic/ActsTransformations.h>
0009 #include <trackbase_historic/SvtxTrackMap_v2.h>
0010
0011 #include <trackreco/ActsPropagator.h>
0012
0013 #include <globalvertex/SvtxVertexMap.h>
0014
0015 #include <fun4all/Fun4AllReturnCodes.h>
0016
0017 #include <phool/PHCompositeNode.h>
0018 #include <phool/getClass.h>
0019
0020 #include <Acts/Surfaces/CylinderSurface.hpp>
0021
0022 #pragma GCC diagnostic push
0023 #pragma GCC diagnostic ignored "-Wshadow"
0024 #include <ActsExamples/EventData/Trajectories.hpp>
0025 #pragma GCC diagnostic pop
0026
0027 #include <TFile.h>
0028 #include <TH1.h>
0029 #include <TLorentzVector.h>
0030 #include <TNtuple.h>
0031 #include <TSystem.h>
0032
0033 #include <cmath>
0034 #include <utility>
0035
0036 using BoundTrackParam = const Acts::BoundTrackParameters;
0037 using BoundTrackParamResult = Acts::Result<BoundTrackParam>;
0038 using SurfacePtr = std::shared_ptr<const Acts::Surface>;
0039 using Trajectory = ActsExamples::Trajectories;
0040
0041
0042 int KshortReconstruction::process_event(PHCompositeNode* topNode)
0043 {
0044
0045 EventHeader* evtHeader = findNode::getClass<EventHeader>(topNode, "EventHeader");
0046
0047 int m_runNumber;
0048 int m_evtNumber;
0049 if (evtHeader)
0050 {
0051 m_runNumber = evtHeader->get_RunNumber();
0052 m_evtNumber = evtHeader->get_EvtSequence();
0053 }
0054 else
0055 {
0056 m_runNumber = m_evtNumber = -1;
0057 }
0058
0059
0060 for (auto tr1_it = m_svtxTrackMap->begin(); tr1_it != m_svtxTrackMap->end(); ++tr1_it)
0061 {
0062 auto id1 = tr1_it->first;
0063 auto *tr1 = tr1_it->second;
0064 if (tr1->get_quality() > _qual_cut)
0065 {
0066 continue;
0067 }
0068 if (tr1->get_pt() < track_pt_cut)
0069 {
0070 continue;
0071 }
0072
0073 short int crossing1 = tr1->get_crossing();
0074
0075
0076 double this_dca_cut = track_dca_cut;
0077 TrackSeed* siliconseed = tr1->get_silicon_seed();
0078
0079 if (!siliconseed)
0080 {
0081 this_dca_cut *= 5;
0082 if (Verbosity() > 2)
0083 {
0084 std::cout << "silicon seed not found" << std::endl;
0085 }
0086 if (_require_mvtx)
0087 {
0088 continue;
0089 }
0090 }
0091
0092 std::vector<unsigned int> nstates1 = getTrackStates(tr1);
0093 unsigned int track1_mvtx_state_size = nstates1[0];
0094 unsigned int track1_intt_state_size = nstates1[1];
0095
0096
0097
0098 unsigned int track1_silicon_cluster_size = std::numeric_limits<unsigned int>::quiet_NaN();
0099 if (siliconseed)
0100 {
0101 track1_silicon_cluster_size = siliconseed->size_cluster_keys();
0102 }
0103
0104 std::vector<TrkrDefs::cluskey> ckeys1;
0105 if (siliconseed)
0106 {
0107 ckeys1.insert(ckeys1.end(), siliconseed->begin_cluster_keys(), siliconseed->end_cluster_keys());
0108 }
0109
0110 unsigned int track1_mvtx_cluster_size = 0;
0111 unsigned int track1_intt_cluster_size = 0;
0112 for (const auto& ckey : ckeys1)
0113 {
0114 auto detid = TrkrDefs::getTrkrId(ckey);
0115 if (detid == TrkrDefs::TrkrId::mvtxId)
0116 {
0117 track1_mvtx_cluster_size++;
0118 }
0119 else if (detid == TrkrDefs::TrkrId::inttId)
0120 {
0121 track1_intt_cluster_size++;
0122 }
0123 }
0124
0125 Acts::Vector3 pos1(tr1->get_x(), tr1->get_y(), tr1->get_z());
0126 Acts::Vector3 mom1(tr1->get_px(), tr1->get_py(), tr1->get_pz());
0127 Acts::Vector3 dcaVals1 = calculateDca(tr1, mom1, pos1);
0128
0129 if (fabs(dcaVals1(0)) < this_dca_cut or fabs(dcaVals1(1)) < this_dca_cut)
0130 {
0131 continue;
0132 }
0133
0134
0135 for (auto tr2_it = std::next(tr1_it); tr2_it != m_svtxTrackMap->end(); ++tr2_it)
0136 {
0137 auto id2 = tr2_it->first;
0138 auto *tr2 = tr2_it->second;
0139 if (tr2->get_quality() > _qual_cut)
0140 {
0141 continue;
0142 }
0143 if (tr2->get_pt() < track_pt_cut)
0144 {
0145 continue;
0146 }
0147
0148 short int crossing2 = tr2->get_crossing();
0149
0150
0151 TrackSeed* siliconseed2 = tr2->get_silicon_seed();
0152
0153 double this_dca_cut2 = track_dca_cut;
0154
0155 if (!siliconseed2)
0156 {
0157 this_dca_cut2 *= 5;
0158 if (Verbosity() > 2)
0159 {
0160 std::cout << "silicon seed not found" << std::endl;
0161 }
0162 if (_require_mvtx)
0163 {
0164 continue;
0165 }
0166 }
0167
0168 std::vector<unsigned int> nstates2 = getTrackStates(tr2);
0169 unsigned int track2_mvtx_state_size = nstates2[0];
0170 unsigned int track2_intt_state_size = nstates2[1];
0171
0172
0173
0174 unsigned int track2_silicon_cluster_size = std::numeric_limits<unsigned int>::quiet_NaN();
0175 if (siliconseed2)
0176 {
0177 track2_silicon_cluster_size = siliconseed2->size_cluster_keys();
0178 }
0179
0180 std::vector<TrkrDefs::cluskey> ckeys2;
0181 if (siliconseed2)
0182 {
0183 ckeys2.insert(ckeys2.end(), siliconseed2->begin_cluster_keys(), siliconseed2->end_cluster_keys());
0184 }
0185
0186 unsigned int track2_mvtx_cluster_size = 0;
0187 unsigned int track2_intt_cluster_size = 0;
0188 for (const auto& ckey : ckeys2)
0189 {
0190 auto detid = TrkrDefs::getTrkrId(ckey);
0191 if (detid == TrkrDefs::TrkrId::mvtxId)
0192 {
0193 track2_mvtx_cluster_size++;
0194 }
0195 else if (detid == TrkrDefs::TrkrId::inttId)
0196 {
0197 track2_intt_cluster_size++;
0198 }
0199 }
0200
0201
0202 Acts::Vector3 pos2(tr2->get_x(), tr2->get_y(), tr2->get_z());
0203 Acts::Vector3 mom2(tr2->get_px(), tr2->get_py(), tr2->get_pz());
0204 Acts::Vector3 dcaVals2 = calculateDca(tr2, mom2, pos2);
0205
0206 if (fabs(dcaVals2(0)) < this_dca_cut2 or fabs(dcaVals2(1)) < this_dca_cut2)
0207 {
0208 continue;
0209 }
0210
0211
0212 if (Verbosity() > 3)
0213 {
0214 std::cout << "Check DCA for tracks " << id1 << " and " << id2 << std::endl;
0215 }
0216
0217 if (tr1->get_charge() == tr2->get_charge())
0218 {
0219
0220 }
0221
0222
0223 double pair_dca;
0224 Acts::Vector3 pca_rel1;
0225 Acts::Vector3 pca_rel2;
0226 double invariantMass;
0227 double invariantPt;
0228 float invariantPhi;
0229 float rapidity;
0230 float pseudorapidity;
0231
0232
0233
0234
0235 findPcaTwoTracks(pos1, pos2, mom1, mom2, pca_rel1, pca_rel2, pair_dca);
0236
0237
0238 if (abs(pair_dca) < pair_dca_cut)
0239 {
0240
0241
0242 Eigen::Vector3d projected_pos1;
0243 Eigen::Vector3d projected_mom1;
0244 Eigen::Vector3d projected_pos2;
0245 Eigen::Vector3d projected_mom2;
0246
0247 bool ret1 = projectTrackToPoint(tr1, pca_rel1, projected_pos1, projected_mom1);
0248 bool ret2 = projectTrackToPoint(tr2, pca_rel2, projected_pos2, projected_mom2);
0249
0250 if (!ret1 or !ret2)
0251 {
0252 continue;
0253 }
0254
0255
0256 double pair_dca_proj;
0257 Acts::Vector3 pca_rel1_proj;
0258 Acts::Vector3 pca_rel2_proj;
0259 findPcaTwoTracks(projected_pos1, projected_pos2, projected_mom1, projected_mom2, pca_rel1_proj, pca_rel2_proj, pair_dca_proj);
0260
0261
0262
0263
0264 fillHistogram(projected_mom1, projected_mom2, recomass, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity);
0265 fillNtp(tr1, tr2, dcaVals1, dcaVals2, pca_rel1, pca_rel2, pair_dca, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity, projected_pos1, projected_pos2, projected_mom1, projected_mom2, pca_rel1_proj, pca_rel2_proj, pair_dca_proj, track1_silicon_cluster_size, track2_silicon_cluster_size, track1_mvtx_cluster_size, track1_mvtx_state_size, track1_intt_cluster_size, track1_intt_state_size, track2_mvtx_cluster_size, track2_mvtx_state_size, track2_intt_cluster_size, track2_intt_state_size, m_runNumber, m_evtNumber);
0266
0267 if (Verbosity() > 1)
0268 {
0269 std::cout << " Accepted Track Pair" << std::endl;
0270 std::cout << " id1 " << id1 << " id2 " << id2 << std::endl;
0271 std::cout << " crossing1 " << crossing1 << " crossing2 " << crossing2 << std::endl;
0272 std::cout << " invariant mass: " << invariantMass << std::endl;
0273 std::cout << " track1 dca_cut: " << this_dca_cut << " track2 dca_cut: " << this_dca_cut2 << std::endl;
0274 std::cout << " dca3dxy1,dca3dz1,phi1: " << dcaVals1 << std::endl;
0275 std::cout << " dca3dxy2,dca3dz2,phi2: " << dcaVals2 << std::endl;
0276 std::cout << "Initial: pca_rel1: " << pca_rel1 << " pca_rel2: " << pca_rel2 << std::endl;
0277 std::cout << " Initial: mom1: " << mom1 << " mom2: " << mom2 << std::endl;
0278 std::cout << "Proj_pca_rel: proj_pos1: " << projected_pos1 << " proj_pos2: " << projected_pos2 << " proj_mom1: " << projected_mom1 << " proj_mom2: " << projected_mom2 << std::endl;
0279 std::cout << " Relative PCA = " << abs(pair_dca) << " pca_cut = " << pair_dca_cut << std::endl;
0280 std::cout << " charge 1: " << tr1->get_charge() << " charge2: " << tr2->get_charge() << std::endl;
0281 std::cout << "found viable projection" << std::endl;
0282 std::cout << "Final: pca_rel1_proj: " << pca_rel1_proj << " pca_rel2_proj: " << pca_rel2_proj << " mom1: " << projected_mom1 << " mom2: " << projected_mom2 << std::endl
0283 << std::endl;
0284 }
0285
0286 if (m_save_tracks)
0287 {
0288 m_output_trackMap = findNode::getClass<SvtxTrackMap>(topNode, m_output_trackMap_node_name);
0289 m_output_trackMap->insertWithKey(tr1, tr1->get_id());
0290 m_output_trackMap->insertWithKey(tr2, tr2->get_id());
0291 }
0292
0293 }
0294 }
0295 }
0296 return 0;
0297 }
0298
0299 std::vector<unsigned int> KshortReconstruction::getTrackStates(SvtxTrack *track)
0300 {
0301 std::vector<unsigned int> nstates;
0302 unsigned int nmapsstate = 0;
0303 unsigned int ninttstate = 0;
0304 unsigned int ntpcstate = 0;
0305 unsigned int nmmsstate = 0;
0306
0307
0308 for (auto state_iter = track->begin_states();
0309 state_iter != track->end_states();
0310 ++state_iter)
0311 {
0312 SvtxTrackState* tstate = state_iter->second;
0313 auto stateckey = tstate->get_cluskey();
0314
0315 switch (TrkrDefs::getTrkrId(stateckey))
0316 {
0317 case TrkrDefs::mvtxId:
0318 nmapsstate++;
0319 break;
0320 case TrkrDefs::inttId:
0321 ninttstate++;
0322 break;
0323 case TrkrDefs::tpcId:
0324 ntpcstate++;
0325 break;
0326 case TrkrDefs::micromegasId:
0327 nmmsstate++;
0328 break;
0329 default:
0330 std::cout << PHWHERE << " unknown key " << stateckey << std::endl;
0331 gSystem->Exit(1);
0332 exit(1);
0333 }
0334 }
0335 nstates.push_back(nmapsstate);
0336 nstates.push_back(ninttstate);
0337 nstates.push_back(ntpcstate);
0338 nstates.push_back(nmmsstate);
0339
0340 return nstates;
0341 }
0342
0343 void KshortReconstruction::fillNtp(SvtxTrack* track1, SvtxTrack* track2, Acts::Vector3 dcavals1, Acts::Vector3 dcavals2, Acts::Vector3 pca_rel1, Acts::Vector3 pca_rel2, double pair_dca, double invariantMass, double invariantPt, float invariantPhi, float rapidity, float pseudorapidity, Eigen::Vector3d projected_pos1, Eigen::Vector3d projected_pos2, Eigen::Vector3d projected_mom1, Eigen::Vector3d projected_mom2, Acts::Vector3 pca_rel1_proj, Acts::Vector3 pca_rel2_proj, double pair_dca_proj, unsigned int track1_silicon_cluster_size, unsigned int track2_silicon_cluster_size, unsigned int track1_mvtx_cluster_size, unsigned int track1_mvtx_state_size, unsigned int track1_intt_cluster_size, unsigned int track1_intt_state_size, unsigned int track2_mvtx_cluster_size, unsigned int track2_mvtx_state_size, unsigned int track2_intt_cluster_size, unsigned int track2_intt_state_size, int runNumber, int eventNumber)
0344 {
0345 double px1 = track1->get_px();
0346 double py1 = track1->get_py();
0347 double pz1 = track1->get_pz();
0348 auto *tpcSeed1 = track1->get_tpc_seed();
0349 size_t tpcClusters1 = tpcSeed1->size_cluster_keys();
0350 double eta1 = asinh(pz1 / sqrt(pow(px1, 2) + pow(py1, 2)));
0351
0352 double px2 = track2->get_px();
0353 double py2 = track2->get_py();
0354 double pz2 = track2->get_pz();
0355 auto *tpcSeed2 = track2->get_tpc_seed();
0356 size_t tpcClusters2 = tpcSeed2->size_cluster_keys();
0357 double eta2 = asinh(pz2 / sqrt(pow(px2, 2) + pow(py2, 2)));
0358
0359 auto vtxid = track1->get_vertex_id();
0360
0361 Acts::Vector3 vertex(0, 0, track1->get_z());
0362 auto *svtxVertex = m_vertexMap->get(vtxid);
0363 if (svtxVertex)
0364 {
0365 vertex(0) = svtxVertex->get_x();
0366 vertex(1) = svtxVertex->get_y();
0367 vertex(2) = svtxVertex->get_z();
0368 }
0369
0370 Acts::Vector3 pathLength = (pca_rel1 + pca_rel2) * 0.5 - vertex;
0371 Acts::Vector3 pathLength_proj = (pca_rel1_proj + pca_rel2_proj) * 0.5 - vertex;
0372
0373 float mag_pathLength = sqrt(pow(pathLength(0), 2) + pow(pathLength(1), 2) + pow(pathLength(2), 2));
0374 float mag_pathLength_proj = sqrt(pow(pathLength_proj(0), 2) + pow(pathLength_proj(1), 2) + pow(pathLength_proj(2), 2));
0375
0376 Acts::Vector3 projected_momentum = projected_mom1 + projected_mom2;
0377 float cos_theta_reco = pathLength_proj.dot(projected_momentum) / (projected_momentum.norm() * pathLength_proj.norm());
0378
0379
0380 float reco_info[] = {(float) track1->get_id(), (float) track1->get_crossing(), track1->get_x(), track1->get_y(), track1->get_z(), track1->get_px(), track1->get_py(), track1->get_pz(), (float) dcavals1(0), (float) dcavals1(1), (float) dcavals1(2), (float) pca_rel1(0), (float) pca_rel1(1), (float) pca_rel1(2), (float) eta1, (float) track1->get_charge(), (float) tpcClusters1, (float) track2->get_id(), (float) track2->get_crossing(), track2->get_x(), track2->get_y(), track2->get_z(), track2->get_px(), track2->get_py(), track2->get_pz(), (float) dcavals2(0), (float) dcavals2(1), (float) dcavals2(2), (float) pca_rel2(0), (float) pca_rel2(1), (float) pca_rel2(2), (float) eta2, (float) track2->get_charge(), (float) tpcClusters2, (float) vertex(0), (float) vertex(1), (float) vertex(2), (float) pair_dca, (float) invariantMass, (float) invariantPt, invariantPhi, (float) pathLength(0), (float) pathLength(1), (float) pathLength(2), mag_pathLength, rapidity, pseudorapidity, (float) projected_pos1(0), (float) projected_pos1(1), (float) projected_pos1(2), (float) projected_pos2(0), (float) projected_pos2(1), (float) projected_pos2(2), (float) projected_mom1(0), (float) projected_mom1(1), (float) projected_mom1(2), (float) projected_mom2(0), (float) projected_mom2(1), (float) projected_mom2(2), (float) pca_rel1_proj(0), (float) pca_rel1_proj(1), (float) pca_rel1_proj(2), (float) pca_rel2_proj(0), (float) pca_rel2_proj(1), (float) pca_rel2_proj(2), (float) pair_dca_proj, (float) pathLength_proj(0), (float) pathLength_proj(1), (float) pathLength_proj(2), mag_pathLength_proj, track1->get_quality(), track2->get_quality(), cos_theta_reco, (float) track1_silicon_cluster_size, (float) track2_silicon_cluster_size, (float) track1_mvtx_cluster_size, (float) track1_mvtx_state_size, (float) track1_intt_cluster_size, (float) track1_intt_state_size, (float) track2_mvtx_cluster_size, (float) track2_mvtx_state_size, (float) track2_intt_cluster_size, (float) track2_intt_state_size, (float) runNumber, (float) eventNumber};
0381
0382 ntp_reco_info->Fill(reco_info);
0383 }
0384
0385 void KshortReconstruction::fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity)
0386 {
0387 double E1 = sqrt(pow(mom1(0), 2) + pow(mom1(1), 2) + pow(mom1(2), 2) + pow(decaymass, 2));
0388 double E2 = sqrt(pow(mom2(0), 2) + pow(mom2(1), 2) + pow(mom2(2), 2) + pow(decaymass, 2));
0389
0390 TLorentzVector v1(mom1(0), mom1(1), mom1(2), E1);
0391 TLorentzVector v2(mom2(0), mom2(1), mom2(2), E2);
0392
0393 TLorentzVector tsum;
0394 tsum = v1 + v2;
0395
0396 rapidity = tsum.Rapidity();
0397 pseudorapidity = tsum.Eta();
0398 invariantMass = tsum.M();
0399 invariantPt = tsum.Pt();
0400 invariantPhi = tsum.Phi();
0401
0402 if (Verbosity() > 2)
0403 {
0404 std::cout << "px1: " << mom1(0) << " py1: " << mom1(1) << " pz1: " << mom1(2) << " E1: " << E1 << std::endl;
0405 std::cout << "px2: " << mom2(0) << " py2: " << mom2(1) << " pz2: " << mom2(2) << " E2: " << E2 << std::endl;
0406 std::cout << "tsum: " << tsum(0) << " " << tsum(1) << " " << tsum(2) << " " << tsum(3) << std::endl;
0407 std::cout << "invariant mass: " << invariantMass << " invariant Pt: " << invariantPt << " invariantPhi: " << invariantPhi << std::endl;
0408 }
0409
0410 if (invariantPt > invariant_pt_cut)
0411 {
0412 massreco->Fill(invariantMass);
0413 }
0414 }
0415
0416 bool KshortReconstruction::projectTrackToPoint(SvtxTrack* track, Eigen::Vector3d PCA, Eigen::Vector3d& pos, Eigen::Vector3d& mom)
0417 {
0418 bool ret = true;
0419
0420
0421 ActsPropagator actsPropagator(_tGeometry);
0422 auto perigee = actsPropagator.makeVertexSurface(PCA);
0423 auto params = actsPropagator.makeTrackParams(track, m_vertexMap);
0424 if (!params.ok())
0425 {
0426 return false;
0427 }
0428 auto result = actsPropagator.propagateTrack(params.value(), perigee);
0429
0430 if (result.ok())
0431 {
0432 auto projectionPos = result.value().second.position(_tGeometry->geometry().getGeoContext());
0433 const auto momentum = result.value().second.momentum();
0434 pos(0) = projectionPos.x() / Acts::UnitConstants::cm;
0435 pos(1) = projectionPos.y() / Acts::UnitConstants::cm;
0436 pos(2) = projectionPos.z() / Acts::UnitConstants::cm;
0437
0438 if (Verbosity() > 2)
0439 {
0440 std::cout << " Input PCA " << PCA << " projection out " << pos << std::endl;
0441 }
0442
0443 mom(0) = momentum.x();
0444 mom(1) = momentum.y();
0445 mom(2) = momentum.z();
0446 }
0447 else
0448 {
0449 pos(0) = track->get_x();
0450 pos(1) = track->get_y();
0451 pos(2) = track->get_z();
0452
0453 mom(0) = track->get_px();
0454 mom(1) = track->get_py();
0455 mom(2) = track->get_pz();
0456
0457 if(Verbosity() > 0)
0458 {
0459 std::cout << result.error() << std::endl;
0460 std::cout << result.error().message() << std::endl;
0461 std::cout << " Failed projection of track with: " << std::endl;
0462 std::cout << " x,y,z = " << track->get_x() << " " << track->get_y() << " " << track->get_z() << std::endl;
0463 std::cout << " px,py,pz = " << track->get_px() << " " << track->get_py() << " " << track->get_pz() << std::endl;
0464 std::cout << " to point (x,y,z) = " << PCA(0) / Acts::UnitConstants::cm << " " << PCA(1) / Acts::UnitConstants::cm << " " << PCA(2) / Acts::UnitConstants::cm << std::endl;
0465 }
0466
0467
0468 }
0469
0470 return ret;
0471 }
0472
0473 bool KshortReconstruction::projectTrackToCylinder(SvtxTrack* track, double Radius, Eigen::Vector3d& pos, Eigen::Vector3d& mom)
0474 {
0475
0476 bool ret = true;
0477 const double eta = 2.0;
0478 const double theta = 2. * atan(exp(-eta));
0479 const double halfZ = Radius / tan(theta) * Acts::UnitConstants::cm;
0480 Radius *= Acts::UnitConstants::cm;
0481
0482
0483 auto transform = Acts::Transform3::Identity();
0484
0485 std::shared_ptr<Acts::CylinderSurface> cylSurf =
0486 Acts::Surface::makeShared<Acts::CylinderSurface>(transform,
0487 Radius,
0488 halfZ);
0489 ActsPropagator actsPropagator(_tGeometry);
0490 auto params = actsPropagator.makeTrackParams(track, m_vertexMap);
0491 if (!params.ok())
0492 {
0493 return false;
0494 }
0495
0496 auto result = actsPropagator.propagateTrack(params.value(), cylSurf);
0497 if (result.ok())
0498 {
0499 auto projectionPos = result.value().second.position(_tGeometry->geometry().getGeoContext());
0500 const auto momentum = result.value().second.momentum();
0501 pos(0) = projectionPos.x() / Acts::UnitConstants::cm;
0502 pos(1) = projectionPos.y() / Acts::UnitConstants::cm;
0503 pos(2) = projectionPos.z() / Acts::UnitConstants::cm;
0504
0505 mom(0) = momentum.x();
0506 mom(1) = momentum.y();
0507 mom(2) = momentum.z();
0508 }
0509 else
0510 {
0511 ret = false;
0512 }
0513
0514 return ret;
0515 }
0516
0517 Acts::Vector3 KshortReconstruction::getVertex(SvtxTrack* track)
0518 {
0519 auto vertexId = track->get_vertex_id();
0520 const SvtxVertex* svtxVertex = m_vertexMap->get(vertexId);
0521 Acts::Vector3 vertex = Acts::Vector3::Zero();
0522 if (svtxVertex)
0523 {
0524 vertex(0) = svtxVertex->get_x() * Acts::UnitConstants::cm;
0525 vertex(1) = svtxVertex->get_y() * Acts::UnitConstants::cm;
0526 vertex(2) = svtxVertex->get_z() * Acts::UnitConstants::cm;
0527 }
0528
0529 return vertex;
0530 }
0531
0532 void KshortReconstruction::findPcaTwoTracks(const Acts::Vector3& pos1, const Acts::Vector3& pos2, Acts::Vector3 mom1, Acts::Vector3 mom2, Acts::Vector3& pca1, Acts::Vector3& pca2, double& dca) const
0533 {
0534 TLorentzVector v1;
0535 TLorentzVector v2;
0536
0537 double px1 = mom1(0);
0538 double py1 = mom1(1);
0539 double pz1 = mom1(2);
0540 double px2 = mom2(0);
0541 double py2 = mom2(1);
0542 double pz2 = mom2(2);
0543
0544 Float_t E1 = sqrt(pow(px1, 2) + pow(py1, 2) + pow(pz1, 2) + pow(decaymass, 2));
0545 Float_t E2 = sqrt(pow(px2, 2) + pow(py2, 2) + pow(pz2, 2) + pow(decaymass, 2));
0546
0547 v1.SetPxPyPzE(px1, py1, pz1, E1);
0548 v2.SetPxPyPzE(px2, py2, pz2, E2);
0549
0550
0551 const Eigen::Vector3d& a1 = pos1;
0552 const Eigen::Vector3d& a2 = pos2;
0553
0554 Eigen::Vector3d b1(v1.Px(), v1.Py(), v1.Pz());
0555 Eigen::Vector3d b2(v2.Px(), v2.Py(), v2.Pz());
0556
0557
0558
0559
0560
0561
0562
0563
0564 auto bcrossb = b1.cross(b2);
0565 auto mag_bcrossb = bcrossb.norm();
0566
0567 auto aminusa = a2 - a1;
0568
0569
0570
0571 dca = 999;
0572 if (mag_bcrossb != 0)
0573 {
0574 dca = bcrossb.dot(aminusa) / mag_bcrossb;
0575 }
0576 else
0577 {
0578 return;
0579 }
0580
0581
0582 double X = b1.dot(b2) - (b1.dot(b1) * b2.dot(b2) / b2.dot(b1));
0583 double Y = (a2.dot(b2) - a1.dot(b2)) - ((a2.dot(b1) - a1.dot(b1)) * b2.dot(b2) / b2.dot(b1));
0584 double c = Y / X;
0585
0586 double F = b1.dot(b1) / b2.dot(b1);
0587 double G = -(a2.dot(b1) - a1.dot(b1)) / b2.dot(b1);
0588 double d = (c * F) + G;
0589
0590
0591 pca1 = a1 + c * b1;
0592 pca2 = a2 + d * b2;
0593
0594 return;
0595 }
0596
0597 KshortReconstruction::KshortReconstruction(const std::string& name)
0598 : SubsysReco(name)
0599 {
0600 }
0601
0602 Acts::Vector3 KshortReconstruction::calculateDca(SvtxTrack* track, const Acts::Vector3& momentum, Acts::Vector3 position)
0603 {
0604
0605 Acts::Vector3 r = momentum.cross(Acts::Vector3(0., 0., 1.));
0606 float phi = atan2(r(1), r(0));
0607 Acts::Vector3 outVals(track_dca_cut*1.1, track_dca_cut*1.1, phi);
0608 auto vtxid = track->get_vertex_id();
0609 if (!m_vertexMap)
0610 {
0611
0612 return outVals;
0613 }
0614 auto *svtxVertex = m_vertexMap->get(vtxid);
0615 if (!svtxVertex)
0616 {
0617
0618 return outVals;
0619 }
0620 Acts::Vector3 vertex(svtxVertex->get_x(), svtxVertex->get_y(), svtxVertex->get_z());
0621 position -= vertex;
0622
0623 Acts::RotationMatrix3 rot;
0624 rot(0, 0) = std::cos(phi);
0625 rot(0, 1) = -std::sin(phi);
0626 rot(0, 2) = 0;
0627 rot(1, 0) = std::sin(phi);
0628 rot(1, 1) = std::cos(phi);
0629 rot(1, 2) = 0;
0630 rot(2, 0) = 0;
0631 rot(2, 1) = 0;
0632 rot(2, 2) = 1;
0633
0634 Acts::Vector3 pos_R = rot * position;
0635 double dca3dxy = pos_R(0);
0636 double dca3dz = pos_R(2);
0637
0638 outVals(0) = abs(dca3dxy);
0639 outVals(1) = abs(dca3dz);
0640 outVals(2) = phi;
0641
0642 if (Verbosity() > 4)
0643 {
0644 std::cout << " pre-position: " << position << std::endl;
0645 std::cout << " vertex: " << vertex << std::endl;
0646 std::cout << " vertex subtracted-position: " << position << std::endl;
0647 }
0648
0649 return outVals;
0650 }
0651
0652 int KshortReconstruction::InitRun(PHCompositeNode* topNode)
0653 {
0654 const char* cfilepath = filepath.c_str();
0655 fout = new TFile(cfilepath, "recreate");
0656 ntp_reco_info = new TNtuple("ntp_reco_info", "decay_pairs", "id1:crossing1:x1:y1:z1:px1:py1:pz1:dca3dxy1:dca3dz1:phi1:pca_rel1_x:pca_rel1_y:pca_rel1_z:eta1:charge1:tpcClusters_1:id2:crossing2:x2:y2:z2:px2:py2:pz2:dca3dxy2:dca3dz2:phi2:pca_rel2_x:pca_rel2_y:pca_rel2_z:eta2:charge2:tpcClusters_2:vertex_x:vertex_y:vertex_z:pair_dca:invariant_mass:invariant_pt:invariantPhi:pathlength_x:pathlength_y:pathlength_z:pathlength:rapidity:pseudorapidity:projected_pos1_x:projected_pos1_y:projected_pos1_z:projected_pos2_x:projected_pos2_y:projected_pos2_z:projected_mom1_x:projected_mom1_y:projected_mom1_z:projected_mom2_x:projected_mom2_y:projected_mom2_z:projected_pca_rel1_x:projected_pca_rel1_y:projected_pca_rel1_z:projected_pca_rel2_x:projected_pca_rel2_y:projected_pca_rel2_z:projected_pair_dca:projected_pathlength_x:projected_pathlength_y:projected_pathlength_z:projected_pathlength:quality1:quality2:cosThetaReco:track1_silicon_clusters:track2_silicon_clusters:track1_mvtx_clusters:track1_mvtx_states:track1_intt_clusters:track1_intt_states:track2_mvtx_clusters:track2_mvtx_states:track2_intt_clusters:track2_intt_states:runNumber:eventNumber");
0657
0658 getNodes(topNode);
0659
0660 recomass = new TH1D("recomass", "recomass", 1000, 0.0, 1);
0661
0662
0663 if (m_save_tracks)
0664 {
0665 PHNodeIterator nodeIter(topNode);
0666
0667 PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(nodeIter.findFirst("PHCompositeNode", "DST"));
0668 if (!dstNode)
0669 {
0670 dstNode = new PHCompositeNode("DST");
0671 topNode->addNode(dstNode);
0672 std::cout << "DST node added" << std::endl;
0673 }
0674
0675 m_output_trackMap = new SvtxTrackMap_v2();
0676 PHIODataNode<PHObject> *outputTrackNode = new PHIODataNode<PHObject>(m_output_trackMap, m_output_trackMap_node_name, "PHObject");
0677 dstNode->addNode(outputTrackNode);
0678 if (Verbosity() > 1) { std::cout << m_output_trackMap_node_name << " node added" << std::endl; }
0679 }
0680
0681 return 0;
0682 }
0683
0684 int KshortReconstruction::End(PHCompositeNode* )
0685 {
0686 fout->cd();
0687 ntp_reco_info->Write();
0688 recomass->Write();
0689 fout->Close();
0690
0691 return 0;
0692 }
0693
0694 int KshortReconstruction::getNodes(PHCompositeNode* topNode)
0695 {
0696 m_svtxTrackMap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap");
0697 if (!m_svtxTrackMap)
0698 {
0699 std::cout << PHWHERE << "No SvtxTrackMap on node tree, exiting." << std::endl;
0700 return Fun4AllReturnCodes::ABORTEVENT;
0701 }
0702
0703 m_vertexMap = findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap");
0704 if (!m_vertexMap)
0705 {
0706 std::cout << PHWHERE << "No vertexMap on node tree, exiting." << std::endl;
0707 return Fun4AllReturnCodes::ABORTEVENT;
0708 }
0709
0710 _tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0711 if (!_tGeometry)
0712 {
0713 std::cout << PHWHERE << "Error, can't find acts tracking geometry" << std::endl;
0714 return Fun4AllReturnCodes::ABORTEVENT;
0715 }
0716
0717 return Fun4AllReturnCodes::EVENT_OK;
0718 }