43 : _basetrutheval(topNode)
54 std::cout <<
"SvtxTruthEval::~SvtxTruthEval() - Error Count: " <<
_errors << std::endl;
79 return std::set<PHG4Hit*>();
93 std::set<PHG4Hit*> truth_hits;
102 PHG4Hit* g4hit = g4iter->second;
103 truth_hits.insert(g4hit);
114 PHG4Hit* g4hit = g4iter->second;
115 truth_hits.insert(g4hit);
126 PHG4Hit* g4hit = g4iter->second;
127 truth_hits.insert(g4hit);
138 PHG4Hit* g4hit = g4iter->second;
139 truth_hits.insert(g4hit);
156 return std::set<PHG4Hit*>();
166 return std::set<PHG4Hit*>();
176 std::map<PHG4Particle*, std::set<PHG4Hit*>>::iterator iter =
185 std::set<PHG4Hit*> truth_hits;
191 std::multimap<const int, PHG4Hit*> temp_clusters_from_particles;
199 PHG4Hit* g4hit = g4iter->second;
200 temp_clusters_from_particles.insert(std::make_pair(g4hit->
get_trkid(), g4hit));
211 PHG4Hit* g4hit = g4iter->second;
212 temp_clusters_from_particles.insert(std::make_pair(g4hit->
get_trkid(), g4hit));
223 PHG4Hit* g4hit = g4iter->second;
224 temp_clusters_from_particles.insert(std::make_pair(g4hit->
get_trkid(), g4hit));
235 PHG4Hit* g4hit = g4iter->second;
236 temp_clusters_from_particles.insert(std::make_pair(g4hit->
get_trkid(), g4hit));
242 iter != range.second; ++iter)
245 std::set<PHG4Hit*> truth_hits;
246 std::multimap<const int, PHG4Hit*>::const_iterator lower_bound = temp_clusters_from_particles.lower_bound(g4particle->
get_track_id());
247 std::multimap<const int, PHG4Hit*>::const_iterator upper_bound = temp_clusters_from_particles.upper_bound(g4particle->
get_track_id());
248 std::multimap<const int, PHG4Hit*>::const_iterator cfp_iter;
249 for (cfp_iter = lower_bound; cfp_iter != upper_bound; ++cfp_iter)
251 PHG4Hit* g4hit = cfp_iter->second;
252 truth_hits.insert(g4hit);
260 using output_type_t = std::map<TrkrDefs::cluskey, std::shared_ptr<TrkrCluster>>;
264 return output_type_t();
274 return output_type_t();
288 std::cout <<
PHWHERE <<
" Truth clustering for particle " << particle->
get_track_id() << std::endl;
297 return output_type_t();
301 output_type_t truth_clusters;
315 std::vector<PHG4Hit*> contributing_hits;
316 std::vector<double> contributing_hits_energy;
317 std::vector<std::vector<double>> contributing_hits_entry;
318 std::vector<std::vector<double>> contributing_hits_exit;
319 LayerClusterG4Hits(g4hits, contributing_hits, contributing_hits_energy, contributing_hits_entry, contributing_hits_exit, layer, gx, gy, gz, gt, gedep);
330 unsigned int side = 0;
336 unsigned int sector = 0;
341 unsigned int stave = 0;
342 unsigned int chip = 0;
343 unsigned int strobe = 0;
349 unsigned int ladderzid = 0;
350 unsigned int ladderphiid = 0;
351 uint16_t crossing = 0;
356 unsigned int tile = 0;
364 std::cout <<
PHWHERE <<
"Bad layer number: " << layer << std::endl;
368 auto clus = std::make_shared<TrkrClusterv1>();
374 clus->setAdc(adc_value);
375 clus->setPosition(0, gx);
376 clus->setPosition(1, gy);
377 clus->setPosition(2, gz);
381 for (
auto& contributing_hit : contributing_hits)
387 float g4phisize = NAN;
389 G4ClusterSize(ckey, layer, contributing_hits_entry, contributing_hits_exit, g4phisize, g4zsize);
391 for (
int i1 = 0; i1 < 3; ++i1)
393 for (
int i2 = 0; i2 < 3; ++i2)
395 clus->setSize(i1, i2, 0.0);
396 clus->setError(i1, i2, 0.0);
399 clus->setError(0, 0, gedep);
400 clus->setSize(1, 1, g4phisize);
401 clus->setSize(2, 2, g4zsize);
402 clus->setError(1, 1, g4phisize / std::sqrt(12));
403 clus->setError(2, 2, g4zsize / std::sqrt(12.0));
405 truth_clusters.insert(std::make_pair(ckey, clus));
414 return truth_clusters;
417 void SvtxTruthEval::LayerClusterG4Hits(
const std::set<PHG4Hit*>& truth_hits, std::vector<PHG4Hit*>& contributing_hits, std::vector<double>& contributing_hits_energy, std::vector<std::vector<double>>& contributing_hits_entry, std::vector<std::vector<double>>& contributing_hits_exit,
float layer,
float&
x,
float&
y,
float&
z,
float&
t,
float&
e)
446 std::cout <<
" TruthEval::LayerCluster hits for layer " << layer <<
" with rbin " << rbin <<
" rbout " << rbout << std::endl;
450 for (
auto this_g4hit : truth_hits)
452 float rbegin = std::sqrt(this_g4hit->get_x(0) * this_g4hit->get_x(0) + this_g4hit->get_y(0) * this_g4hit->get_y(0));
453 float rend = std::sqrt(this_g4hit->get_x(1) * this_g4hit->get_x(1) + this_g4hit->get_y(1) * this_g4hit->get_y(1));
463 xl[0] = this_g4hit->get_x(0);
464 yl[0] = this_g4hit->get_y(0);
465 zl[0] = this_g4hit->get_z(0);
466 xl[1] = this_g4hit->get_x(1);
467 yl[1] = this_g4hit->get_y(1);
468 zl[1] = this_g4hit->get_z(1);
472 xl[0] = this_g4hit->get_x(1);
473 yl[0] = this_g4hit->get_y(1);
474 zl[0] = this_g4hit->get_z(1);
475 xl[1] = this_g4hit->get_x(0);
476 yl[1] = this_g4hit->get_y(0);
477 zl[1] = this_g4hit->get_z(0);
483 if (rbegin < rbin && rend < rbin)
487 if (rbegin > rbout && rend > rbout)
494 std::cout <<
" keep g4hit with rbegin " << rbegin <<
" rend " << rend
495 <<
" xbegin " << xl[0] <<
" xend " << xl[1]
496 <<
" ybegin " << yl[0] <<
" yend " << yl[1]
497 <<
" zbegin " << zl[0] <<
" zend " << zl[1]
516 xin = xl[0] + local_t * (xl[1] - xl[0]);
517 yin = yl[0] + local_t * (yl[1] - yl[0]);
518 zin = zl[0] + local_t * (zl[1] - zl[0]);
528 xout = xl[0] + local_t * (xl[1] - xl[0]);
529 yout = yl[0] + local_t * (yl[1] - yl[0]);
530 zout = zl[0] + local_t * (zl[1] - zl[0]);
534 double rin = std::sqrt(xin * xin + yin * yin);
535 double rout = std::sqrt(xout * xout + yout * yout);
538 double efrac = this_g4hit->get_edep() * (rout - rin) / (rend - rbegin);
539 gx += (xin + xout) * 0.5 * efrac;
540 gy += (yin + yout) * 0.5 * efrac;
541 gz += (zin + zout) * 0.5 * efrac;
542 gt += this_g4hit->get_avg_t() * efrac;
543 gr += (rin + rout) * 0.5 * efrac;
548 std::cout <<
" rin " << rin <<
" rout " << rout
549 <<
" xin " << xin <<
" xout " << xout <<
" yin " << yin <<
" yout " << yout <<
" zin " << zin <<
" zout " << zout
550 <<
" edep " << this_g4hit->get_edep()
551 <<
" this_edep " << efrac << std::endl;
552 std::cout <<
" xavge " << (xin + xout) * 0.5 <<
" yavge " << (yin + yout) * 0.5 <<
" zavge " << (zin + zout) * 0.5 <<
" ravge " << (rin + rout) * 0.5
557 std::vector<double> entry_loc;
558 entry_loc.push_back(xin);
559 entry_loc.push_back(yin);
560 entry_loc.push_back(zin);
561 std::vector<double> exit_loc;
562 exit_loc.push_back(xout);
563 exit_loc.push_back(yout);
564 exit_loc.push_back(zout);
567 contributing_hits.push_back(this_g4hit);
568 contributing_hits_energy.push_back(this_g4hit->get_edep() * (zout - zin) / (zl[1] - zl[0]));
569 contributing_hits_entry.push_back(entry_loc);
570 contributing_hits_exit.push_back(exit_loc);
583 gr = (rbin + rbout) * 0.5;
588 std::cout <<
" weighted means: gx " << gx <<
" gy " << gy <<
" gz " << gz <<
" gr " << gr <<
" e " << gwt << std::endl;
595 float rentry = 999.0;
596 float xentry = 999.0;
597 float yentry = 999.0;
598 float zentry = 999.0;
599 float rexit = -999.0;
600 float xexit = -999.0;
601 float yexit = -999.0;
602 float zexit = -999.0;
604 for (
unsigned int ientry = 0; ientry < contributing_hits_entry.size(); ++ientry)
606 float tmpx = contributing_hits_entry[ientry][0];
607 float tmpy = contributing_hits_entry[ientry][1];
608 float tmpr = std::sqrt(tmpx * tmpx + tmpy * tmpy);
613 xentry = contributing_hits_entry[ientry][0];
614 yentry = contributing_hits_entry[ientry][1];
615 zentry = contributing_hits_entry[ientry][2];
618 tmpx = contributing_hits_exit[ientry][0];
619 tmpy = contributing_hits_exit[ientry][1];
620 tmpr = std::sqrt(tmpx * tmpx + tmpy * tmpy);
625 xexit = contributing_hits_exit[ientry][0];
626 yexit = contributing_hits_exit[ientry][1];
627 zexit = contributing_hits_exit[ientry][2];
631 float geo_r = (rentry + rexit) * 0.5;
632 float geo_x = (xentry + xexit) * 0.5;
633 float geo_y = (yentry + yexit) * 0.5;
634 float geo_z = (zentry + zexit) * 0.5;
646 std::cout <<
" rentry " << rentry <<
" rexit " << rexit
647 <<
" xentry " << xentry <<
" xexit " << xexit <<
" yentry " << yentry <<
" yexit " << yexit <<
" zentry " << zentry <<
" zexit " << zexit << std::endl;
649 std::cout <<
" geometric means: geo_x " << geo_x <<
" geo_y " << geo_y <<
" geo_z " << geo_z <<
" geo r " << geo_r <<
" e " << gwt << std::endl
658 for (
auto this_g4hit : truth_hits)
660 if (this_g4hit->get_layer() != (
unsigned int) layer)
665 gx = this_g4hit->get_avg_x();
666 gy = this_g4hit->get_avg_y();
667 gz = this_g4hit->get_avg_z();
668 gt = this_g4hit->get_avg_t();
669 gwt += this_g4hit->get_edep();
672 std::vector<double> entry_loc;
673 entry_loc.push_back(this_g4hit->get_x(0));
674 entry_loc.push_back(this_g4hit->get_y(0));
675 entry_loc.push_back(this_g4hit->get_z(0));
676 std::vector<double> exit_loc;
677 exit_loc.push_back(this_g4hit->get_x(1));
678 exit_loc.push_back(this_g4hit->get_y(1));
679 exit_loc.push_back(this_g4hit->get_z(1));
682 contributing_hits.push_back(this_g4hit);
683 contributing_hits_energy.push_back(this_g4hit->get_edep());
684 contributing_hits_entry.push_back(entry_loc);
685 contributing_hits_exit.push_back(exit_loc);
702 double inner_x = NAN;
703 double inner_y = NAN;
704 double inner_z = NAN;
708 double outer_x = NAN;
709 double outer_y = NAN;
710 double outer_z = NAN;
712 for (
unsigned int ihit = 0;
ihit < contributing_hits_entry.size(); ++
ihit)
714 double rad1 = std::sqrt(pow(contributing_hits_entry[
ihit][0], 2) + pow(contributing_hits_entry[ihit][1], 2));
715 if (rad1 < inner_radius)
718 inner_x = contributing_hits_entry[
ihit][0];
719 inner_y = contributing_hits_entry[
ihit][1];
720 inner_z = contributing_hits_entry[
ihit][2];
723 double rad2 = std::sqrt(pow(contributing_hits_exit[ihit][0], 2) + pow(contributing_hits_exit[ihit][1], 2));
724 if (rad2 > outer_radius)
727 outer_x = contributing_hits_exit[
ihit][0];
728 outer_y = contributing_hits_exit[
ihit][1];
729 outer_z = contributing_hits_exit[
ihit][2];
733 double inner_phi = atan2(inner_y, inner_x);
734 double outer_phi = atan2(outer_y, outer_x);
735 double avge_z = (outer_z + inner_z) / 2.0;
742 if (radius > 28 && radius < 80)
746 double tpc_length = 211.0;
747 double drift_velocity = 8.0 / 1000.0;
751 double diffusion_trans = 0.006;
752 double phidiffusion = diffusion_trans * std::sqrt(tpc_length / 2. - fabs(avge_z));
754 double added_smear_trans = 0.085;
755 double gem_spread = 0.04;
757 if (outer_phi < inner_phi)
763 double g4max_phi = outer_phi + sigmas * std::sqrt(pow(phidiffusion, 2) + pow(added_smear_trans, 2) + pow(gem_spread, 2)) / radius;
764 double g4min_phi = inner_phi - sigmas * std::sqrt(pow(phidiffusion, 2) + pow(added_smear_trans, 2) + pow(gem_spread, 2)) / radius;
767 unsigned int phibinmin = layergeom->
get_phibin(g4min_phi);
768 unsigned int phibinmax = layergeom->
get_phibin(g4max_phi);
769 unsigned int phibinwidth = phibinmax - phibinmin + 1;
777 outer_z = fabs(outer_z);
778 inner_z = fabs(inner_z);
780 double diffusion_long = 0.015;
781 double zdiffusion = diffusion_long * std::sqrt(tpc_length / 2. - fabs(avge_z));
782 double zshaping_lead = 32.0 * drift_velocity;
783 double zshaping_tail = 48.0 * drift_velocity;
784 double added_smear_long = 0.105;
787 if (outer_z < inner_z)
791 g4max_z = outer_z + sigmas * std::sqrt(pow(zdiffusion, 2) + pow(added_smear_long, 2) + pow(zshaping_lead, 2));
792 g4min_z = inner_z - sigmas * std::sqrt(pow(zdiffusion, 2) + pow(added_smear_long, 2) + pow(zshaping_tail, 2));
795 unsigned int binmin = layergeom->
get_zbin(g4min_z);
796 unsigned int binmax = layergeom->
get_zbin(g4max_z);
801 unsigned int binwidth = binmax - binmin + 1;
806 else if (radius > 5 && radius < 20)
813 double world_inner[3] = {inner_x, inner_y, inner_z};
814 TVector3 world_inner_vec = {inner_x, inner_y, inner_z};
816 int segment_z_bin, segment_phi_bin;
822 double yin = local_inner_vec[1];
823 double zin = local_inner_vec[2];
824 int strip_y_index, strip_z_index;
828 double world_outer[3] = {outer_x, outer_y, outer_z};
829 TVector3 world_outer_vec = {outer_x, outer_y, outer_z};
835 double yout = local_outer_vec[1];
836 double zout = local_outer_vec[2];
837 int strip_y_index_out, strip_z_index_out;
840 int strips = abs(strip_y_index_out - strip_y_index) + 1;
841 int cols = abs(strip_z_index_out - strip_z_index) + 1;
846 g4phisize = strip_width;
847 g4zsize = strip_length;
855 else if (radius > 80)
863 unsigned int stave, stave_outer;
864 unsigned int chip, chip_outer;
866 int column, column_outer;
869 double max_diffusion_radius = 25.0e-4;
870 double min_diffusion_radius = 8.0e-4;
874 TVector3 world_inner = {inner_x, inner_y, inner_z};
875 std::vector<double> world_inner_vec = {world_inner[0], world_inner[1], world_inner[2]};
881 TVector3 world_outer = {outer_x, outer_y, outer_z};
882 std::vector<double> world_outer_vec = {world_outer[0], world_outer[1], world_outer[2]};
888 double diff = max_diffusion_radius * 0.6;
889 if (local_outer[0] < local_inner[0])
893 local_outer[0] += diff;
894 local_inner[0] -= diff;
896 double diff_outer = min_diffusion_radius * 0.6;
897 if (local_outer[2] < local_inner[2])
899 diff_outer = -diff_outer;
901 local_outer[2] += diff_outer;
902 local_inner[2] -= diff_outer;
911 unsigned int rows = row_outer - row + 1;
914 if (column_outer < column)
918 unsigned int columns = column_outer - column + 1;
931 std::set<PHG4Hit*> g4hit_set;
933 std::pair<std::multimap<TrkrDefs::cluskey, PHG4Hit*>::iterator,
934 std::multimap<TrkrDefs::cluskey, PHG4Hit*>::iterator>
937 for (std::multimap<TrkrDefs::cluskey, PHG4Hit*>::iterator jter = ret.first; jter != ret.second; ++jter)
939 g4hit_set.insert(jter->second);
963 PHG4Hit* innermost_hit =
nullptr;
964 float innermost_radius = FLT_MAX;
967 for (
auto candidate : truth_hits)
969 float x = candidate->get_x(0);
970 float y = candidate->get_y(0);
971 float r = std::sqrt(x * x + y * y);
972 if (r < innermost_radius)
974 innermost_radius =
r;
975 innermost_hit = candidate;
979 return innermost_hit;
1000 PHG4Hit* outermost_hit =
nullptr;
1001 float outermost_radius = FLT_MAX * -1.0;
1005 std::map<PHG4Particle*, PHG4Hit*>::iterator iter =
1009 return iter->second;
1014 for (
auto candidate : truth_hits)
1016 float x = candidate->get_x(1);
1017 float y = candidate->get_y(1);
1018 float r = std::sqrt(x * x + y * y);
1019 if (r > outermost_radius)
1021 outermost_radius =
r;
1022 outermost_hit = candidate;
1030 return outermost_hit;
1073 std::map<PHG4Hit*, PHG4Particle*>::iterator iter =
1077 return iter->second;
1127 _tgeometry = findNode::getClass<ActsGeometry>(topNode,
"ActsGeometry");
1128 _truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode,
"G4TruthInfo");
1130 _g4hits_mms = findNode::getClass<PHG4HitContainer>(topNode,
"G4HIT_MICROMEGAS");
1131 _g4hits_svtx = findNode::getClass<PHG4HitContainer>(topNode,
"G4HIT_TPC");
1132 _g4hits_tracker = findNode::getClass<PHG4HitContainer>(topNode,
"G4HIT_INTT");
1133 _g4hits_maps = findNode::getClass<PHG4HitContainer>(topNode,
"G4HIT_MVTX");
1135 _mms_geom_container = findNode::getClass<PHG4CylinderGeomContainer>(topNode,
"CYLINDERGEOM_MICROMEGAS_FULL");
1136 _tpc_geom_container = findNode::getClass<PHG4TpcCylinderGeomContainer>(topNode,
"CYLINDERCELLGEOM_SVTX");
1137 _intt_geom_container = findNode::getClass<PHG4CylinderGeomContainer>(topNode,
"CYLINDERGEOM_INTT");
1138 _mvtx_geom_container = findNode::getClass<PHG4CylinderGeomContainer>(topNode,
"CYLINDERGEOM_MVTX");
1176 float A = (x[1] - x[0]) * (x[1] - x[0]) + (y[1] - y[0]) * (y[1] - y[0]);
1177 float B = 2.0 * x[0] * (x[1] - x[0]) + 2.0 * y[0] * (y[1] - y[0]);
1178 float C = x[0] * x[0] + y[0] * y[0] - radius * radius;
1179 float tup = (-B + std::sqrt(B * B - 4.0 * A * C)) / (2.0 * A);
1180 float tdn = (-B - std::sqrt(B * B - 4.0 * A * C)) / (2.0 * A);
1184 if (tdn >= -0.0
e-4 && tdn <= 1.0004)
1188 else if (tup >= -0.0
e-4 && tup <= 1.0004)
1194 std::cout <<
PHWHERE <<
" **** Oops! No valid solution for tup or tdn, tdn = " << tdn <<
" tup = " << tup << std::endl;
1195 std::cout <<
" radius " << radius <<
" rbegin " << std::sqrt(x[0] * x[0] + y[0] * y[0]) <<
" rend " << std::sqrt(x[1] * x[1] + y[1] * y[1]) << std::endl;
1196 std::cout <<
" x0 " << x[0] <<
" x1 " << x[1] << std::endl;
1197 std::cout <<
" y0 " << y[0] <<
" y1 " << y[1] << std::endl;
1198 std::cout <<
" z0 " << z[0] <<
" z1 " << z[1] << std::endl;
1199 std::cout <<
" A " << A <<
" B " << B <<
" C " << C << std::endl;
1216 double Tpc_NTot = 0.5 * Ne_NTotal + 0.5 *
CF4_NTotal;
1217 double Tpc_dEdx = 0.5 * Ne_dEdx + 0.5 *
CF4_dEdx;
1218 double Tpc_ElectronsPerKeV = Tpc_NTot / Tpc_dEdx;
1219 double electrons_per_gev = Tpc_ElectronsPerKeV * 1e6;
1221 double gem_amplification = 1400;
1222 double input_electrons = gedep * electrons_per_gev * gem_amplification;
1225 double ChargeToPeakVolts = 20;
1226 double ADCSignalConversionGain = ChargeToPeakVolts * 1.60e-04 * 2.4;
1227 double adc_input_voltage = input_electrons * ADCSignalConversionGain;
1228 unsigned int adc_output = (
unsigned int) (adc_input_voltage * 1024.0 / 2200.0);
1229 if (adc_output > 1023)