File indexing completed on 2025-08-06 08:18:18
0001 #include "HelicalFitter.h"
0002
0003 #include "AlignmentDefs.h"
0004 #include "Mille.h"
0005
0006 #include <tpc/TpcClusterZCrossingCorrection.h>
0007
0008
0009 #include <fun4all/SubsysReco.h>
0010 #include <math.h>
0011 #include <phool/PHIODataNode.h>
0012 #include <phparameter/PHParameterInterface.h>
0013 #include <trackbase/ActsSurfaceMaps.h>
0014 #include <trackbase/InttDefs.h>
0015 #include <trackbase/MvtxDefs.h>
0016 #include <trackbase/TpcDefs.h>
0017 #include <trackbase/TrackFitUtils.h>
0018 #include <trackbase/TrkrClusterContainer.h>
0019 #include <trackbase/TrkrClusterContainerv4.h>
0020 #include <trackbase/TrkrClusterv3.h>
0021 #include <trackbase/TrkrDefs.h> // for cluskey, getTrkrId, tpcId
0022 #include <trackbase/alignmentTransformationContainer.h>
0023
0024 #include <trackbase_historic/TrackSeedContainer.h>
0025 #include <trackbase_historic/SvtxAlignmentState.h>
0026 #include <trackbase_historic/SvtxAlignmentStateMap_v1.h>
0027 #include <trackbase_historic/SvtxAlignmentState_v1.h>
0028 #include <trackbase_historic/SvtxTrackMap_v2.h>
0029 #include <trackbase_historic/SvtxTrackState_v1.h>
0030 #include <trackbase_historic/SvtxTrack_v4.h>
0031 #include <trackbase_historic/TrackSeedHelper.h>
0032 #include <trackbase_historic/TrackSeed_v2.h>
0033
0034 #include <globalvertex/SvtxVertex.h>
0035 #include <globalvertex/SvtxVertexMap.h>
0036
0037 #include <Acts/Definitions/Algebra.hpp>
0038 #include <Acts/Definitions/Units.hpp>
0039
0040 #include <fun4all/Fun4AllReturnCodes.h>
0041
0042 #include <phool/PHCompositeNode.h>
0043 #include <phool/getClass.h>
0044 #include <phool/phool.h>
0045
0046 #include <TFile.h>
0047 #include <TNtuple.h>
0048
0049 #include <climits> // for UINT_MAX
0050 #include <cmath> // for fabs, sqrt
0051 #include <fstream>
0052 #include <iostream> // for operator<<, basic_ostream
0053 #include <memory>
0054 #include <set> // for _Rb_tree_const_iterator
0055 #include <stdexcept>
0056 #include <string>
0057 #include <tuple>
0058 #include <utility> // for pair
0059 #include <vector>
0060
0061 using namespace std;
0062
0063
0064
0065
0066
0067 namespace
0068 {
0069 bool arr_has_nan(float* arr)
0070 {
0071 for (int i = 0; i < AlignmentDefs::NLC; ++i)
0072 {
0073 if (isnan(arr[i]))
0074 {
0075 return true;
0076 }
0077 }
0078 return false;
0079 }
0080 };
0081
0082 HelicalFitter::HelicalFitter(const std::string& name)
0083 : SubsysReco(name)
0084 , PHParameterInterface(name)
0085 , _mille(nullptr)
0086 {
0087 InitializeParameters();
0088
0089 vertexPosition(0) = 0;
0090 vertexPosition(1) = 0;
0091
0092 vtx_sigma(0) = 0.005;
0093 vtx_sigma(1) = 0.005;
0094 }
0095
0096
0097 int HelicalFitter::InitRun(PHCompositeNode* topNode)
0098 {
0099 UpdateParametersWithMacro();
0100
0101 int ret = GetNodes(topNode);
0102 if (ret != Fun4AllReturnCodes::EVENT_OK)
0103 {
0104 return ret;
0105 }
0106
0107 ret = CreateNodes(topNode);
0108 if (ret != Fun4AllReturnCodes::EVENT_OK)
0109 {
0110 return ret;
0111 }
0112
0113
0114 if (test_output)
0115 {
0116 _mille = new Mille(data_outfilename.c_str(), false);
0117 }
0118 else
0119 {
0120 _mille = new Mille(data_outfilename.c_str());
0121 }
0122
0123
0124 std::ofstream steering_file(steering_outfilename);
0125 steering_file << data_outfilename << std::endl;
0126 steering_file.close();
0127
0128 if (make_ntuple)
0129 {
0130
0131 fout = new TFile(ntuple_outfilename.c_str(), "recreate");
0132 if (straight_line_fit)
0133 {
0134 ntp = new TNtuple("ntp", "HF ntuple", "event:trkid:layer:nsilicon:crosshalfmvtx:ntpc:nclus:trkrid:sector:side:subsurf:phi:glbl0:glbl1:glbl2:glbl3:glbl4:glbl5:sensx:sensy:sensz:normx:normy:normz:sensxideal:sensyideal:senszideal:normxideal:normyideal:normzideal:xglobideal:yglobideal:zglobideal:XYs:Y0:Zs:Z0:xglob:yglob:zglob:xfit:yfit:zfit:xfitMvtxHalf:yfitMvtxHalf:zfitMvtxHalf:pcax:pcay:pcaz:tangx:tangy:tangz:X:Y:fitX:fitY:fitXMvtxHalf:fitYMvtxHalf:dXdXYs:dXdY0:dXdZs:dXdZ0:dXdalpha:dXdbeta:dXdgamma:dXdx:dXdy:dXdz:dYdXYs:dYdY0:dYdZs:dYdZ0:dYdalpha:dYdbeta:dYdgamma:dYdx:dYdy:dYdz");
0135 }
0136 else
0137 {
0138 ntp = new TNtuple("ntp", "HF ntuple", "event:trkid:layer:nsilicon:ntpc:nclus:trkrid:sector:side:subsurf:phi:glbl0:glbl1:glbl2:glbl3:glbl4:glbl5:sensx:sensy:sensz:normx:normy:normz:sensxideal:sensyideal:senszideal:normxideal:normyideal:normzideal:xglobideal:yglobideal:zglobideal:R:X0:Y0:Zs:Z0:xglob:yglob:zglob:xfit:yfit:zfit:pcax:pcay:pcaz:tangx:tangy:tangz:X:Y:fitX:fitY:dXdR:dXdX0:dXdY0:dXdZs:dXdZ0:dXdalpha:dXdbeta:dXdgamma:dXdx:dXdy:dXdz:dYdR:dYdX0:dYdY0:dYdZs:dYdZ0:dYdalpha:dYdbeta:dYdgamma:dYdx:dYdy:dYdz");
0139 }
0140
0141 if (straight_line_fit)
0142 {
0143 track_ntp = new TNtuple("track_ntp", "HF track ntuple", "track_id:residual_x:residual_y:residualxsigma:residualysigma:dXdXYs:dXdY0:dXdZs:dXdZ0:dXdx:dXdy:dXdz:dYdXYs:dYdY0:dYdZs:dYdZ0:dYdx:dYdy:dYdz:track_xvtx:track_yvtx:track_zvtx:event_xvtx:event_yvtx:event_zvtx:track_phi:perigee_phi:track_eta");
0144 }
0145 else
0146 {
0147 track_ntp = new TNtuple("track_ntp", "HF track ntuple", "track_id:residual_x:residual_y:residualxsigma:residualysigma:dXdR:dXdX0:dXdY0:dXdZs:dXdZ0:dXdx:dXdy:dXdz:dYdR:dYdX0:dYdY0:dYdZs:dYdZ0:dYdx:dYdy:dYdz:track_xvtx:track_yvtx:track_zvtx:event_xvtx:event_yvtx:event_zvtx:track_phi:perigee_phi");
0148 }
0149 }
0150
0151
0152 std::cout << "HelicalFitter::InitRun: Surface groupings are mvtx " << mvtx_grp << " intt " << intt_grp << " tpc " << tpc_grp << " mms " << mms_grp << std::endl;
0153 std::cout << " possible groupings are:" << std::endl
0154 << " mvtx "
0155 << AlignmentDefs::mvtxGrp::snsr << " "
0156 << AlignmentDefs::mvtxGrp::stv << " "
0157 << AlignmentDefs::mvtxGrp::mvtxlyr << " "
0158 << AlignmentDefs::mvtxGrp::clamshl << " " << std::endl
0159 << " intt "
0160 << AlignmentDefs::inttGrp::chp << " "
0161 << AlignmentDefs::inttGrp::lad << " "
0162 << AlignmentDefs::inttGrp::inttlyr << " "
0163 << AlignmentDefs::inttGrp::inttbrl << " " << std::endl
0164 << " tpc "
0165 << AlignmentDefs::tpcGrp::htst << " "
0166 << AlignmentDefs::tpcGrp::sctr << " "
0167 << AlignmentDefs::tpcGrp::tp << " " << std::endl
0168 << " mms "
0169 << AlignmentDefs::mmsGrp::tl << " "
0170 << AlignmentDefs::mmsGrp::mm << " " << std::endl;
0171
0172 event = -1;
0173
0174 return ret;
0175 }
0176
0177
0178 void HelicalFitter::SetDefaultParameters()
0179 {
0180 return;
0181 }
0182
0183
0184 int HelicalFitter::process_event(PHCompositeNode* )
0185 {
0186
0187
0188
0189
0190 event++;
0191
0192 if (Verbosity() > 0)
0193 {
0194 if (_track_map_tpc)
0195 {
0196 std::cout << PHWHERE
0197 << " TPC seed map size " << _track_map_tpc->size() << std::endl;
0198 }
0199 if (_track_map_silicon)
0200 {
0201 std::cout << " Silicon seed map size " << _track_map_silicon->size()
0202 << std::endl;
0203 }
0204 }
0205
0206 if (fitsilicon && _track_map_silicon != nullptr)
0207 {
0208 if (_track_map_silicon->size() == 0)
0209 {
0210 return Fun4AllReturnCodes::ABORTEVENT;
0211 }
0212 }
0213 if (fittpc && _track_map_tpc != nullptr)
0214 {
0215 if (_track_map_tpc->size() == 0)
0216 {
0217 return Fun4AllReturnCodes::ABORTEVENT;
0218 }
0219 }
0220
0221
0222 unsigned int maxtracks = 0;
0223 unsigned int nsilicon = 0;
0224 unsigned int ntpc = 0;
0225 unsigned int nclus = 0;
0226 bool h2h_flag = false;
0227 bool mvtx_east_only = false;
0228 bool mvtx_west_only = false;
0229 if (do_mvtx_half == 0)
0230 {
0231 mvtx_east_only = true;
0232 }
0233 if (do_mvtx_half == 1)
0234 {
0235 mvtx_west_only = true;
0236 }
0237 std::vector<std::vector<Acts::Vector3>> cumulative_global_vec;
0238 std::vector<std::vector<TrkrDefs::cluskey>> cumulative_cluskey_vec;
0239 std::vector<std::vector<float>> cumulative_fitpars_vec;
0240 std::vector<std::vector<float>> cumulative_fitpars_mvtx_half_vec;
0241 std::vector<Acts::Vector3> cumulative_vertex;
0242 std::vector<TrackSeed> cumulative_someseed;
0243 std::vector<SvtxTrack_v4> cumulative_newTrack;
0244
0245 if (fittpc && _track_map_tpc != nullptr)
0246 {
0247 maxtracks = _track_map_tpc->size();
0248 }
0249 if (fitsilicon && _track_map_silicon != nullptr)
0250 {
0251 maxtracks = _track_map_silicon->size();
0252 }
0253 for (unsigned int trackid = 0; trackid < maxtracks; ++trackid)
0254 {
0255 TrackSeed* tracklet = nullptr;
0256 if (fitsilicon && _track_map_silicon != nullptr)
0257 {
0258 tracklet = _track_map_silicon->get(trackid);
0259 }
0260 else if (fittpc && _track_map_tpc != nullptr)
0261 {
0262 tracklet = _track_map_tpc->get(trackid);
0263 }
0264 if (!tracklet)
0265 {
0266 continue;
0267 }
0268
0269 std::vector<Acts::Vector3> global_vec;
0270 std::vector<TrkrDefs::cluskey> cluskey_vec;
0271
0272
0273 getTrackletClusterList(tracklet, cluskey_vec);
0274 if (cluskey_vec.size() < 3)
0275 {
0276 continue;
0277 }
0278 int nintt = 0;
0279 for (auto& key : cluskey_vec)
0280 {
0281 if (TrkrDefs::getTrkrId(key) == TrkrDefs::inttId)
0282 {
0283 nintt++;
0284 }
0285 }
0286
0287
0288
0289 TrackFitUtils::getTrackletClusters(_tGeometry, _cluster_map, global_vec, cluskey_vec);
0290
0291 correctTpcGlobalPositions(global_vec, cluskey_vec);
0292
0293
0294 std::vector<float> fitpars;
0295 std::vector<float> fitpars_mvtx_half;
0296 if (straight_line_fit)
0297 {
0298 fitpars = TrackFitUtils::fitClustersZeroField(global_vec, cluskey_vec, use_intt_zfit, false, false);
0299 fitpars_mvtx_half = TrackFitUtils::fitClustersZeroField(global_vec, cluskey_vec, use_intt_zfit, mvtx_east_only, mvtx_west_only);
0300 if (fitpars_mvtx_half.size() < 3)
0301 {
0302 fitpars_mvtx_half = fitpars;
0303 }
0304 if (fitpars.size() == 0)
0305 {
0306 continue;
0307 }
0308
0309 if (Verbosity() > 1)
0310 {
0311 std::cout << " Track " << trackid << " xy slope " << fitpars[0] << " y intercept " << fitpars[1]
0312 << " zslope " << fitpars[2] << " Z0 " << fitpars[3] << " eta " << tracklet->get_eta() << " phi " << tracklet->get_phi() << std::endl;
0313 }
0314 }
0315 else
0316 {
0317 if (fitsilicon && nintt < 2)
0318 {
0319 continue;
0320 }
0321 if (fabs(tracklet->get_eta()) > m_eta_cut)
0322 {
0323 continue;
0324 }
0325
0326 fitpars = TrackFitUtils::fitClusters(global_vec, cluskey_vec);
0327
0328 if (fitpars.size() == 0)
0329 {
0330 continue;
0331 }
0332
0333 if (Verbosity() > 1)
0334 {
0335 std::cout << " Track " << trackid << " radius " << fitpars[0] << " X0 " << fitpars[1] << " Y0 " << fitpars[2]
0336 << " zslope " << fitpars[3] << " Z0 " << fitpars[4] << std::endl;
0337 }
0338 }
0339
0340
0341 SvtxTrack_v4 newTrack;
0342 newTrack.set_id(trackid);
0343 if (fitsilicon)
0344 {
0345 newTrack.set_silicon_seed(tracklet);
0346 }
0347 else if (fittpc)
0348 {
0349 newTrack.set_tpc_seed(tracklet);
0350 }
0351
0352
0353 if (fittpc && fitfulltrack)
0354 {
0355
0356 ntpc = cluskey_vec.size();
0357
0358 if (straight_line_fit)
0359 {
0360 std::tuple<double, double> linefit_xy(fitpars[0], fitpars[1]);
0361 nsilicon = TrackFitUtils::addClustersOnLine(linefit_xy, true, dca_cut, _tGeometry, _cluster_map, global_vec, cluskey_vec, 0, 6);
0362 }
0363 else
0364 {
0365 nsilicon = TrackFitUtils::addClusters(fitpars, dca_cut, _tGeometry, _cluster_map, global_vec, cluskey_vec, 0, 6);
0366 }
0367
0368 if (nsilicon < 5)
0369 {
0370 continue;
0371 }
0372 auto trackseed = std::make_unique<TrackSeed_v2>();
0373 for (auto& ckey : cluskey_vec)
0374 {
0375 if (TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId or
0376 TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::inttId)
0377 {
0378 trackseed->insert_cluster_key(ckey);
0379 }
0380 }
0381
0382 newTrack.set_silicon_seed(trackseed.get());
0383
0384
0385 fitpars.clear();
0386 fitpars_mvtx_half.clear();
0387
0388 if (straight_line_fit)
0389 {
0390 fitpars = TrackFitUtils::fitClustersZeroField(global_vec, cluskey_vec, use_intt_zfit);
0391 fitpars_mvtx_half = TrackFitUtils::fitClustersZeroField(global_vec, cluskey_vec, use_intt_zfit, mvtx_east_only, mvtx_west_only);
0392 if (fitpars.size() == 0)
0393 {
0394 continue;
0395 }
0396
0397 if (Verbosity() > 1)
0398 {
0399 std::cout << " Track " << trackid << " dy/dx " << fitpars[0] << " y intercept " << fitpars[1]
0400 << " dx/dz " << fitpars[2] << " Z0 " << fitpars[3] << " eta " << tracklet->get_eta() << " phi " << tracklet->get_phi() << std::endl;
0401 }
0402 if (fabs(tracklet->get_eta()) > m_eta_cut)
0403 {
0404 continue;
0405 }
0406 }
0407 else
0408 {
0409 fitpars = TrackFitUtils::fitClusters(global_vec, cluskey_vec, use_intt_zfit);
0410
0411 if (fitpars.size() == 0)
0412 {
0413 continue;
0414 }
0415
0416 if (Verbosity() > 1)
0417 {
0418 std::cout << " Full track " << trackid << " radius " << fitpars[0] << " X0 " << fitpars[1] << " Y0 " << fitpars[2]
0419 << " zslope " << fitpars[3] << " Z0 " << fitpars[4] << std::endl;
0420 }
0421 }
0422 }
0423 else if (fitsilicon)
0424 {
0425 nsilicon = cluskey_vec.size();
0426 h2h_flag = TrackFitUtils::isTrackCrossMvtxHalf(cluskey_vec);
0427 }
0428 else if (fittpc && !fitfulltrack)
0429 {
0430 ntpc = cluskey_vec.size();
0431 }
0432
0433 Acts::Vector3 const beamline(0, 0, 0);
0434 Acts::Vector2 pca2d;
0435 Acts::Vector3 track_vtx;
0436 if (straight_line_fit)
0437 {
0438 pca2d = TrackFitUtils::get_line_point_pca(fitpars[0], fitpars[1], beamline);
0439 track_vtx(0) = pca2d(0);
0440 track_vtx(1) = pca2d(1);
0441 track_vtx(2) = fitpars[3];
0442 }
0443 else
0444 {
0445 pca2d = TrackFitUtils::get_circle_point_pca(fitpars[0], fitpars[1], fitpars[2], beamline);
0446 track_vtx(0) = pca2d(0);
0447 track_vtx(1) = pca2d(1);
0448 track_vtx(2) = fitpars[4];
0449 }
0450
0451 newTrack.set_crossing(tracklet->get_crossing());
0452 newTrack.set_id(trackid);
0453
0454
0455
0456
0457 TrackSeed_v2 someseed;
0458 for (auto& ckey : cluskey_vec)
0459 {
0460 someseed.insert_cluster_key(ckey);
0461 }
0462
0463 if (straight_line_fit)
0464 {
0465 someseed.set_qOverR(1.0);
0466 someseed.set_phi(tracklet->get_phi());
0467
0468 someseed.set_X0(fitpars[0]);
0469 someseed.set_Y0(fitpars[1]);
0470 someseed.set_Z0(fitpars[3]);
0471 someseed.set_slope(fitpars[2]);
0472
0473 auto tangent = get_line_tangent(fitpars, global_vec[0]);
0474 newTrack.set_x(track_vtx(0));
0475 newTrack.set_y(track_vtx(1));
0476 newTrack.set_z(track_vtx(2));
0477 newTrack.set_px(tangent.second(0));
0478 newTrack.set_py(tangent.second(1));
0479 newTrack.set_pz(tangent.second(2));
0480 newTrack.set_charge(tracklet->get_charge());
0481 }
0482 else
0483 {
0484 someseed.set_qOverR(tracklet->get_charge() / fitpars[0]);
0485 someseed.set_phi(tracklet->get_phi());
0486
0487 someseed.set_X0(fitpars[1]);
0488 someseed.set_Y0(fitpars[2]);
0489 someseed.set_Z0(fitpars[4]);
0490 someseed.set_slope(fitpars[3]);
0491
0492 const auto position = TrackSeedHelper::get_xyz(&someseed);
0493
0494 newTrack.set_x(position.x());
0495 newTrack.set_y(position.y());
0496 newTrack.set_z(position.z());
0497 newTrack.set_px(someseed.get_px());
0498 newTrack.set_py(someseed.get_py());
0499 newTrack.set_pz(someseed.get_pz());
0500 newTrack.set_charge(tracklet->get_charge());
0501 }
0502
0503 nclus = ntpc + nsilicon;
0504
0505
0506 if (fittpc && ntpc < 35)
0507 {
0508 if (Verbosity() > 1)
0509 {
0510 std::cout << " reject this track, ntpc = " << ntpc << std::endl;
0511 }
0512 continue;
0513 }
0514 if ((fitsilicon || fitfulltrack) && nsilicon < 3)
0515 {
0516 if (Verbosity() > 1)
0517 {
0518 std::cout << " reject this track, nsilicon = " << nsilicon << std::endl;
0519 }
0520 continue;
0521 }
0522 if (fabs(newTrack.get_eta()) > m_eta_cut)
0523 {
0524 continue;
0525 }
0526 cumulative_global_vec.push_back(global_vec);
0527 cumulative_cluskey_vec.push_back(cluskey_vec);
0528 cumulative_vertex.push_back(track_vtx);
0529 cumulative_fitpars_vec.push_back(fitpars);
0530 cumulative_fitpars_mvtx_half_vec.push_back(fitpars_mvtx_half);
0531 cumulative_someseed.push_back(someseed);
0532 cumulative_newTrack.push_back(newTrack);
0533 }
0534
0535
0536
0537
0538
0539 float xsum = 0;
0540 float ysum = 0;
0541 float zsum = 0;
0542 unsigned int const accepted_tracks = cumulative_fitpars_vec.size();
0543
0544 for (unsigned int trackid = 0; trackid < accepted_tracks; ++trackid)
0545 {
0546 xsum += cumulative_vertex[trackid][0];
0547 ysum += cumulative_vertex[trackid][1];
0548 zsum += cumulative_vertex[trackid][2];
0549 }
0550 Acts::Vector3 averageVertex(xsum / accepted_tracks, ysum / accepted_tracks, zsum / accepted_tracks);
0551
0552 for (unsigned int trackid = 0; trackid < accepted_tracks; ++trackid)
0553 {
0554 const auto& global_vec = cumulative_global_vec[trackid];
0555 const auto& cluskey_vec = cumulative_cluskey_vec[trackid];
0556 auto fitpars = cumulative_fitpars_vec[trackid];
0557 auto fitpars_mvtx_half = cumulative_fitpars_mvtx_half_vec[trackid];
0558 const auto& someseed = cumulative_someseed[trackid];
0559 auto newTrack = cumulative_newTrack[trackid];
0560 SvtxAlignmentStateMap::StateVec statevec;
0561
0562
0563 for (unsigned int ivec = 0; ivec < global_vec.size(); ++ivec)
0564 {
0565 auto global = global_vec[ivec];
0566 auto cluskey = cluskey_vec[ivec];
0567 auto cluster = _cluster_map->findCluster(cluskey);
0568
0569 if (!cluster)
0570 {
0571 continue;
0572 }
0573
0574 unsigned int const trkrid = TrkrDefs::getTrkrId(cluskey);
0575
0576
0577
0578
0579
0580 Surface const surf = _tGeometry->maps().getSurface(cluskey, cluster);
0581 Acts::Vector3 helix_pca(0, 0, 0);
0582 Acts::Vector3 helix_tangent(0, 0, 0);
0583 Acts::Vector3 fitpoint;
0584 Acts::Vector3 fitpoint_mvtx_half;
0585 if (straight_line_fit)
0586 {
0587 fitpoint = get_line_surface_intersection(surf, fitpars);
0588 fitpoint_mvtx_half = get_line_surface_intersection(surf, fitpars_mvtx_half);
0589 }
0590 else
0591 {
0592 fitpoint = get_helix_surface_intersection(surf, fitpars, global, helix_pca, helix_tangent);
0593 }
0594
0595
0596
0597 Acts::Vector3 fitpoint_local = surf->transform(_tGeometry->geometry().getGeoContext()).inverse() * (fitpoint * Acts::UnitConstants::cm);
0598 Acts::Vector3 fitpoint_mvtx_half_local = surf->transform(_tGeometry->geometry().getGeoContext()).inverse() * (fitpoint_mvtx_half * Acts::UnitConstants::cm);
0599
0600 fitpoint_local /= Acts::UnitConstants::cm;
0601 fitpoint_mvtx_half_local /= Acts::UnitConstants::cm;
0602
0603 auto xloc = cluster->getLocalX();
0604 auto zloc = cluster->getLocalY();
0605
0606 if (trkrid == TrkrDefs::tpcId)
0607 {
0608 zloc = convertTimeToZ(cluskey, cluster);
0609 }
0610
0611 Acts::Vector2 residual(xloc - fitpoint_local(0), zloc - fitpoint_local(1));
0612
0613 unsigned int const layer = TrkrDefs::getLayer(cluskey_vec[ivec]);
0614 float const phi = atan2(global(1), global(0));
0615
0616 SvtxTrackState_v1 svtxstate(fitpoint.norm());
0617 svtxstate.set_x(fitpoint(0));
0618 svtxstate.set_y(fitpoint(1));
0619 svtxstate.set_z(fitpoint(2));
0620 std::pair<Acts::Vector3, Acts::Vector3> tangent;
0621 if (straight_line_fit)
0622 {
0623 tangent = get_line_tangent(fitpars, global);
0624 }
0625 else
0626 {
0627 tangent = get_helix_tangent(fitpars, global);
0628 }
0629
0630 svtxstate.set_px(someseed.get_p() * tangent.second.x());
0631 svtxstate.set_py(someseed.get_p() * tangent.second.y());
0632 svtxstate.set_pz(someseed.get_p() * tangent.second.z());
0633 newTrack.insert_state(&svtxstate);
0634
0635 if (Verbosity() > 1)
0636 {
0637 Acts::Vector3 loc_check = surf->transform(_tGeometry->geometry().getGeoContext()).inverse() * (global * Acts::UnitConstants::cm);
0638 loc_check /= Acts::UnitConstants::cm;
0639 std::cout << " layer " << layer << std::endl
0640 << " cluster global " << global(0) << " " << global(1) << " " << global(2) << std::endl
0641 << " fitpoint " << fitpoint(0) << " " << fitpoint(1) << " " << fitpoint(2) << std::endl
0642 << " fitpoint_local " << fitpoint_local(0) << " " << fitpoint_local(1) << " " << fitpoint_local(2) << std::endl
0643 << " cluster local x " << cluster->getLocalX() << " cluster local y " << cluster->getLocalY() << std::endl
0644 << " cluster global to local x " << loc_check(0) << " local y " << loc_check(1) << " local z " << loc_check(2) << std::endl
0645 << " cluster local residual x " << residual(0) << " cluster local residual y " << residual(1) << std::endl;
0646 }
0647
0648 if (Verbosity() > 1)
0649 {
0650 Acts::Transform3 transform = surf->transform(_tGeometry->geometry().getGeoContext());
0651 std::cout << "Transform is:" << std::endl;
0652 std::cout << transform.matrix() << std::endl;
0653 Acts::Vector3 loc_check = surf->transform(_tGeometry->geometry().getGeoContext()).inverse() * (global * Acts::UnitConstants::cm);
0654 loc_check /= Acts::UnitConstants::cm;
0655 unsigned int const sector = TpcDefs::getSectorId(cluskey_vec[ivec]);
0656 unsigned int const side = TpcDefs::getSide(cluskey_vec[ivec]);
0657 std::cout << " layer " << layer << " sector " << sector << " side " << side << " subsurf " << cluster->getSubSurfKey() << std::endl
0658 << " cluster global " << global(0) << " " << global(1) << " " << global(2) << std::endl
0659 << " fitpoint " << fitpoint(0) << " " << fitpoint(1) << " " << fitpoint(2) << std::endl
0660 << " fitpoint_local " << fitpoint_local(0) << " " << fitpoint_local(1) << " " << fitpoint_local(2) << std::endl
0661 << " cluster local x " << cluster->getLocalX() << " cluster local y " << cluster->getLocalY() << std::endl
0662 << " cluster global to local x " << loc_check(0) << " local y " << loc_check(1) << " local z " << loc_check(2) << std::endl
0663 << " cluster local residual x " << residual(0) << " cluster local residual y " << residual(1) << std::endl;
0664 }
0665
0666
0667 Acts::Vector2 clus_sigma = getClusterError(cluster, cluskey, global);
0668 if (isnan(clus_sigma(0)) || isnan(clus_sigma(1)))
0669 {
0670 continue;
0671 }
0672
0673 int glbl_label[AlignmentDefs::NGL];
0674 if (layer < 3)
0675 {
0676 AlignmentDefs::getMvtxGlobalLabels(surf, cluskey, glbl_label, mvtx_grp);
0677 }
0678 else if (layer > 2 && layer < 7)
0679 {
0680 AlignmentDefs::getInttGlobalLabels(surf, cluskey, glbl_label, intt_grp);
0681 }
0682 else if (layer < 55)
0683 {
0684 AlignmentDefs::getTpcGlobalLabels(surf, cluskey, glbl_label, tpc_grp);
0685 }
0686 else
0687 {
0688 continue;
0689 }
0690
0691
0692 float lcl_derivativeX[AlignmentDefs::NLC] = {0., 0., 0., 0., 0.};
0693 float lcl_derivativeY[AlignmentDefs::NLC] = {0., 0., 0., 0., 0.};
0694 if (straight_line_fit)
0695 {
0696 getLocalDerivativesZeroFieldXY(surf, global, fitpars, lcl_derivativeX, lcl_derivativeY, layer);
0697 }
0698 else
0699 {
0700 getLocalDerivativesXY(surf, global, fitpars, lcl_derivativeX, lcl_derivativeY, layer);
0701 }
0702
0703
0704 float glbl_derivativeX[AlignmentDefs::NGL];
0705 float glbl_derivativeY[AlignmentDefs::NGL];
0706 getGlobalDerivativesXY(surf, global, fitpoint, fitpars, glbl_derivativeX, glbl_derivativeY, layer);
0707
0708 auto alignmentstate = std::make_unique<SvtxAlignmentState_v1>();
0709 alignmentstate->set_residual(residual);
0710 alignmentstate->set_cluster_key(cluskey);
0711 SvtxAlignmentState::GlobalMatrix svtxglob =
0712 SvtxAlignmentState::GlobalMatrix::Zero();
0713 SvtxAlignmentState::LocalMatrix svtxloc =
0714 SvtxAlignmentState::LocalMatrix::Zero();
0715 for (int i = 0; i < AlignmentDefs::NLC; i++)
0716 {
0717 svtxloc(0, i) = lcl_derivativeX[i];
0718 svtxloc(1, i) = lcl_derivativeY[i];
0719 }
0720 for (int i = 0; i < AlignmentDefs::NGL; i++)
0721 {
0722 svtxglob(0, i) = glbl_derivativeX[i];
0723 svtxglob(1, i) = glbl_derivativeY[i];
0724 }
0725
0726 alignmentstate->set_local_derivative_matrix(svtxloc);
0727 alignmentstate->set_global_derivative_matrix(svtxglob);
0728
0729 statevec.push_back(alignmentstate.release());
0730
0731 for (unsigned int i = 0; i < AlignmentDefs::NGL; ++i)
0732 {
0733 if (trkrid == TrkrDefs::mvtxId)
0734 {
0735
0736 auto stave = MvtxDefs::getStaveId(cluskey_vec[ivec]);
0737 auto clamshell = AlignmentDefs::getMvtxClamshell(layer, stave);
0738 if (is_layer_param_fixed(layer, i) || is_mvtx_layer_fixed(layer, clamshell))
0739 {
0740 glbl_derivativeX[i] = 0;
0741 glbl_derivativeY[i] = 0;
0742 }
0743 }
0744
0745 if (trkrid == TrkrDefs::inttId)
0746 {
0747 if (is_layer_param_fixed(layer, i) || is_intt_layer_fixed(layer))
0748 {
0749 glbl_derivativeX[i] = 0;
0750 glbl_derivativeY[i] = 0;
0751 }
0752 }
0753
0754 if (trkrid == TrkrDefs::tpcId)
0755 {
0756 unsigned int const sector = TpcDefs::getSectorId(cluskey_vec[ivec]);
0757 unsigned int const side = TpcDefs::getSide(cluskey_vec[ivec]);
0758 if (is_layer_param_fixed(layer, i) || is_tpc_sector_fixed(layer, sector, side))
0759 {
0760 glbl_derivativeX[i] = 0;
0761 glbl_derivativeY[i] = 0;
0762 }
0763 }
0764 }
0765
0766
0767
0768
0769 float errinf = 1.0;
0770
0771 if (_layerMisalignment.find(layer) != _layerMisalignment.end())
0772 {
0773 errinf = _layerMisalignment.find(layer)->second;
0774 }
0775 if (make_ntuple)
0776 {
0777
0778 alignmentTransformationContainer::use_alignment = false;
0779 Acts::Vector3 ideal_center = surf->center(_tGeometry->geometry().getGeoContext()) * 0.1;
0780 Acts::Vector3 ideal_norm = -surf->normal(_tGeometry->geometry().getGeoContext(),Acts::Vector3(1,1,1), Acts::Vector3(1,1,1));
0781 Acts::Vector3 const ideal_local(xloc, zloc, 0.0);
0782 Acts::Vector3 ideal_glob = surf->transform(_tGeometry->geometry().getGeoContext()) * (ideal_local * Acts::UnitConstants::cm);
0783 ideal_glob /= Acts::UnitConstants::cm;
0784 alignmentTransformationContainer::use_alignment = true;
0785
0786 Acts::Vector3 sensorCenter = surf->center(_tGeometry->geometry().getGeoContext()) * 0.1;
0787 Acts::Vector3 sensorNormal = -surf->normal(_tGeometry->geometry().getGeoContext(), Acts::Vector3(1,1,1), Acts::Vector3(1,1,1));
0788 unsigned int sector = TpcDefs::getSectorId(cluskey_vec[ivec]);
0789 unsigned int const side = TpcDefs::getSide(cluskey_vec[ivec]);
0790 unsigned int subsurf = cluster->getSubSurfKey();
0791 if (layer < 3)
0792 {
0793 sector = MvtxDefs::getStaveId(cluskey_vec[ivec]);
0794 subsurf = MvtxDefs::getChipId(cluskey_vec[ivec]);
0795 }
0796 else if (layer > 2 && layer < 7)
0797 {
0798 sector = InttDefs::getLadderPhiId(cluskey_vec[ivec]);
0799 subsurf = InttDefs::getLadderZId(cluskey_vec[ivec]);
0800 }
0801 if (straight_line_fit)
0802 {
0803 float ntp_data[78] = {
0804 (float) event, (float) trackid,
0805 (float) layer, (float) nsilicon, (float) h2h_flag, (float) ntpc, (float) nclus, (float) trkrid, (float) sector, (float) side,
0806 (float) subsurf, phi,
0807 (float) glbl_label[0], (float) glbl_label[1], (float) glbl_label[2], (float) glbl_label[3], (float) glbl_label[4], (float) glbl_label[5],
0808 (float) sensorCenter(0), (float) sensorCenter(1), (float) sensorCenter(2),
0809 (float) sensorNormal(0), (float) sensorNormal(1), (float) sensorNormal(2),
0810 (float) ideal_center(0), (float) ideal_center(1), (float) ideal_center(2),
0811 (float) ideal_norm(0), (float) ideal_norm(1), (float) ideal_norm(2),
0812 (float) ideal_glob(0), (float) ideal_glob(1), (float) ideal_glob(2),
0813 (float) fitpars[0], (float) fitpars[1], (float) fitpars[2], (float) fitpars[3],
0814 (float) global(0), (float) global(1), (float) global(2),
0815 (float) fitpoint(0), (float) fitpoint(1), (float) fitpoint(2),
0816 (float) fitpoint_mvtx_half(0), (float) fitpoint_mvtx_half(1), (float) fitpoint_mvtx_half(2),
0817 (float) tangent.first.x(), (float) tangent.first.y(), (float) tangent.first.z(),
0818 (float) tangent.second.x(), (float) tangent.second.y(), (float) tangent.second.z(),
0819 xloc, zloc, (float) fitpoint_local(0), (float) fitpoint_local(1), (float) fitpoint_mvtx_half_local(0), (float) fitpoint_mvtx_half_local(1),
0820 lcl_derivativeX[0], lcl_derivativeX[1], lcl_derivativeX[2], lcl_derivativeX[3],
0821 glbl_derivativeX[0], glbl_derivativeX[1], glbl_derivativeX[2], glbl_derivativeX[3], glbl_derivativeX[4], glbl_derivativeX[5],
0822 lcl_derivativeY[0], lcl_derivativeY[1], lcl_derivativeY[2], lcl_derivativeY[3],
0823 glbl_derivativeY[0], glbl_derivativeY[1], glbl_derivativeY[2], glbl_derivativeY[3], glbl_derivativeY[4], glbl_derivativeY[5]};
0824
0825 ntp->Fill(ntp_data);
0826 }
0827 else
0828 {
0829 float ntp_data[75] = {
0830 (float) event, (float) trackid,
0831 (float) layer, (float) nsilicon, (float) ntpc, (float) nclus, (float) trkrid, (float) sector, (float) side,
0832 (float) subsurf, phi,
0833 (float) glbl_label[0], (float) glbl_label[1], (float) glbl_label[2], (float) glbl_label[3], (float) glbl_label[4], (float) glbl_label[5],
0834 (float) sensorCenter(0), (float) sensorCenter(1), (float) sensorCenter(2),
0835 (float) sensorNormal(0), (float) sensorNormal(1), (float) sensorNormal(2),
0836 (float) ideal_center(0), (float) ideal_center(1), (float) ideal_center(2),
0837 (float) ideal_norm(0), (float) ideal_norm(1), (float) ideal_norm(2),
0838 (float) ideal_glob(0), (float) ideal_glob(1), (float) ideal_glob(2),
0839 (float) fitpars[0], (float) fitpars[1], (float) fitpars[2], (float) fitpars[3], (float) fitpars[4],
0840 (float) global(0), (float) global(1), (float) global(2),
0841 (float) fitpoint(0), (float) fitpoint(1), (float) fitpoint(2),
0842 (float) tangent.first.x(), (float) tangent.first.y(), (float) tangent.first.z(),
0843 (float) tangent.second.x(), (float) tangent.second.y(), (float) tangent.second.z(),
0844 xloc, zloc, (float) fitpoint_local(0), (float) fitpoint_local(1),
0845 lcl_derivativeX[0], lcl_derivativeX[1], lcl_derivativeX[2], lcl_derivativeX[3], lcl_derivativeX[4],
0846 glbl_derivativeX[0], glbl_derivativeX[1], glbl_derivativeX[2], glbl_derivativeX[3], glbl_derivativeX[4], glbl_derivativeX[5],
0847 lcl_derivativeY[0], lcl_derivativeY[1], lcl_derivativeY[2], lcl_derivativeY[3], lcl_derivativeY[4],
0848 glbl_derivativeY[0], glbl_derivativeY[1], glbl_derivativeY[2], glbl_derivativeY[3], glbl_derivativeY[4], glbl_derivativeY[5]};
0849
0850 ntp->Fill(ntp_data);
0851
0852 if (Verbosity() > 2)
0853 {
0854 for (auto& i : ntp_data)
0855 {
0856 std::cout << i << " ";
0857 }
0858 std::cout << std::endl;
0859 }
0860 }
0861 }
0862
0863 if (!isnan(residual(0)) && clus_sigma(0) < 1.0)
0864 {
0865 if (arr_has_nan(lcl_derivativeX))
0866 {
0867 std::cerr << "lcl_derivativeX is NaN" << std::endl;
0868 continue;
0869 }
0870 if (arr_has_nan(glbl_derivativeX))
0871 {
0872 std::cerr << "glbl_derivativeX is NaN" << std::endl;
0873 continue;
0874 }
0875 _mille->mille(AlignmentDefs::NLC, lcl_derivativeX, AlignmentDefs::NGL, glbl_derivativeX, glbl_label, residual(0), errinf * clus_sigma(0));
0876 }
0877
0878 if (!isnan(residual(1)) && clus_sigma(1) < 1.0)
0879 {
0880 if (arr_has_nan(lcl_derivativeY))
0881 {
0882 std::cerr << "lcl_derivativeY is NaN" << std::endl;
0883 continue;
0884 }
0885 if (arr_has_nan(glbl_derivativeY))
0886 {
0887 std::cerr << "glbl_derivativeY is NaN" << std::endl;
0888 continue;
0889 }
0890 _mille->mille(AlignmentDefs::NLC, lcl_derivativeY, AlignmentDefs::NGL, glbl_derivativeY, glbl_label, residual(1), errinf * clus_sigma(1));
0891 }
0892 }
0893
0894 m_alignmentmap->insertWithKey(trackid, statevec);
0895 m_trackmap->insertWithKey(&newTrack, trackid);
0896
0897
0898
0899 if (accepted_tracks < 3)
0900 {
0901 _mille->end();
0902 continue;
0903 }
0904
0905
0906
0907 Acts::Vector3 event_vtx(averageVertex(0), averageVertex(1), averageVertex(2));
0908
0909 for (const auto& [vtxkey, vertex] : *m_vertexmap)
0910 {
0911 for (auto trackiter = vertex->begin_tracks(); trackiter != vertex->end_tracks(); ++trackiter)
0912 {
0913 SvtxTrack* vtxtrack = m_trackmap->get(*trackiter);
0914 if (vtxtrack)
0915 {
0916 unsigned int const vtxtrackid = vtxtrack->get_id();
0917 if (trackid == vtxtrackid)
0918 {
0919 event_vtx(0) = vertex->get_x();
0920 event_vtx(1) = vertex->get_y();
0921 event_vtx(2) = vertex->get_z();
0922 if (Verbosity() > 0)
0923 {
0924 std::cout << " setting event_vertex for trackid " << trackid << " to vtxid " << vtxkey
0925 << " vtx " << event_vtx(0) << " " << event_vtx(1) << " " << event_vtx(2) << std::endl;
0926 }
0927 }
0928 }
0929 }
0930 }
0931
0932
0933
0934
0935 float dca3dxy = 0;
0936 float dca3dz = 0;
0937 float dca3dxysigma = 0;
0938 float dca3dzsigma = 0;
0939 if (!straight_line_fit)
0940 {
0941 get_dca(newTrack, dca3dxy, dca3dz, dca3dxysigma, dca3dzsigma, event_vtx);
0942 }
0943 else
0944 {
0945 get_dca_zero_field(newTrack, dca3dxy, dca3dz, dca3dxysigma, dca3dzsigma, event_vtx);
0946 }
0947
0948
0949 Acts::Vector2 vtx_residual(-dca3dxy, -dca3dz);
0950
0951 float lclvtx_derivativeX[AlignmentDefs::NLC];
0952 float lclvtx_derivativeY[AlignmentDefs::NLC];
0953 if (straight_line_fit)
0954 {
0955 getLocalVtxDerivativesZeroFieldXY(newTrack, event_vtx, fitpars, lclvtx_derivativeX, lclvtx_derivativeY);
0956 }
0957 else
0958 {
0959 getLocalVtxDerivativesXY(newTrack, event_vtx, fitpars, lclvtx_derivativeX, lclvtx_derivativeY);
0960 }
0961
0962
0963 float glblvtx_derivativeX[3];
0964 float glblvtx_derivativeY[3];
0965 getGlobalVtxDerivativesXY(newTrack, event_vtx, glblvtx_derivativeX, glblvtx_derivativeY);
0966
0967 if (use_event_vertex)
0968 {
0969 for (int p = 0; p < 3; p++)
0970 {
0971 if (is_vertex_param_fixed(p))
0972 {
0973 glblvtx_derivativeX[p] = 0;
0974 glblvtx_derivativeY[p] = 0;
0975 }
0976 }
0977 if (Verbosity() > 1)
0978 {
0979 std::cout << "vertex info for track " << trackid << " with charge " << newTrack.get_charge() << std::endl;
0980
0981 std::cout << "vertex is " << event_vtx.transpose() << std::endl;
0982 std::cout << "vertex residuals " << vtx_residual.transpose()
0983 << std::endl;
0984 std::cout << "local derivatives " << std::endl;
0985 for (float const i : lclvtx_derivativeX)
0986 {
0987 std::cout << i << ", ";
0988 }
0989 std::cout << std::endl;
0990 for (float const i : lclvtx_derivativeY)
0991 {
0992 std::cout << i << ", ";
0993 }
0994 std::cout << "global vtx derivaties " << std::endl;
0995 for (float const i : glblvtx_derivativeX)
0996 {
0997 std::cout << i << ", ";
0998 }
0999 std::cout << std::endl;
1000 for (float const i : glblvtx_derivativeY)
1001 {
1002 std::cout << i << ", ";
1003 }
1004 }
1005
1006 if (!isnan(vtx_residual(0)))
1007 {
1008 if (arr_has_nan(lclvtx_derivativeX))
1009 {
1010 std::cerr << "lclvtx_derivativeX is NaN" << std::endl;
1011 continue;
1012 }
1013 if (arr_has_nan(glblvtx_derivativeX))
1014 {
1015 std::cerr << "glblvtx_derivativeX is NaN" << std::endl;
1016 continue;
1017 }
1018 _mille->mille(AlignmentDefs::NLC, lclvtx_derivativeX, AlignmentDefs::NGLVTX, glblvtx_derivativeX, AlignmentDefs::glbl_vtx_label, vtx_residual(0), vtx_sigma(0));
1019 }
1020 if (!isnan(vtx_residual(1)))
1021 {
1022 if (arr_has_nan(lclvtx_derivativeY))
1023 {
1024 std::cerr << "lclvtx_derivativeY is NaN" << std::endl;
1025 continue;
1026 }
1027 if (arr_has_nan(glblvtx_derivativeY))
1028 {
1029 std::cerr << "glblvtx_derivativeY is NaN" << std::endl;
1030 continue;
1031 }
1032 _mille->mille(AlignmentDefs::NLC, lclvtx_derivativeY, AlignmentDefs::NGLVTX, glblvtx_derivativeY, AlignmentDefs::glbl_vtx_label, vtx_residual(1), vtx_sigma(1));
1033 }
1034 }
1035
1036 if (make_ntuple)
1037 {
1038 Acts::Vector3 const mom(newTrack.get_px(), newTrack.get_py(), newTrack.get_pz());
1039 Acts::Vector3 r = mom.cross(Acts::Vector3(0., 0., 1.));
1040 float const perigee_phi = atan2(r(1), r(0));
1041 float const track_phi = atan2(newTrack.get_py(), newTrack.get_px());
1042 float const track_eta = atanh(newTrack.get_pz() / newTrack.get_p());
1043 if (straight_line_fit)
1044 {
1045 float ntp_data[28] = {(float) trackid, (float) vtx_residual(0), (float) vtx_residual(1), (float) vtx_sigma(0), (float) vtx_sigma(1),
1046 lclvtx_derivativeX[0], lclvtx_derivativeX[1], lclvtx_derivativeX[2], lclvtx_derivativeX[3],
1047 glblvtx_derivativeX[0], glblvtx_derivativeX[1], glblvtx_derivativeX[2],
1048 lclvtx_derivativeY[0], lclvtx_derivativeY[1], lclvtx_derivativeY[2], lclvtx_derivativeY[3],
1049 glblvtx_derivativeY[0], glblvtx_derivativeY[1], glblvtx_derivativeY[2],
1050 newTrack.get_x(), newTrack.get_y(), newTrack.get_z(),
1051 (float) event_vtx(0), (float) event_vtx(1), (float) event_vtx(2), track_phi, perigee_phi, track_eta};
1052
1053 track_ntp->Fill(ntp_data);
1054 }
1055 else
1056 {
1057 float ntp_data[29] = {(float) trackid, (float) vtx_residual(0), (float) vtx_residual(1), (float) vtx_sigma(0), (float) vtx_sigma(1),
1058 lclvtx_derivativeX[0], lclvtx_derivativeX[1], lclvtx_derivativeX[2], lclvtx_derivativeX[3], lclvtx_derivativeX[4],
1059 glblvtx_derivativeX[0], glblvtx_derivativeX[1], glblvtx_derivativeX[2],
1060 lclvtx_derivativeY[0], lclvtx_derivativeY[1], lclvtx_derivativeY[2], lclvtx_derivativeY[3], lclvtx_derivativeY[4],
1061 glblvtx_derivativeY[0], glblvtx_derivativeY[1], glblvtx_derivativeY[2],
1062 newTrack.get_x(), newTrack.get_y(), newTrack.get_z(),
1063 (float) event_vtx(0), (float) event_vtx(1), (float) event_vtx(2), track_phi, perigee_phi};
1064
1065 track_ntp->Fill(ntp_data);
1066 }
1067
1068 }
1069
1070 if (Verbosity() > 1)
1071 {
1072 std::cout << "vtx_residual xy: " << vtx_residual(0) << " vtx_residual z: " << vtx_residual(1) << " vtx_sigma xy: " << vtx_sigma(0) << " vtx_sigma z: " << vtx_sigma(1) << std::endl;
1073 std::cout << "track_x " << newTrack.get_x() << "track_y " << newTrack.get_y() << "track_z " << newTrack.get_z() << std::endl;
1074 }
1075
1076 _mille->end();
1077
1078 }
1079
1080 return Fun4AllReturnCodes::EVENT_OK;
1081 }
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091 Acts::Vector3 HelicalFitter::get_helix_surface_intersection(const Surface& surf, std::vector<float>& fitpars, Acts::Vector3 global)
1092 {
1093
1094
1095 Acts::Vector3 const sensorCenter = surf->center(_tGeometry->geometry().getGeoContext()) * 0.1;
1096 Acts::Vector3 sensorNormal = -surf->normal(_tGeometry->geometry().getGeoContext(), Acts::Vector3(1, 1, 1), Acts::Vector3(1, 1, 1));
1097 sensorNormal /= sensorNormal.norm();
1098
1099
1100
1101 std::pair<Acts::Vector3, Acts::Vector3> const line = get_helix_tangent(fitpars, std::move(global));
1102 Acts::Vector3 const pca = line.first;
1103 Acts::Vector3 const tangent = line.second;
1104
1105 Acts::Vector3 intersection = get_line_plane_intersection(pca, tangent, sensorCenter, sensorNormal);
1106
1107 return intersection;
1108 }
1109
1110 Acts::Vector3 HelicalFitter::get_line_surface_intersection(const Surface& surf, std::vector<float>& fitpars)
1111 {
1112
1113
1114 Acts::Vector3 const sensorCenter = surf->center(_tGeometry->geometry().getGeoContext()) * 0.1;
1115 Acts::Vector3 sensorNormal = -surf->normal(_tGeometry->geometry().getGeoContext(), Acts::Vector3(1, 1, 1), Acts::Vector3(1, 1, 1));
1116 sensorNormal /= sensorNormal.norm();
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137 auto line = get_line_zero_field(fitpars);
1138
1139 auto arb_point = line.first;
1140 auto tangent = line.second;
1141
1142 Acts::Vector3 intersection = get_line_plane_intersection(arb_point, tangent, sensorCenter, sensorNormal);
1143
1144 return intersection;
1145 }
1146
1147 Acts::Vector3 HelicalFitter::get_helix_surface_intersection(const Surface& surf, std::vector<float>& fitpars, Acts::Vector3 global, Acts::Vector3& pca, Acts::Vector3& tangent)
1148 {
1149
1150
1151
1152 Acts::Vector3 const sensorCenter = surf->center(_tGeometry->geometry().getGeoContext()) * 0.1;
1153 Acts::Vector3 sensorNormal = -surf->normal(_tGeometry->geometry().getGeoContext(), Acts::Vector3(1, 1, 1), Acts::Vector3(1, 1, 1));
1154 sensorNormal /= sensorNormal.norm();
1155
1156
1157
1158 std::pair<Acts::Vector3, Acts::Vector3> const line = get_helix_tangent(fitpars, std::move(global));
1159 pca = line.first;
1160 tangent = line.second;
1161
1162 Acts::Vector3 intersection = get_line_plane_intersection(pca, tangent, sensorCenter, sensorNormal);
1163
1164 return intersection;
1165 }
1166
1167 Acts::Vector3 HelicalFitter::get_helix_vtx(Acts::Vector3 event_vtx, const std::vector<float>& fitpars)
1168 {
1169 Acts::Vector2 pca2d = TrackFitUtils::get_circle_point_pca(fitpars[0], fitpars[1], fitpars[2], std::move(event_vtx));
1170 Acts::Vector3 helix_vtx(pca2d(0), pca2d(1), fitpars[4]);
1171
1172 return helix_vtx;
1173 }
1174
1175 Acts::Vector3 HelicalFitter::get_line_vtx(Acts::Vector3 event_vtx, const std::vector<float>& fitpars)
1176 {
1177 Acts::Vector2 pca2d = TrackFitUtils::get_line_point_pca(fitpars[0], fitpars[1], std::move(event_vtx));
1178 Acts::Vector3 line_vtx(pca2d(0), pca2d(1), fitpars[3]);
1179
1180 return line_vtx;
1181 }
1182
1183 std::pair<Acts::Vector3, Acts::Vector3> HelicalFitter::get_line_tangent(const std::vector<float>& fitpars, Acts::Vector3 global)
1184 {
1185
1186
1187
1188 float const phi = atan2(global(1), global(0));
1189
1190
1191
1192
1193 double const x = 0;
1194 double const y = fitpars[0] * x + fitpars[1];
1195
1196 double const z = fitpars[2] * x + fitpars[3];
1197 Acts::Vector3 arb_point(x, y, z);
1198
1199 double const x2 = 1;
1200 double const y2 = fitpars[0] * x2 + fitpars[1];
1201 double const z2 = fitpars[2] * x2 + fitpars[3];
1202 Acts::Vector3 const arb_point2(x2, y2, z2);
1203
1204 float const arb_phi = atan2(arb_point(1), arb_point(0));
1205 Acts::Vector3 tangent = arb_point2 - arb_point;
1206 if (fabs(arb_phi - phi) > M_PI / 2)
1207 {
1208 tangent = arb_point - arb_point2;
1209 }
1210
1211 tangent /= tangent.norm();
1212
1213 std::pair<Acts::Vector3, Acts::Vector3> line = std::make_pair(arb_point, tangent);
1214
1215 return line;
1216 }
1217
1218 std::pair<Acts::Vector3, Acts::Vector3> HelicalFitter::get_line_zero_field(const std::vector<float>& fitpars)
1219 {
1220
1221
1222
1223 double const x = 0;
1224 double const y = fitpars[0] * x + fitpars[1];
1225 double const z = fitpars[2] * x + fitpars[3];
1226 Acts::Vector3 const arb_point(x, y, z);
1227
1228 double const x2 = 1;
1229 double const y2 = fitpars[0] * x2 + fitpars[1];
1230 double const z2 = fitpars[2] * x2 + fitpars[3];
1231 Acts::Vector3 const arb_point2(x2, y2, z2);
1232
1233 Acts::Vector3 tangent = arb_point2 - arb_point;
1234 tangent /= tangent.norm();
1235
1236 std::pair<Acts::Vector3, Acts::Vector3> line = std::make_pair(arb_point, tangent);
1237
1238 return line;
1239 }
1240
1241 std::pair<Acts::Vector3, Acts::Vector3> HelicalFitter::get_line(const std::vector<float>& fitpars)
1242 {
1243
1244
1245
1246 double const x = 0.0;
1247 double const y = fitpars[0] * x + fitpars[1];
1248 double const rxy = sqrt(x * x + y * y);
1249 double const z = fitpars[2] * rxy + fitpars[3];
1250 Acts::Vector3 const arb_point(x, y, z);
1251
1252 double const x2 = 1;
1253 double const y2 = fitpars[0] * x2 + fitpars[1];
1254 double const rxy2 = sqrt(x2 * x2 + y2 * y2);
1255 double const z2 = fitpars[2] * rxy2 + fitpars[3];
1256 Acts::Vector3 const arb_point2(x2, y2, z2);
1257
1258 Acts::Vector3 tangent = arb_point2 - arb_point;
1259 tangent /= tangent.norm();
1260
1261 std::pair<Acts::Vector3, Acts::Vector3> line = std::make_pair(arb_point, tangent);
1262
1263 return line;
1264 }
1265
1266 Acts::Vector3 HelicalFitter::get_line_plane_intersection(const Acts::Vector3& PCA, const Acts::Vector3& tangent, const Acts::Vector3& sensor_center, const Acts::Vector3& sensor_normal)
1267 {
1268
1269
1270
1271
1272
1273
1274 float const d = (sensor_center - PCA).dot(sensor_normal) / tangent.dot(sensor_normal);
1275 Acts::Vector3 intersection = PCA + d * tangent;
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285 return intersection;
1286 }
1287
1288 std::pair<Acts::Vector3, Acts::Vector3> HelicalFitter::get_helix_tangent(const std::vector<float>& fitpars, Acts::Vector3 global)
1289 {
1290 auto pair = TrackFitUtils::get_helix_tangent(fitpars, global);
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323 return pair;
1324 }
1325
1326 int HelicalFitter::End(PHCompositeNode* )
1327 {
1328
1329 delete _mille;
1330
1331 if (make_ntuple)
1332 {
1333 fout->Write();
1334 fout->Close();
1335 }
1336
1337 return Fun4AllReturnCodes::EVENT_OK;
1338 }
1339 int HelicalFitter::CreateNodes(PHCompositeNode* topNode)
1340 {
1341 PHNodeIterator iter(topNode);
1342
1343 PHCompositeNode* dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
1344
1345 if (!dstNode)
1346 {
1347 std::cerr << "DST node is missing, quitting" << std::endl;
1348 throw std::runtime_error("Failed to find DST node in PHActsTrkFitter::createNodes");
1349 }
1350
1351 PHNodeIterator dstIter(topNode);
1352 PHCompositeNode* svtxNode = dynamic_cast<PHCompositeNode*>(dstIter.findFirst("PHCompositeNode", "SVTX"));
1353 if (!svtxNode)
1354 {
1355 svtxNode = new PHCompositeNode("SVTX");
1356 dstNode->addNode(svtxNode);
1357 }
1358
1359 m_trackmap = findNode::getClass<SvtxTrackMap>(topNode, "HelicalFitterTrackMap");
1360 if (!m_trackmap)
1361 {
1362 m_trackmap = new SvtxTrackMap_v2;
1363 PHIODataNode<PHObject>* node = new PHIODataNode<PHObject>(m_trackmap, "HelicalFitterTrackMap", "PHObject");
1364 svtxNode->addNode(node);
1365 }
1366
1367 m_alignmentmap = findNode::getClass<SvtxAlignmentStateMap>(topNode, "HelicalFitterAlignmentStateMap");
1368 if (!m_alignmentmap)
1369 {
1370 m_alignmentmap = new SvtxAlignmentStateMap_v1;
1371 PHIODataNode<PHObject>* node = new PHIODataNode<PHObject>(m_alignmentmap, "HelicalFitterAlignmentStateMap", "PHObject");
1372 svtxNode->addNode(node);
1373 }
1374
1375 return Fun4AllReturnCodes::EVENT_OK;
1376 }
1377 int HelicalFitter::GetNodes(PHCompositeNode* topNode)
1378 {
1379
1380
1381
1382
1383 _track_map_silicon = findNode::getClass<TrackSeedContainer>(topNode, _silicon_track_map_name);
1384 if (!_track_map_silicon && (fitsilicon || fitfulltrack))
1385 {
1386 cerr << PHWHERE << " ERROR: Can't find SiliconTrackSeedContainer " << endl;
1387 return Fun4AllReturnCodes::ABORTEVENT;
1388 }
1389
1390 _track_map_tpc = findNode::getClass<TrackSeedContainer>(topNode, _track_map_name);
1391 if (!_track_map_tpc && (fittpc || fitfulltrack))
1392 {
1393 cerr << PHWHERE << " ERROR: Can't find " << _track_map_name.c_str() << endl;
1394 return Fun4AllReturnCodes::ABORTEVENT;
1395 }
1396
1397 _cluster_map = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
1398 if (!_cluster_map)
1399 {
1400 std::cout << PHWHERE << " ERROR: Can't find node TRKR_CLUSTER" << std::endl;
1401 return Fun4AllReturnCodes::ABORTEVENT;
1402 }
1403
1404 _tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
1405 if (!_tGeometry)
1406 {
1407 std::cout << PHWHERE << "Error, can't find acts tracking geometry" << std::endl;
1408 return Fun4AllReturnCodes::ABORTEVENT;
1409 }
1410
1411 m_vertexmap = findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap");
1412 if (!m_vertexmap)
1413 {
1414 std::cout << PHWHERE << " ERROR: Can't find node SvtxVertexMap" << std::endl;
1415
1416 }
1417
1418
1419 m_globalPositionWrapper.loadNodes(topNode);
1420
1421 return Fun4AllReturnCodes::EVENT_OK;
1422 }
1423
1424 Acts::Vector3 HelicalFitter::get_helix_pca(std::vector<float>& fitpars, const Acts::Vector3& global)
1425 {
1426 return TrackFitUtils::get_helix_pca(fitpars, global);
1427 }
1428
1429 Acts::Vector3 HelicalFitter::getPCALinePoint(const Acts::Vector3& global, const Acts::Vector3& tangent, const Acts::Vector3& posref)
1430 {
1431
1432
1433
1434
1435 Acts::Vector3 pca = posref + ((global - posref).dot(tangent)) * tangent;
1436
1437 return pca;
1438 }
1439
1440 float HelicalFitter::convertTimeToZ(TrkrDefs::cluskey cluster_key, TrkrCluster* cluster)
1441 {
1442
1443 double const drift_velocity = _tGeometry->get_drift_velocity();
1444 double const zdriftlength = cluster->getLocalY() * drift_velocity;
1445 double const surfCenterZ = 52.89;
1446 double zloc = surfCenterZ - zdriftlength;
1447 unsigned int const side = TpcDefs::getSide(cluster_key);
1448 if (side == 0)
1449 {
1450 zloc = -zloc;
1451 }
1452 float const z = zloc;
1453
1454 return z;
1455 }
1456
1457 void HelicalFitter::makeTpcGlobalCorrections(TrkrDefs::cluskey cluster_key, short int crossing, Acts::Vector3& global)
1458 {
1459
1460 unsigned int const side = TpcDefs::getSide(cluster_key);
1461 global.z() = m_clusterCrossingCorrection.correctZ(global.z(), side, crossing);
1462
1463
1464 global = m_globalPositionWrapper.applyDistortionCorrections(global);
1465 }
1466
1467 void HelicalFitter::getTrackletClusters(TrackSeed* tracklet, std::vector<Acts::Vector3>& global_vec, std::vector<TrkrDefs::cluskey>& cluskey_vec)
1468 {
1469 getTrackletClusterList(tracklet, cluskey_vec);
1470
1471 TrackFitUtils::getTrackletClusters(_tGeometry, _cluster_map, global_vec, cluskey_vec);
1472 }
1473
1474 void HelicalFitter::getTrackletClusterList(TrackSeed* tracklet, std::vector<TrkrDefs::cluskey>& cluskey_vec)
1475 {
1476 for (auto clusIter = tracklet->begin_cluster_keys();
1477 clusIter != tracklet->end_cluster_keys();
1478 ++clusIter)
1479 {
1480 auto key = *clusIter;
1481 auto cluster = _cluster_map->findCluster(key);
1482 if (!cluster)
1483 {
1484 std::cout << PHWHERE << "Failed to get cluster with key " << key << std::endl;
1485 continue;
1486 }
1487
1488
1489 auto surf = _tGeometry->maps().getSurface(key, cluster);
1490 if (!surf)
1491 {
1492 continue;
1493 }
1494
1495
1496 unsigned int const layer = TrkrDefs::getLayer(key);
1497 if (layer == 7 || layer == 22 || layer == 23 || layer == 38 || layer == 39)
1498 {
1499 continue;
1500 }
1501
1502
1503
1504
1505
1506
1507
1508 cluskey_vec.push_back(key);
1509
1510 }
1511 }
1512
1513 std::vector<float> HelicalFitter::fitClusters(std::vector<Acts::Vector3>& global_vec, std::vector<TrkrDefs::cluskey> cluskey_vec)
1514 {
1515 return TrackFitUtils::fitClusters(global_vec, std::move(cluskey_vec), use_intt_zfit);
1516 }
1517
1518 Acts::Vector2 HelicalFitter::getClusterError(TrkrCluster* cluster, TrkrDefs::cluskey cluskey, Acts::Vector3& global)
1519 {
1520 Acts::Vector2 clus_sigma(0, 0);
1521
1522 double const clusRadius = sqrt(global[0] * global[0] + global[1] * global[1]);
1523 auto para_errors = _ClusErrPara.get_clusterv5_modified_error(cluster, clusRadius, cluskey);
1524 double const phierror = sqrt(para_errors.first);
1525 double const zerror = sqrt(para_errors.second);
1526 clus_sigma(1) = zerror;
1527 clus_sigma(0) = phierror;
1528
1529 return clus_sigma;
1530 }
1531
1532
1533 void HelicalFitter::getLocalDerivativesXY(const Surface& surf, const Acts::Vector3& global, const std::vector<float>& fitpars, float lcl_derivativeX[5], float lcl_derivativeY[5], unsigned int layer)
1534 {
1535
1536 std::vector<float> temp_fitpars;
1537
1538 std::vector<float> fitpars_delta;
1539 fitpars_delta.push_back(0.1);
1540 fitpars_delta.push_back(0.1);
1541 fitpars_delta.push_back(0.1);
1542 fitpars_delta.push_back(0.1);
1543 fitpars_delta.push_back(0.1);
1544
1545 temp_fitpars.reserve(fitpars.size());
1546 for (float const fitpar : fitpars)
1547 {
1548 temp_fitpars.push_back(fitpar);
1549 }
1550
1551
1552 if (Verbosity() > 1)
1553 {
1554 std::cout << "Call get_helix_tangent for best fit fitpars" << std::endl;
1555 }
1556 std::pair<Acts::Vector3, Acts::Vector3> const tangent = get_helix_tangent(fitpars, global);
1557
1558 Acts::Vector3 projX(0, 0, 0), projY(0, 0, 0);
1559 get_projectionXY(surf, tangent, projX, projY);
1560
1561 Acts::Vector3 const intersection = get_helix_surface_intersection(surf, temp_fitpars, global);
1562
1563
1564 for (unsigned int ip = 0; ip < fitpars.size(); ++ip)
1565 {
1566 Acts::Vector3 intersection_delta[2];
1567 for (int ipm = 0; ipm < 2; ++ipm)
1568 {
1569 temp_fitpars[ip] = fitpars[ip];
1570 float const deltapm = pow(-1.0, ipm);
1571 temp_fitpars[ip] += deltapm * fitpars_delta[ip];
1572
1573 Acts::Vector3 const temp_intersection = get_helix_surface_intersection(surf, temp_fitpars, global);
1574 intersection_delta[ipm] = temp_intersection - intersection;
1575 }
1576 Acts::Vector3 average_intersection_delta = (intersection_delta[0] - intersection_delta[1]) / (2 * fitpars_delta[ip]);
1577
1578 if (Verbosity() > 1)
1579 {
1580 std::cout << " average_intersection_delta / delta " << average_intersection_delta(0) << " " << average_intersection_delta(1) << " " << average_intersection_delta(2) << std::endl;
1581 }
1582
1583
1584
1585 lcl_derivativeX[ip] = average_intersection_delta.dot(projX);
1586 lcl_derivativeY[ip] = average_intersection_delta.dot(projY);
1587 if (Verbosity() > 1)
1588 {
1589 std::cout << " layer " << layer << " ip " << ip << " derivativeX " << lcl_derivativeX[ip] << " "
1590 << " derivativeY " << lcl_derivativeY[ip] << std::endl;
1591 }
1592
1593 temp_fitpars[ip] = fitpars[ip];
1594 }
1595 }
1596
1597 void HelicalFitter::getLocalDerivativesZeroFieldXY(const Surface& surf, const Acts::Vector3& global, const std::vector<float>& fitpars, float lcl_derivativeX[5], float lcl_derivativeY[5], unsigned int layer)
1598 {
1599
1600
1601
1602
1603
1604 std::vector<float> temp_fitpars;
1605
1606 std::vector<float> fitpars_delta;
1607 fitpars_delta.push_back(0.1);
1608 fitpars_delta.push_back(0.1);
1609 fitpars_delta.push_back(0.1);
1610 fitpars_delta.push_back(0.1);
1611
1612 temp_fitpars.reserve(fitpars.size());
1613 for (float const fitpar : fitpars)
1614 {
1615 temp_fitpars.push_back(fitpar);
1616 }
1617
1618
1619 if (Verbosity() > 1)
1620 {
1621 std::cout << "Call get_line to get tangent for ZF fitpars" << std::endl;
1622 }
1623
1624 std::pair<Acts::Vector3, Acts::Vector3> const tangent = get_line_tangent(fitpars, global);
1625
1626 Acts::Vector3 projX(0, 0, 0), projY(0, 0, 0);
1627 get_projectionXY(surf, tangent, projX, projY);
1628
1629 Acts::Vector3 const intersection = get_line_surface_intersection(surf, temp_fitpars);
1630
1631
1632 for (unsigned int ip = 0; ip < fitpars.size(); ++ip)
1633 {
1634 Acts::Vector3 intersection_delta[2];
1635 for (int ipm = 0; ipm < 2; ++ipm)
1636 {
1637 temp_fitpars[ip] = fitpars[ip];
1638 float const deltapm = pow(-1.0, ipm);
1639 temp_fitpars[ip] += deltapm * fitpars_delta[ip];
1640
1641 Acts::Vector3 const temp_intersection = get_line_surface_intersection(surf, temp_fitpars);
1642 intersection_delta[ipm] = temp_intersection - intersection;
1643 }
1644 Acts::Vector3 average_intersection_delta = (intersection_delta[0] - intersection_delta[1]) / (2 * fitpars_delta[ip]);
1645
1646 if (Verbosity() > 1)
1647 {
1648 std::cout << " average_intersection_delta / delta " << average_intersection_delta(0) << " " << average_intersection_delta(1) << " " << average_intersection_delta(2) << std::endl;
1649 }
1650
1651
1652
1653 lcl_derivativeX[ip] = average_intersection_delta.dot(projX);
1654 lcl_derivativeY[ip] = average_intersection_delta.dot(projY);
1655 if (Verbosity() > 1)
1656 {
1657 std::cout << " layer " << layer << " ip " << ip << " derivativeX " << lcl_derivativeX[ip] << " "
1658 << " derivativeY " << lcl_derivativeY[ip] << std::endl;
1659 }
1660
1661 temp_fitpars[ip] = fitpars[ip];
1662 }
1663 }
1664
1665 void HelicalFitter::getLocalVtxDerivativesXY(SvtxTrack& track, const Acts::Vector3& event_vtx, const std::vector<float>& fitpars, float lcl_derivativeX[5], float lcl_derivativeY[5])
1666 {
1667
1668 std::vector<float> temp_fitpars;
1669 Acts::Vector3 const track_vtx(track.get_x(), track.get_y(), track.get_z());
1670
1671 std::vector<float> fitpars_delta;
1672 fitpars_delta.push_back(0.1);
1673 fitpars_delta.push_back(0.1);
1674 fitpars_delta.push_back(0.1);
1675 fitpars_delta.push_back(0.1);
1676 fitpars_delta.push_back(0.1);
1677
1678 temp_fitpars.reserve(fitpars.size());
1679 for (float const fitpar : fitpars)
1680 {
1681 temp_fitpars.push_back(fitpar);
1682 }
1683
1684
1685 if (Verbosity() > 1)
1686 {
1687 std::cout << "Get tangent from track momentum vector" << std::endl;
1688 }
1689
1690 Acts::Vector3 const perigeeNormal(track.get_px(), track.get_py(), track.get_pz());
1691
1692
1693 for (unsigned int ip = 0; ip < fitpars.size(); ++ip)
1694 {
1695 Acts::Vector3 localPerturb[2];
1696 Acts::Vector3 paperPerturb[2];
1697
1698 for (int ipm = 0; ipm < 2; ++ipm)
1699 {
1700 temp_fitpars[ip] = fitpars[ip];
1701 float const deltapm = pow(-1.0, ipm);
1702 temp_fitpars[ip] += deltapm * fitpars_delta[ip];
1703
1704 Acts::Vector3 const temp_track_vtx = get_helix_vtx(event_vtx, temp_fitpars);
1705 paperPerturb[ipm] = temp_track_vtx;
1706
1707
1708 Acts::Vector3 const localtemp_track_vtx = globalvtxToLocalvtx(track, event_vtx, temp_track_vtx);
1709 localPerturb[ipm] = localtemp_track_vtx;
1710
1711 if (Verbosity() > 1)
1712 {
1713 std::cout << "vtx local parameter " << ip << " with ipm " << ipm << " deltapm " << deltapm << " :" << std::endl;
1714 std::cout << " fitpars " << fitpars[ip] << " temp_fitpars " << temp_fitpars[ip] << std::endl;
1715 std::cout << " localtmp_track_vtx: " << localtemp_track_vtx << std::endl;
1716 }
1717 }
1718
1719 Acts::Vector3 projX(0, 0, 0), projY(0, 0, 0);
1720 get_projectionVtxXY(track, event_vtx, projX, projY);
1721
1722 Acts::Vector3 const average_vtxX = (paperPerturb[0] - paperPerturb[1]) / (2 * fitpars_delta[ip]);
1723 Acts::Vector3 const average_vtxY = (paperPerturb[0] - paperPerturb[1]) / (2 * fitpars_delta[ip]);
1724
1725
1726
1727
1728 lcl_derivativeX[ip] = average_vtxX.dot(projX);
1729 lcl_derivativeY[ip] = average_vtxY.dot(projY);
1730
1731 temp_fitpars[ip] = fitpars[ip];
1732 }
1733 }
1734
1735 void HelicalFitter::getLocalVtxDerivativesZeroFieldXY(SvtxTrack& track, const Acts::Vector3& event_vtx, const std::vector<float>& fitpars, float lcl_derivativeX[5], float lcl_derivativeY[5])
1736 {
1737
1738 std::vector<float> temp_fitpars;
1739 Acts::Vector3 const track_vtx(track.get_x(), track.get_y(), track.get_z());
1740
1741 std::vector<float> fitpars_delta;
1742 fitpars_delta.push_back(0.1);
1743 fitpars_delta.push_back(0.1);
1744 fitpars_delta.push_back(0.1);
1745 fitpars_delta.push_back(0.1);
1746
1747 temp_fitpars.reserve(fitpars.size());
1748 for (float const fitpar : fitpars)
1749 {
1750 temp_fitpars.push_back(fitpar);
1751 }
1752
1753 Acts::Vector3 const perigeeNormal(track.get_px(), track.get_py(), track.get_pz());
1754
1755
1756 for (unsigned int ip = 0; ip < fitpars.size(); ++ip)
1757 {
1758 Acts::Vector3 localPerturb[2];
1759 Acts::Vector3 paperPerturb[2];
1760
1761 for (int ipm = 0; ipm < 2; ++ipm)
1762 {
1763 temp_fitpars[ip] = fitpars[ip];
1764 float const deltapm = pow(-1.0, ipm);
1765 temp_fitpars[ip] += deltapm * fitpars_delta[ip];
1766
1767 Acts::Vector3 const temp_track_vtx = get_line_vtx(event_vtx, temp_fitpars);
1768 paperPerturb[ipm] = temp_track_vtx;
1769
1770
1771 Acts::Vector3 const localtemp_track_vtx = globalvtxToLocalvtx(track, event_vtx, temp_track_vtx);
1772 localPerturb[ipm] = localtemp_track_vtx;
1773
1774 if (Verbosity() > 1)
1775 {
1776 std::cout << "vtx local parameter " << ip << " with ipm " << ipm << " deltapm " << deltapm << " :" << std::endl;
1777 std::cout << " fitpars " << fitpars[ip] << " temp_fitpars " << temp_fitpars[ip] << std::endl;
1778 std::cout << " localtmp_track_vtx: " << localtemp_track_vtx << std::endl;
1779 }
1780 }
1781
1782
1783 Acts::Vector3 projX(0, 0, 0), projY(0, 0, 0);
1784 get_projectionVtxXY(track, event_vtx, projX, projY);
1785
1786 Acts::Vector3 const average_vtxX = (paperPerturb[0] - paperPerturb[1]) / (2 * fitpars_delta[ip]);
1787 Acts::Vector3 const average_vtxY = (paperPerturb[0] - paperPerturb[1]) / (2 * fitpars_delta[ip]);
1788
1789
1790
1791
1792 lcl_derivativeX[ip] = average_vtxX.dot(projX);
1793 lcl_derivativeY[ip] = average_vtxY.dot(projY);
1794
1795 temp_fitpars[ip] = fitpars[ip];
1796 }
1797 }
1798
1799 void HelicalFitter::getGlobalDerivativesXY(const Surface& surf, const Acts::Vector3& global, const Acts::Vector3& fitpoint, const std::vector<float>& fitpars, float glbl_derivativeX[6], float glbl_derivativeY[6], unsigned int layer)
1800 {
1801
1802 std::pair<Acts::Vector3, Acts::Vector3> tangent;
1803 if (straight_line_fit)
1804 {
1805 tangent = get_line_tangent(fitpars, global);
1806 }
1807 else
1808 {
1809 tangent = get_helix_tangent(fitpars, global);
1810 }
1811
1812 Acts::Vector3 projX(0, 0, 0), projY(0, 0, 0);
1813 get_projectionXY(surf, tangent, projX, projY);
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838 Acts::Vector3 const unitx(1, 0, 0);
1839 Acts::Vector3 const unity(0, 1, 0);
1840 Acts::Vector3 const unitz(0, 0, 1);
1841
1842 glbl_derivativeX[3] = unitx.dot(projX);
1843 glbl_derivativeX[4] = unity.dot(projX);
1844 glbl_derivativeX[5] = unitz.dot(projX);
1845
1846 glbl_derivativeY[3] = unitx.dot(projY);
1847 glbl_derivativeY[4] = unity.dot(projY);
1848 glbl_derivativeY[5] = unitz.dot(projY);
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863 Acts::Vector3 const sensorCenter = surf->center(_tGeometry->geometry().getGeoContext()) / Acts::UnitConstants::cm;
1864 Acts::Vector3 const OM = fitpoint - sensorCenter;
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876 glbl_derivativeX[0] = (unitx.cross(OM)).dot(projX);
1877 glbl_derivativeX[1] = (unity.cross(OM)).dot(projX);
1878 glbl_derivativeX[2] = (unitz.cross(OM)).dot(projX);
1879
1880 glbl_derivativeY[0] = (unitx.cross(OM)).dot(projY);
1881 glbl_derivativeY[1] = (unity.cross(OM)).dot(projY);
1882 glbl_derivativeY[2] = (unitz.cross(OM)).dot(projY);
1883
1884 if (Verbosity() > 1)
1885 {
1886 for (int ip = 0; ip < 6; ++ip)
1887 {
1888 std::cout << " layer " << layer << " ip " << ip
1889 << " glbl_derivativeX " << glbl_derivativeX[ip] << " "
1890 << " glbl_derivativeY " << glbl_derivativeY[ip] << std::endl;
1891 }
1892 }
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904 }
1905
1906 void HelicalFitter::getGlobalVtxDerivativesXY(SvtxTrack& track, const Acts::Vector3& event_vtx, float glbl_derivativeX[3], float glbl_derivativeY[3])
1907 {
1908 Acts::Vector3 const unitx(1, 0, 0);
1909 Acts::Vector3 const unity(0, 1, 0);
1910 Acts::Vector3 const unitz(0, 0, 1);
1911
1912 Acts::Vector3 const track_vtx(track.get_x(), track.get_y(), track.get_z());
1913 Acts::Vector3 const mom(track.get_px(), track.get_py(), track.get_pz());
1914
1915
1916 Acts::Vector3 projX(0, 0, 0), projY(0, 0, 0);
1917 get_projectionVtxXY(track, event_vtx, projX, projY);
1918
1919
1920 glbl_derivativeX[0] = unitx.dot(projX);
1921 glbl_derivativeX[1] = unity.dot(projX);
1922 glbl_derivativeX[2] = unitz.dot(projX);
1923 glbl_derivativeY[0] = unitx.dot(projY);
1924 glbl_derivativeY[1] = unity.dot(projY);
1925 glbl_derivativeY[2] = unitz.dot(projY);
1926
1927
1928
1929
1930
1931
1932
1933 for (int i = 0; i < 3; ++i)
1934 {
1935 glbl_derivativeX[i] *= -1.0;
1936 glbl_derivativeY[i] *= -1.0;
1937 }
1938 }
1939
1940 void HelicalFitter::get_projectionXY(const Surface& surf, const std::pair<Acts::Vector3, Acts::Vector3>& tangent, Acts::Vector3& projX, Acts::Vector3& projY)
1941 {
1942
1943 Acts::Vector3 const tanvec = tangent.second;
1944
1945 Acts::Vector3 const sensorCenter = surf->center(_tGeometry->geometry().getGeoContext()) / Acts::UnitConstants::cm;
1946
1947
1948
1949
1950 Acts::Vector3 const Z = -surf->normal(_tGeometry->geometry().getGeoContext(), Acts::Vector3(1, 1, 1), Acts::Vector3(1, 1, 1));
1951
1952
1953 Acts::Vector3 const xloc(1.0, 0.0, 0.0);
1954 Acts::Vector3 xglob = surf->transform(_tGeometry->geometry().getGeoContext()) * (xloc * Acts::UnitConstants::cm);
1955 xglob /= Acts::UnitConstants::cm;
1956 Acts::Vector3 const yloc(0.0, 1.0, 0.0);
1957 Acts::Vector3 yglob = surf->transform(_tGeometry->geometry().getGeoContext()) * (yloc * Acts::UnitConstants::cm);
1958 yglob /= Acts::UnitConstants::cm;
1959
1960 Acts::Vector3 const X = (xglob - sensorCenter) / (xglob - sensorCenter).norm();
1961 Acts::Vector3 const Y = (yglob - sensorCenter) / (yglob - sensorCenter).norm();
1962
1963
1964
1965
1966 projX = X - (tanvec.dot(X) / tanvec.dot(Z)) * Z;
1967 projY = Y - (tanvec.dot(Y) / tanvec.dot(Z)) * Z;
1968
1969 if(Verbosity() > 1)
1970 {
1971 std::cout << " tanvec: " << std::endl << tanvec << std::endl;
1972 std::cout << " X: " << std::endl << X << std::endl;
1973 std::cout << " Y: " << std::endl << Y << std::endl;
1974 std::cout << " Z: " << std::endl << Z << std::endl;
1975
1976 std::cout << " projX: " << std::endl << projX << std::endl;
1977 std::cout << " projY: " << std::endl << projY << std::endl;
1978 }
1979
1980 return;
1981 }
1982
1983 void HelicalFitter::get_projectionVtxXY(SvtxTrack& track, const Acts::Vector3& event_vtx, Acts::Vector3& projX, Acts::Vector3& projY)
1984 {
1985 Acts::Vector3 tanvec(track.get_px(), track.get_py(), track.get_pz());
1986 Acts::Vector3 normal(track.get_px(), track.get_py(), 0);
1987
1988 tanvec /= tanvec.norm();
1989 normal /= normal.norm();
1990
1991
1992 Acts::Vector3 const xloc(1.0, 0.0, 0.0);
1993 Acts::Vector3 const yloc(0.0, 0.0, 1.0);
1994 Acts::Vector3 const xglob = localvtxToGlobalvtx(track, event_vtx, xloc);
1995 Acts::Vector3 const yglob = yloc + event_vtx;
1996 Acts::Vector3 const X = (xglob - event_vtx) / (xglob - event_vtx).norm();
1997 Acts::Vector3 const Y = (yglob - event_vtx) / (yglob - event_vtx).norm();
1998
1999
2000 projX = X - (tanvec.dot(X) / tanvec.dot(normal)) * normal;
2001 projY = Y - (tanvec.dot(Y) / tanvec.dot(normal)) * normal;
2002 return;
2003 }
2004
2005 unsigned int HelicalFitter::addSiliconClusters(std::vector<float>& fitpars, std::vector<Acts::Vector3>& global_vec, std::vector<TrkrDefs::cluskey>& cluskey_vec)
2006 {
2007 return TrackFitUtils::addClusters(fitpars, dca_cut, _tGeometry, _cluster_map, global_vec, cluskey_vec, 0, 6);
2008 }
2009 bool HelicalFitter::is_vertex_param_fixed(unsigned int param)
2010 {
2011 bool ret = false;
2012 auto it = fixed_vertex_params.find(param);
2013 if (it != fixed_vertex_params.end())
2014 {
2015 ret = true;
2016 }
2017 return ret;
2018 }
2019 bool HelicalFitter::is_intt_layer_fixed(unsigned int layer)
2020 {
2021 bool ret = false;
2022 auto it = fixed_intt_layers.find(layer);
2023 if (it != fixed_intt_layers.end())
2024 {
2025 ret = true;
2026 }
2027
2028 return ret;
2029 }
2030
2031 bool HelicalFitter::is_mvtx_layer_fixed(unsigned int layer, unsigned int clamshell)
2032 {
2033 bool ret = false;
2034
2035 std::pair const pair = std::make_pair(layer, clamshell);
2036 auto it = fixed_mvtx_layers.find(pair);
2037 if (it != fixed_mvtx_layers.end())
2038 {
2039 ret = true;
2040 }
2041 return ret;
2042 }
2043
2044 void HelicalFitter::set_intt_layer_fixed(unsigned int layer)
2045 {
2046 fixed_intt_layers.insert(layer);
2047 }
2048
2049 void HelicalFitter::set_mvtx_layer_fixed(unsigned int layer, unsigned int clamshell)
2050 {
2051 fixed_mvtx_layers.insert(std::make_pair(layer, clamshell));
2052 }
2053
2054 bool HelicalFitter::is_layer_param_fixed(unsigned int layer, unsigned int param)
2055 {
2056 bool ret = false;
2057 std::pair<unsigned int, unsigned int> const pair = std::make_pair(layer, param);
2058 auto it = fixed_layer_params.find(pair);
2059 if (it != fixed_layer_params.end())
2060 {
2061 ret = true;
2062 }
2063
2064 return ret;
2065 }
2066
2067 void HelicalFitter::set_layer_param_fixed(unsigned int layer, unsigned int param)
2068 {
2069 std::pair<unsigned int, unsigned int> const pair = std::make_pair(layer, param);
2070 fixed_layer_params.insert(pair);
2071 }
2072
2073 void HelicalFitter::set_tpc_sector_fixed(unsigned int region, unsigned int sector, unsigned int side)
2074 {
2075
2076 unsigned int const subsector = region * 24 + side * 12 + sector;
2077 fixed_sectors.insert(subsector);
2078 }
2079
2080 bool HelicalFitter::is_tpc_sector_fixed(unsigned int layer, unsigned int sector, unsigned int side)
2081 {
2082 bool ret = false;
2083 unsigned int const region = AlignmentDefs::getTpcRegion(layer);
2084 unsigned int const subsector = region * 24 + side * 12 + sector;
2085 auto it = fixed_sectors.find(subsector);
2086 if (it != fixed_sectors.end())
2087 {
2088 ret = true;
2089 }
2090
2091 return ret;
2092 }
2093
2094 void HelicalFitter::correctTpcGlobalPositions(std::vector<Acts::Vector3> global_vec, const std::vector<TrkrDefs::cluskey> &cluskey_vec)
2095 {
2096 for (unsigned int iclus = 0; iclus < cluskey_vec.size(); ++iclus)
2097 {
2098 auto cluskey = cluskey_vec[iclus];
2099 auto global = global_vec[iclus];
2100 const unsigned int trkrId = TrkrDefs::getTrkrId(cluskey);
2101 if (trkrId == TrkrDefs::tpcId)
2102 {
2103
2104 int const crossing = 0;
2105 makeTpcGlobalCorrections(cluskey, crossing, global);
2106 global_vec[iclus] = global;
2107 }
2108 }
2109 }
2110
2111 float HelicalFitter::getVertexResidual(Acts::Vector3 vtx)
2112 {
2113 float const phi = atan2(vtx(1), vtx(0));
2114 float const r = vtx(0) / cos(phi);
2115 float const test_r = sqrt(vtx(0) * vtx(0) + vtx(1) * vtx(1));
2116
2117 if (Verbosity() > 1)
2118 {
2119 std::cout << "my method position: " << vtx << std::endl;
2120 std::cout << "r " << r << " phi: " << phi * 180 / M_PI << " test_r" << test_r << std::endl;
2121 }
2122 return r;
2123 }
2124
2125 void HelicalFitter::get_dca(SvtxTrack& track, float& dca3dxy, float& dca3dz, float& dca3dxysigma, float& dca3dzsigma, const Acts::Vector3& event_vertex)
2126 {
2127
2128 dca3dxy = NAN;
2129 Acts::Vector3 track_vtx(track.get_x(), track.get_y(), track.get_z());
2130 Acts::Vector3 const mom(track.get_px(), track.get_py(), track.get_pz());
2131
2132 track_vtx -= event_vertex;
2133
2134 Acts::ActsSquareMatrix<3> posCov;
2135 for (int i = 0; i < 3; ++i)
2136 {
2137 for (int j = 0; j < 3; ++j)
2138 {
2139 posCov(i, j) = track.get_error(i, j);
2140 }
2141 }
2142
2143 Acts::Vector3 r = mom.cross(Acts::Vector3(0., 0., 1.));
2144
2145 float phi = atan2(r(1), r(0));
2146 Acts::RotationMatrix3 rot;
2147 Acts::RotationMatrix3 rot_T;
2148 phi *= -1;
2149 rot(0, 0) = cos(phi);
2150 rot(0, 1) = -sin(phi);
2151 rot(0, 2) = 0;
2152 rot(1, 0) = sin(phi);
2153 rot(1, 1) = cos(phi);
2154 rot(1, 2) = 0;
2155 rot(2, 0) = 0;
2156 rot(2, 1) = 0;
2157 rot(2, 2) = 1;
2158 rot_T = rot.transpose();
2159
2160 Acts::Vector3 pos_R = rot * track_vtx;
2161 Acts::ActsSquareMatrix<3> rotCov = rot * posCov * rot_T;
2162 dca3dxy = pos_R(0);
2163 dca3dz = pos_R(2);
2164 dca3dxysigma = sqrt(rotCov(0, 0));
2165 dca3dzsigma = sqrt(rotCov(2, 2));
2166
2167 if (Verbosity() > 1)
2168 {
2169 std::cout << " Helix: momentum.cross(z): " << r << " phi: " << phi * 180 / M_PI << std::endl;
2170 std::cout << "dca3dxy " << dca3dxy << " dca3dz: " << dca3dz << " pos_R(1): " << pos_R(1) << " dca3dxysigma " << dca3dxysigma << " dca3dzsigma " << dca3dzsigma << std::endl;
2171 }
2172 }
2173
2174 void HelicalFitter::get_dca_zero_field(SvtxTrack& track, float& dca3dxy, float& dca3dz, float& dca3dxysigma, float& dca3dzsigma, const Acts::Vector3& event_vertex)
2175 {
2176 dca3dxy = NAN;
2177
2178 Acts::Vector3 track_vtx(track.get_x(), track.get_y(), track.get_z());
2179 track_vtx -= event_vertex;
2180
2181
2182
2183 Acts::Vector3 const mom(track.get_px(), track.get_py(), track.get_pz());
2184
2185 Acts::ActsSquareMatrix<3> posCov;
2186 for (int i = 0; i < 3; ++i)
2187 {
2188 for (int j = 0; j < 3; ++j)
2189 {
2190 posCov(i, j) = track.get_error(i, j);
2191 }
2192 }
2193
2194 Acts::Vector3 r = mom.cross(Acts::Vector3(0., 0., 1.));
2195
2196 float phi = atan2(r(1), r(0));
2197 Acts::RotationMatrix3 rot;
2198 Acts::RotationMatrix3 rot_T;
2199 phi *= -1;
2200 rot(0, 0) = cos(phi);
2201 rot(0, 1) = -sin(phi);
2202 rot(0, 2) = 0;
2203 rot(1, 0) = sin(phi);
2204 rot(1, 1) = cos(phi);
2205 rot(1, 2) = 0;
2206 rot(2, 0) = 0;
2207 rot(2, 1) = 0;
2208 rot(2, 2) = 1;
2209 rot_T = rot.transpose();
2210
2211 Acts::Vector3 pos_R = rot * track_vtx;
2212 Acts::ActsSquareMatrix<3> rotCov = rot * posCov * rot_T;
2213 dca3dxy = pos_R(0);
2214 dca3dz = pos_R(2);
2215 dca3dxysigma = sqrt(rotCov(0, 0));
2216 dca3dzsigma = sqrt(rotCov(2, 2));
2217
2218 if (Verbosity() > 1)
2219 {
2220 std::cout << " Zero Field: momentum.cross(z): " << r << " phi (deg): " << phi * 180 / M_PI << std::endl;
2221 std::cout << "dca3dxy " << dca3dxy << " dca3dz: " << dca3dz << " pos_R(1): " << pos_R(1) << " dca3dxysigma " << dca3dxysigma << " dca3dzsigma " << dca3dzsigma << std::endl;
2222 }
2223 }
2224
2225 Acts::Vector3 HelicalFitter::globalvtxToLocalvtx(SvtxTrack& track, const Acts::Vector3& event_vertex)
2226 {
2227 Acts::Vector3 track_vtx(track.get_x(), track.get_y(), track.get_z());
2228 Acts::Vector3 const mom(track.get_px(), track.get_py(), track.get_pz());
2229 track_vtx -= event_vertex;
2230
2231 Acts::Vector3 r = mom.cross(Acts::Vector3(0., 0., 1.));
2232 float phi = atan2(r(1), r(0));
2233 Acts::RotationMatrix3 rot;
2234 Acts::RotationMatrix3 rot_T;
2235 phi *= -1;
2236 rot(0, 0) = cos(phi);
2237 rot(0, 1) = -sin(phi);
2238 rot(0, 2) = 0;
2239 rot(1, 0) = sin(phi);
2240 rot(1, 1) = cos(phi);
2241 rot(1, 2) = 0;
2242 rot(2, 0) = 0;
2243 rot(2, 1) = 0;
2244 rot(2, 2) = 1;
2245 rot_T = rot.transpose();
2246
2247 Acts::Vector3 pos_R = rot * track_vtx;
2248
2249 if (Verbosity() > 1)
2250 {
2251 std::cout << " momentum X z: " << r << " phi: " << phi * 180 / M_PI << std::endl;
2252 std::cout << " pos_R(0): " << pos_R(0) << " pos_R(1): " << pos_R(1) << std::endl;
2253 }
2254 return pos_R;
2255 }
2256
2257 Acts::Vector3 HelicalFitter::globalvtxToLocalvtx(SvtxTrack& track, const Acts::Vector3& event_vertex, Acts::Vector3 PCA)
2258 {
2259 Acts::Vector3 const mom(track.get_px(), track.get_py(), track.get_pz());
2260 PCA -= event_vertex;
2261
2262 Acts::Vector3 r = mom.cross(Acts::Vector3(0., 0., 1.));
2263 float phi = atan2(r(1), r(0));
2264 Acts::RotationMatrix3 rot;
2265 Acts::RotationMatrix3 rot_T;
2266 phi *= -1;
2267 rot(0, 0) = cos(phi);
2268 rot(0, 1) = -sin(phi);
2269 rot(0, 2) = 0;
2270 rot(1, 0) = sin(phi);
2271 rot(1, 1) = cos(phi);
2272 rot(1, 2) = 0;
2273 rot(2, 0) = 0;
2274 rot(2, 1) = 0;
2275 rot(2, 2) = 1;
2276 rot_T = rot.transpose();
2277
2278 Acts::Vector3 pos_R = rot * PCA;
2279
2280 if (Verbosity() > 1)
2281 {
2282 std::cout << " momentum X z: " << r << " phi: " << phi * 180 / M_PI << std::endl;
2283 std::cout << " pos_R(0): " << pos_R(0) << " pos_R(1): " << pos_R(1) << std::endl;
2284 }
2285 return pos_R;
2286 }
2287
2288 Acts::Vector3 HelicalFitter::localvtxToGlobalvtx(SvtxTrack& track, const Acts::Vector3& event_vtx, const Acts::Vector3& local)
2289 {
2290
2291 Acts::Vector3 const mom(track.get_px(), track.get_py(), track.get_pz());
2292
2293
2294
2295 Acts::Vector3 r = mom.cross(Acts::Vector3(0., 0., 1.));
2296 float const phi = atan2(r(1), r(0));
2297 Acts::RotationMatrix3 rot;
2298 Acts::RotationMatrix3 rot_T;
2299
2300 rot(0, 0) = cos(phi);
2301 rot(0, 1) = -sin(phi);
2302 rot(0, 2) = 0;
2303 rot(1, 0) = sin(phi);
2304 rot(1, 1) = cos(phi);
2305 rot(1, 2) = 0;
2306 rot(2, 0) = 0;
2307 rot(2, 1) = 0;
2308 rot(2, 2) = 1;
2309
2310 rot_T = rot.transpose();
2311
2312 Acts::Vector3 pos_R = rot * local;
2313 pos_R += event_vtx;
2314 if (Verbosity() > 1)
2315 {
2316 std::cout << " momentum X z: " << r << " phi: " << phi * 180 / M_PI << std::endl;
2317 std::cout << " pos_R(0): " << pos_R(0) << " pos_R(1): " << pos_R(1) << "pos_R(2): " << pos_R(2) << std::endl;
2318 }
2319 return pos_R;
2320 }