36 #include <Eigen/Dense>
90 { std::cout <<
"track pair map size " <<
_track_pair_map.size() << std::endl; }
96 for(
unsigned int ivtx = 0; ivtx < connected_tracks.size(); ++ivtx)
98 if(
Verbosity() > 1) std::cout <<
"process vertex " << ivtx << std::endl;
100 for(
auto it : connected_tracks[ivtx])
102 unsigned int id =
it;
104 if(
Verbosity() > 2) std::cout <<
" adding track " <<
id <<
" to vertex " << ivtx << std::endl;
111 if(
Verbosity() > 1) std::cout <<
" vertex " <<
it.first <<
" track " <<
it.second << std::endl;
124 auto ret = _vertex_track_map.equal_range(
it);
125 for (
auto cit=ret.first; cit!=ret.second; ++cit)
127 unsigned int trid = cit->second;
130 for(
int i = 0;
i < 3; ++
i)
131 for(
int j = 0;
j < 3; ++
j)
132 cov(
i,
j) = track->get_error(
i,
j);
138 avgCov /= sqrt(cov_wt);
141 std::cout <<
"Average covariance for vertex " <<
it <<
" is:" << std::endl;
142 std::cout << std::setprecision(8) << avgCov << std::endl;
149 if(_vertex_track_map.size() > 0)
152 for(
auto it : _vertex_set)
154 auto svtxVertex = std::make_unique<SvtxVertex_v2>();
156 svtxVertex->set_chisq(0.0);
157 svtxVertex->set_ndof(0);
158 svtxVertex->set_t0(0);
159 svtxVertex->set_id(
it);
161 auto ret = _vertex_track_map.equal_range(
it);
162 for (
auto cit=ret.first; cit!=ret.second; ++cit)
164 unsigned int trid = cit->second;
166 if(
Verbosity() > 1) std::cout <<
" vertex " <<
it <<
" insert track " << trid << std::endl;
167 svtxVertex->insert_track(trid);
172 svtxVertex->set_x(pos.x());
173 svtxVertex->set_y(pos.y());
174 svtxVertex->set_z(pos.z());
175 if(
Verbosity() > 1) std::cout <<
" vertex " <<
it <<
" insert pos.x " << pos.x() <<
" pos.y " << pos.y() <<
" pos.z " << pos.z() << std::endl;
178 for(
int i = 0;
i < 3; ++
i)
180 for(
int j = 0;
j < 3; ++
j)
182 svtxVertex->set_error(
i,
j, vtxCov(
i,
j));
194 for(
const auto& [trackkey, track] : *
_track_map)
196 auto vtxid = track->get_vertex_id();
202 float maxdz = std::numeric_limits<float>::max();
203 unsigned int newvtxid = std::numeric_limits<unsigned int>::max();
207 float dz = track->get_z() -
vertex->get_z();
215 track->set_vertex_id(newvtxid);
237 std::cerr <<
"DST Node missing, quitting" << std::endl;
238 throw std::runtime_error(
"failed to find DST node in PHActsInitialVertexFinder::createNodes");
250 _svtx_vertex_map = findNode::getClass<SvtxVertexMap>(topNode,
"SvtxVertexMap");
267 _track_map = findNode::getClass<SvtxTrackMap>(topNode,
"SvtxTrackMap");
270 std::cout <<
PHWHERE <<
" ERROR: Can't find SvtxTrackMap: " << std::endl;
284 auto id1 = tr1_it->first;
285 auto tr1 = tr1_it->second;
286 if(tr1->get_quality() >
_qual_cut)
continue;
289 unsigned int nmvtx = 0;
290 TrackSeed *siliconseed = tr1->get_silicon_seed();
303 if(
Verbosity() > 3) std::cout <<
" tr1 id " << id1 <<
" has nmvtx at least " << nmvtx << std::endl;
309 auto id2 = tr2_it->first;
310 auto tr2 = tr2_it->second;
311 if(tr2->get_quality() >
_qual_cut)
continue;
314 unsigned int nmvtx = 0;
315 TrackSeed *siliconseed = tr2->get_silicon_seed();
328 if(
Verbosity() > 3) std::cout <<
" tr2 id " << id2 <<
" has nmvtx at least " << nmvtx << std::endl;
332 if(
Verbosity() > 3) std::cout <<
"Check DCA for tracks " << id1 <<
" and " << id2 << std::endl;
347 unsigned int id1 = tr1->
get_id();
348 unsigned int id2 = tr2->
get_id();
357 Eigen::Vector3d PCA1(0,0,0);
358 Eigen::Vector3d PCA2(0,0,0);
362 <<
" PCA1.x " << PCA1.x() <<
" PCA1.y " << PCA1.y()
363 <<
" PCA2.x " << PCA2.x() <<
" PCA2.y " << PCA2.y() << std::endl; }
370 std::cout <<
" good match for tracks " << tr1->
get_id() <<
" and " << tr2->
get_id() <<
" with pT " << tr1->
get_pt() <<
" and " << tr2->
get_pt() << std::endl;
371 std::cout <<
" a1.x " << a1.x() <<
" a1.y " << a1.y() <<
" a1.z " << a1.z() << std::endl;
372 std::cout <<
" a2.x " <<
a2.x() <<
" a2.y " <<
a2.y() <<
" a2.z " <<
a2.z() << std::endl;
373 std::cout <<
" PCA1.x() " << PCA1.x() <<
" PCA1.y " << PCA1.y() <<
" PCA1.z " << PCA1.z() << std::endl;
374 std::cout <<
" PCA2.x() " << PCA2.x() <<
" PCA2.y " << PCA2.y() <<
" PCA2.z " << PCA2.z() << std::endl;
375 std::cout <<
" dca " << dca << std::endl;
380 _track_pair_pca_map.insert( std::make_pair(id1, std::make_pair(id2, std::make_pair(PCA1, PCA2))) );
387 const Eigen::Vector3d &
a2,
const Eigen::Vector3d &b2,
388 Eigen::Vector3d &PCA1, Eigen::Vector3d &PCA2)
398 auto bcrossb = b1.cross(b2);
399 auto mag_bcrossb = bcrossb.norm();
401 auto aminusa = a2-a1;
406 if( mag_bcrossb != 0)
407 dca = bcrossb.dot(aminusa) / mag_bcrossb;
427 double X = b1.dot(b2) - b1.dot(b1) * b2.dot(b2) / b2.dot(b1);
428 double Y = (a2.dot(b2) - a1.dot(b2)) - (a2.dot(b1) - a1.dot(b1)) * b2.dot(b2) / b2.dot(b1) ;
431 double F = b1.dot(b1) / b2.dot(b1);
432 double G = - (a2.dot(b1) - a1.dot(b1)) / b2.dot(b1);
433 double d = c * F + G;
446 std::vector<std::set<unsigned int>> connected_tracks;
447 std::set<unsigned int> connected;
448 std::set<unsigned int> used;
451 unsigned int id1 =
it.first;
452 unsigned int id2 =
it.second.first;
454 if( (used.find(id1) != used.end()) && (used.find(id2) != used.end()) )
456 if(
Verbosity() > 3) std::cout <<
" tracks " << id1 <<
" and " << id2 <<
" are both in used , skip them" << std::endl;
459 else if( (used.find(id1) == used.end()) && (used.find(id2) == used.end()))
461 if(
Verbosity() > 3) std::cout <<
" tracks " << id1 <<
" and " << id2 <<
" are both not in used , start a new connected set" << std::endl;
463 if(connected.size() > 0)
465 connected_tracks.push_back(connected);
467 if(
Verbosity() > 3) std::cout <<
" closing out set " << std::endl;
472 connected.insert(id1);
474 connected.insert(id2);
476 for(
auto cit : _track_pair_map)
478 unsigned int id3 = cit.first;
479 unsigned int id4 = cit.second.first;
480 if( (connected.find(id3) != connected.end()) || (connected.find(id4) != connected.end()) )
482 if(
Verbosity() > 3) std::cout <<
" found connection to " << id3 <<
" and " << id4 << std::endl;
483 connected.insert(id3);
485 connected.insert(id4);
492 if(connected.size() > 0)
494 connected_tracks.push_back(connected);
496 if(
Verbosity() > 3) std::cout <<
" closing out last set " << std::endl;
499 if(
Verbosity() > 3) std::cout <<
"connected_tracks size " << connected_tracks.size() << std::endl;
501 return connected_tracks;
510 unsigned int vtxid =
it;
511 if(
Verbosity() > 1) std::cout <<
"calculate average position for vertex " << vtxid << std::endl;
514 std::vector<double>
vx;
515 std::vector<double>
vy;
516 std::vector<double>
vz;
518 double pca_median_x = 0.;
519 double pca_median_y = 0.;
520 double pca_median_z = 0.;
522 Eigen::Vector3d new_pca_avge(0.,0.,0.);
528 for (
auto cit=ret.first; cit!=ret.second; ++cit)
530 unsigned int tr1id = cit->second;
531 if(
Verbosity() > 2) std::cout <<
" vectors: get entries for track " << tr1id <<
" for vertex " << vtxid << std::endl;
535 for (
auto pit=pca_range.first; pit!=pca_range.second; ++pit)
537 unsigned int tr2id = pit->second.first;
539 Eigen::Vector3d PCA1 = pit->second.second.first;
540 Eigen::Vector3d PCA2 = pit->second.second.second;
543 std::cout <<
" vectors: tr1id " << tr1id <<
" tr2id " << tr2id
544 <<
" PCA1 " << PCA1.x() <<
" " << PCA1.y() <<
" " << PCA1.z()
545 <<
" PCA2 " << PCA2.x() <<
" " << PCA2.y() <<
" " << PCA2.z()
548 vx.push_back(PCA1.x());
549 vx.push_back(PCA2.x());
550 vy.push_back(PCA1.y());
551 vy.push_back(PCA2.y());
552 vz.push_back(PCA1.z());
553 vz.push_back(PCA2.z());
566 std::cout <<
" Vertex has only 2 tracks, use average for PCA: " << new_pca_avge.x() <<
" " << new_pca_avge.y() <<
" " << new_pca_avge.z() << std::endl;
575 if(
Verbosity() > 1) std::cout <<
"Median values: x " << pca_median_x <<
" y " << pca_median_y <<
" z : " << pca_median_z << std::endl;
578 for (
auto cit=ret.first; cit!=ret.second; ++cit)
580 unsigned int tr1id = cit->second;
581 if(
Verbosity() > 2) std::cout <<
" average: get entries for track " << tr1id <<
" for vertex " << vtxid << std::endl;
585 for (
auto pit=pca_range.first; pit!=pca_range.second; ++pit)
587 unsigned int tr2id = pit->second.first;
589 Eigen::Vector3d PCA1 = pit->second.second.first;
590 Eigen::Vector3d PCA2 = pit->second.second.second;
601 new_pca_avge += PCA1;
603 new_pca_avge += PCA2;
608 if(
Verbosity() > 1) std::cout <<
"Reject pair with tr1id " << tr1id <<
" tr2id " << tr2id << std::endl;
613 new_pca_avge = new_pca_avge / new_wt;
617 new_pca_avge.x() = pca_median_x;
618 new_pca_avge.y() = pca_median_y;
619 new_pca_avge.z() = pca_median_z;
633 if( (v.size() % 2) == 0)
637 auto m1 = v.begin() + v.size()/2;
638 std::nth_element(v.begin(), m1, v.end());
639 double median1 = v[v.size()/2];
641 auto m2 = v.begin() + v.size()/2 - 1;
642 std::nth_element(v.begin(),
m2, v.end());
643 double median2 = v[v.size()/2 - 1];
645 median = (median1 + median2) / 2.0;
646 if(
Verbosity() > 2) std::cout <<
"The vector size is " << v.size()
647 <<
" element m is " << v.size() / 2 <<
" = " << v[v.size()/2]
648 <<
" element m-1 is " << v.size() / 2 -1 <<
" = " << v[v.size()/2-1]
654 auto m = v.begin() + v.size()/2;
655 std::nth_element(v.begin(),
m, v.end());
656 median = v[v.size()/2];
657 if(
Verbosity() > 2) std::cout <<
"The vector size is " << v.size() <<
" element m is " << v.size() / 2 <<
" = " << v[v.size()/2] << std::endl;
675 std::cout <<
" average = " << avge << std::endl;