2 #include <qautils/QAUtil.h>
3 #include <qautils/QAHistManagerDef.h>
65 struct interpolation_data_t
67 using list = std::vector<interpolation_data_t>;
72 double px()
const {
return momentum.x(); }
73 double py()
const {
return momentum.y(); }
74 double pz()
const {
return momentum.z(); }
82 template <
double (
interpolation_data_t::*accessor)() const>
83 double interpolate(
const interpolation_data_t::list& hits,
double z_extrap)
94 for (
const auto& hit : hits)
96 const double x = (hit.*accessor)();
97 const double w = hit.weight;
101 const double z = hit.z();
110 if (!
valid)
return NAN;
112 const auto alpha = (sw * swzx - swz * swx);
113 const auto beta = (swz2 * swx - swz * swzx);
114 const auto denom = (sw * swz2 -
square(swz));
116 return (
alpha * z_extrap + beta) / denom;
124 , m_truthContainer(nullptr)
138 auto geom_container = findNode::getClass<PHG4CylinderGeomContainer>(topNode,
"CYLINDERGEOM_MICROMEGAS_FULL");
141 std::cout <<
PHWHERE <<
" unable to find DST node CYLINDERGEOM_MICROMEGAS_FULL" << std::endl;
157 std::cout <<
"QAG4SimulationTpc::InitRun - Fatal Error - "
158 <<
"unable to find node G4TruthInfo" << std::endl;
163 const auto range = geom_container->get_begin_end();
164 for (
auto iter = range.first; iter != range.second; ++iter)
183 const auto segmentation_type = layergeom->get_segmentation_type();
189 Form(
"micromegas ADC distribution layer_%i",
layer),
191 h->GetXaxis()->SetTitle(
"ADC");
192 hm->registerHisto(
h);
197 const double max_residual = is_segmentation_phi ? 0.04 : 0.08;
199 Form(
"micromegas %s_{cluster-truth} layer_%i",
200 is_segmentation_phi ?
"r#Delta#phi" :
"#Deltaz",
layer),
201 100, -max_residual, max_residual);
202 h->GetXaxis()->SetTitle(Form(
"%s_{cluster-truth} (cm)", is_segmentation_phi ?
"r#Delta#phi" :
"#Deltaz"));
203 hm->registerHisto(
h);
208 const double max_error = is_segmentation_phi ? 0.04 : 0.08;
210 Form(
"micromegas %s error layer_%i",
211 is_segmentation_phi ?
"r#Delta#phi" :
"#Deltaz",
layer),
213 h->GetXaxis()->SetTitle(Form(
"%s error (cm)", is_segmentation_phi ?
"r#Delta#phi" :
"#Deltaz"));
214 hm->registerHisto(
h);
220 Form(
"micromegas %s layer_%i",
221 is_segmentation_phi ?
"#Delta#phi/#sigma#phi" :
"#Deltaz/#sigmaz",
layer),
223 h->GetXaxis()->SetTitle(is_segmentation_phi ?
"#Delta#phi/#sigma#phi" :
"#Deltaz/#sigmaz");
224 hm->registerHisto(
h);
229 auto h =
new TH1F(Form(
"%sclus_size_%i",
get_histo_prefix().c_str(),
layer), Form(
"micromegas cluster size layer_%i",
layer), 20, 0, 20);
230 h->GetXaxis()->SetTitle(
"csize");
231 hm->registerHisto(
h);
260 m_tGeometry = findNode::getClass<ActsGeometry>(topNode,
"ActsGeometry");
263 std::cout <<
PHWHERE <<
"No acts tracking geometry, exiting."
268 m_micromegas_geonode = findNode::getClass<PHG4CylinderGeomContainer>(topNode,
"CYLINDERGEOM_MICROMEGAS_FULL");
271 std::cout <<
PHWHERE <<
" ERROR: Can't find CYLINDERGEOM_MICROMEGAS_FULL." << std::endl;
275 m_hitsets = findNode::getClass<TrkrHitSetContainer>(topNode,
"TRKR_HITSET");
278 std::cout <<
PHWHERE <<
" ERROR: Can't find TrkrHitSetContainer." << std::endl;
281 m_cluster_map = findNode::getClass<TrkrClusterContainer>(topNode,
"TRKR_CLUSTER");
284 std::cout <<
PHWHERE <<
" unable to find DST node TRKR_CLUSTER" << std::endl;
288 m_cluster_hit_map = findNode::getClass<TrkrClusterHitAssoc>(topNode,
"TRKR_CLUSTERHITASSOC");
291 std::cout <<
PHWHERE <<
" unable to find DST node TRKR_CLUSTERHITASSOC" << std::endl;
295 m_hit_truth_map = findNode::getClass<TrkrHitTruthAssoc>(topNode,
"TRKR_HITTRUTHASSOC");
298 std::cout <<
PHWHERE <<
" unable to find DST node TRKR_HITTRUTHASSOC" << std::endl;
305 std::cout <<
PHWHERE <<
" unable to find DST node G4HIT_MVTX" << std::endl;
328 using HistogramMap = std::map<int, HistogramList>;
329 HistogramMap histograms;
335 histograms.insert(std::make_pair(
layer, h));
340 for (
auto hitsetiter = hitsetrange.first; hitsetiter != hitsetrange.second; ++hitsetiter)
343 const auto hitsetkey = hitsetiter->first;
347 const auto hiter = histograms.find(
layer);
348 if (hiter == histograms.end())
continue;
355 for (
auto hit_it = hitrange.first; hit_it != hitrange.second; ++hit_it)
358 auto fill = [](TH1*
h,
float value)
359 {
if( h ) h->Fill(
value ); };
360 fill(hiter->second.adc, hit_it->second->getAdc());
378 TH1* residual =
nullptr;
379 TH1* residual_error =
nullptr;
380 TH1* pulls =
nullptr;
382 TH1* csize =
nullptr;
385 using HistogramMap = std::map<int, HistogramList>;
386 HistogramMap histograms;
391 h.residual =
dynamic_cast<TH1*
>(hm->getHisto(Form(
"%sresidual_%i",
get_histo_prefix().c_str(),
layer)));
392 h.residual_error =
dynamic_cast<TH1*
>(hm->getHisto(Form(
"%sresidual_error_%i",
get_histo_prefix().c_str(),
layer)));
393 h.pulls =
dynamic_cast<TH1*
>(hm->getHisto(Form(
"%scluster_pulls_%i",
get_histo_prefix().c_str(),
layer)));
394 h.csize =
dynamic_cast<TH1*
>(hm->getHisto(Form(
"%sclus_size_%i",
get_histo_prefix().c_str(),
layer)));
396 histograms.insert(std::make_pair(
layer, h));
403 iter != range.second;
409 float gembed = trutheval->
get_embed(g4particle);
413 std::cout <<
PHWHERE <<
" PHG4Particle ID " << gtrackID <<
" gembed " << gembed <<
" gflavor " << gflavor <<
" gprimary " << gprimary << std::endl;
422 for (
const auto& [gkey, gclus] : truth_clusters)
425 if (
layer < 7)
continue;
427 float gx = gclus->getX();
428 float gy = gclus->getY();
429 float gz = gclus->getZ();
431 xy_pts.emplace_back(gx, gy);
432 rz_pts.emplace_back(std::sqrt(gx * gx + gy * gy), gz);
439 if (std::isnan(
R))
continue;
444 for (
const auto ckey : ckeyset)
455 if (!layergeom)
continue;
458 const auto hiter = histograms.find(
layer);
459 if (hiter == histograms.end())
continue;
469 double rphi_error = cluster->getRPhiError();
470 double z_error = cluster->getZError();
473 const TVector3 cluster_world(global(0), global(1), global(2));
474 const auto cluster_local = layergeom->get_local_from_world_coords(tileid,
m_tGeometry, cluster_world);
480 interpolation_data_t::list hits;
481 for (
const auto& g4hit : g4hits)
483 const auto weight = g4hit->get_edep();
484 for (
int i = 0;
i < 2; ++
i)
487 TVector3 g4hit_world(g4hit->get_x(
i), g4hit->get_y(
i), g4hit->get_z(
i));
488 TVector3 g4hit_local = layergeom->get_local_from_world_coords(tileid,
m_tGeometry, g4hit_world);
491 TVector3 momentum_world(g4hit->get_px(
i), g4hit->get_py(
i), g4hit->get_pz(
i));
492 TVector3 momentum_local = layergeom->get_local_from_world_vect(tileid,
m_tGeometry, momentum_world);
494 hits.push_back({.position = g4hit_local, .momentum = momentum_local, .weight = weight});
499 const auto z_extrap = cluster_local.z();
500 const TVector3 interpolation_local(
501 interpolate<&interpolation_data_t::x>(hits, z_extrap),
502 interpolate<&interpolation_data_t::y>(hits, z_extrap),
503 interpolate<&interpolation_data_t::z>(hits, z_extrap));
506 auto fill = [](TH1*
h,
float value)
507 {
if( h ) h->Fill(
value ); };
508 switch (segmentation_type)
512 const auto drphi = cluster_local.x() - interpolation_local.x();
513 fill(hiter->second.residual, drphi);
514 fill(hiter->second.residual_error, rphi_error);
515 fill(hiter->second.pulls, drphi / rphi_error);
521 const auto dz = cluster_local.y() - interpolation_local.y();
522 fill(hiter->second.residual,
dz);
523 fill(hiter->second.residual_error, z_error);
524 fill(hiter->second.pulls,
dz / z_error);
532 fill(hiter->second.csize,
std::distance(hit_range.first, hit_range.second));
546 for (
auto iter = range.first; iter != range.second; ++iter)
549 const auto& hit_key = iter->second;
556 for (
auto truth_iter = g4hit_map.begin(); truth_iter != g4hit_map.end(); ++truth_iter)
559 const auto g4hit_key = truth_iter->second.second;
565 if (g4hit) out.insert(g4hit);