34 #include <phparameter/PHParameterInterface.h>
35 #include <phparameter/PHParameters.h>
36 #include <phparameter/PHParametersContainer.h>
38 #include <pdbcalbase/PdbParameterMapContainer.h>
60 #include <gsl/gsl_randist.h>
61 #include <gsl/gsl_rng.h>
114 std::cout <<
PHWHERE <<
"DST Node missing, doing nothing." << std::endl;
126 std::cout <<
Name() <<
" Could not locate G4HIT node " <<
hitnodename << std::endl;
132 hitsetcontainer = findNode::getClass<TrkrHitSetContainer>(topNode,
"TRKR_HITSET");
145 DetNode->addNode(newNode);
148 hittruthassoc = findNode::getClass<TrkrHitTruthAssoc>(topNode,
"TRKR_HITTRUTHASSOC");
161 DetNode->addNode(newNode);
164 truthtracks = findNode::getClass<TrkrTruthTrackContainer>(topNode,
"TRKR_TRUTHTRACKCONTAINER");
177 DetNode->addNode(newNode);
180 truthclustercontainer = findNode::getClass<TrkrClusterContainer>(topNode,
"TRKR_TRUTHCLUSTERCONTAINER");
193 DetNode->addNode(newNode);
206 runNode->addNode(RunDetNode);
216 parNode->addNode(ParDetNode);
222 auto tpcparams = findNode::getClass<PHParametersContainer>(ParDetNode, tpcgeonodename);
226 auto tpcpdbparams = findNode::getClass<PdbParameterMapContainer>(RunDetNode, runparamname);
231 tpcparams->CreateAndFillFrom(tpcpdbparams,
detector);
236 std::cout <<
"PHG4TpcElectronDrift::InitRun - failed to find " << runparamname <<
" in order to initialize " << tpcgeonodename <<
". Aborting run ..." << std::endl;
243 const PHParameters *tpcparam = tpcparams->GetParameters(0);
266 se->registerHisto(
dlong);
268 se->registerHisto(
dtrans);
273 hitmapstart =
new TH2F(
"hitmapstart",
"g4hit starting X-Y locations", 1560, -78, 78, 1560, -78, 78);
274 hitmapend =
new TH2F(
"hitmapend",
"g4hit final X-Y locations", 1560, -78, 78, 1560, -78, 78);
275 z_startmap =
new TH2F(
"z_startmap",
"g4hit starting Z vs. R locations", 2000, -100, 100, 780, 0, 78);
276 deltaphi =
new TH2F(
"deltaphi",
"Total delta phi; phi (rad);#Delta phi (rad)", 600, -M_PI, M_PI, 1000, -.2, .2);
277 deltaRphinodiff =
new TH2F(
"deltaRphinodiff",
"Total delta R*phi, no diffusion; r (cm);#Delta R*phi (cm)", 600, 20, 80, 1000, -3, 5);
278 deltaphivsRnodiff =
new TH2F(
"deltaphivsRnodiff",
"Total delta phi vs. R; phi (rad);#Delta phi (rad)", 600, 20, 80, 1000, -.2, .2);
279 deltaz =
new TH2F(
"deltaz",
"Total delta z; z (cm);#Delta z (cm)", 1000, 0, 100, 1000, -.5, 5);
280 deltaphinodiff =
new TH2F(
"deltaphinodiff",
"Total delta phi (no diffusion, only SC distortion); phi (rad);#Delta phi (rad)", 600, -M_PI, M_PI, 1000, -.2, .2);
281 deltaphinodist =
new TH2F(
"deltaphinodist",
"Total delta phi (no SC distortion, only diffusion); phi (rad);#Delta phi (rad)", 600, -M_PI, M_PI, 1000, -.2, .2);
282 deltar =
new TH2F(
"deltar",
"Total Delta r; r (cm);#Delta r (cm)", 580, 20, 78, 1000, -3, 5);
283 deltarnodiff =
new TH2F(
"deltarnodiff",
"Delta r (no diffusion, only SC distortion); r (cm);#Delta r (cm)", 580, 20, 78, 1000, -2, 5);
284 deltarnodist =
new TH2F(
"deltarnodist",
"Delta r (no SC distortion, only diffusion); r (cm);#Delta r (cm)", 580, 20, 78, 1000, -2, 5);
290 m_outf.reset(
new TFile(
"nt_out.root",
"recreate"));
291 nt =
new TNtuple(
"nt",
"electron drift stuff",
"hit:ts:tb:tsig:rad:zstart:zfinal");
292 nthit =
new TNtuple(
"nthit",
"TrkrHit collecting",
"layer:phipad:zbin:neffelectrons");
293 ntfinalhit =
new TNtuple(
"ntfinalhit",
"TrkrHit collecting",
"layer:phipad:zbin:neffelectrons");
294 ntpad =
new TNtuple(
"ntpad",
"electron by electron pad centroid",
"layer:phigem:phiclus:zgem:zclus");
295 se->registerHisto(
nt);
296 se->registerHisto(
nthit);
297 se->registerHisto(
ntpad);
306 std::cout <<
"PHG4TpcElectronDrift::InitRun - layers: " <<
std::distance(range.first, range.second) << std::endl;
308 for (
auto layeriter = range.first; layeriter != range.second; ++layeriter)
310 const auto radius = layeriter->second->get_radius();
311 std::cout << Form(
"%.3f ", radius );
315 std::cout << std::endl;
318 std::cout << std::endl;
323 mClusHitsVerbose = findNode::getClass<ClusHitsVerbosev1>(topNode,
"Trkr_TruthClusHitsVerbose");
335 DetNode->addNode(newNode);
346 m_tGeometry = findNode::getClass<ActsGeometry>(topNode,
"ActsGeometry");
349 std::cout <<
PHWHERE <<
"ActsGeometry not found on node tree. Exiting" << std::endl;
359 static constexpr
unsigned int print_layer = 18;
368 auto g4hit = findNode::getClass<PHG4HitContainer>(topNode,
hitnodename);
371 std::cout <<
"Could not locate g4 hit node " <<
hitnodename << std::endl;
375 findNode::getClass<PHG4TruthInfoContainer>(topNode,
"G4TruthInfo");
377 m_tGeometry = findNode::getClass<ActsGeometry>(topNode,
"ActsGeometry");
381 <<
"ActsGeometry not found on node tree. Exiting"
387 unsigned int count_g4hits = 0;
391 int ncollectedhits = 0;
393 unsigned int dump_interval = 5000;
394 unsigned int dump_counter = 0;
398 PHG4Hit* prior_g4hit =
nullptr;
402 for (
auto hiter = hit_begin_end.first; hiter != hit_begin_end.second; ++hiter)
407 const double t0 = fmax(hiter->second->get_t(0), hiter->second->get_t(1));
413 int trkid_new = hiter->second->
get_trkid();
414 if (trkid != trkid_new)
416 prior_g4hit =
nullptr;
420 if (
Verbosity() > 1000) std::cout <<
" New track : " << trkid <<
" is embed? : ";
425 if (
Verbosity() > 1000) { std::cout <<
" YES embedded" << std::endl; }
429 if (
Verbosity() > 1000) { std::cout <<
" NOT embedded" << std::endl; }
446 prior_g4hit = hiter->second;
454 double eion = hiter->second->
get_eion();
459 std::cout <<
" new hit with t0, " << t0 <<
" g4hitid " << hiter->first
460 <<
" eion " << eion <<
" n_electrons " << n_electrons
461 <<
" entry z " << hiter->second->get_z(0) <<
" exit z "
462 << hiter->second->get_z(1) <<
" avg z"
463 << (hiter->second->get_z(0) + hiter->second->get_z(1)) / 2.0
466 if (n_electrons == 0) {
continue; }
470 std::cout << std::endl
471 <<
"electron drift: g4hit " << hiter->first <<
" created electrons: "
472 << n_electrons <<
" from " << eion * 1000000 <<
" keV" << std::endl;
473 std::cout <<
" entry x,y,z = " << hiter->second->get_x(0) <<
" "
474 << hiter->second->get_y(0) <<
" " << hiter->second->get_z(0)
475 <<
" radius " << sqrt(pow(hiter->second->get_x(0), 2) +
476 pow(hiter->second->get_y(0), 2)) << std::endl;
477 std::cout <<
" exit x,y,z = " << hiter->second->get_x(1) <<
" "
478 << hiter->second->get_y(1) <<
" " << hiter->second->get_z(1)
479 <<
" radius " << sqrt(pow(hiter->second->get_x(1), 2) +
480 pow(hiter->second->get_y(1), 2)) << std::endl;
483 for (
unsigned int i = 0;
i < n_electrons;
i++)
491 const double x_start = hiter->second->get_x(0) + f * (hiter->second->get_x(1) - hiter->second->get_x(0));
492 const double y_start = hiter->second->get_y(0) + f * (hiter->second->get_y(1) - hiter->second->get_y(0));
493 const double z_start = hiter->second->get_z(0) + f * (hiter->second->get_z(1) - hiter->second->get_z(0));
494 const double t_start = hiter->second->get_t(0) + f * (hiter->second->get_t(1) - hiter->second->get_t(0));
496 unsigned int side = 0;
497 if (z_start > 0) side = 1;
500 const double rantrans =
506 const double rantime =
509 double t_final = t_start + t_path + rantime;
511 if (t_final < min_time || t_final >
max_time)
continue;
519 const double radstart = std::sqrt(
square(x_start) +
square(y_start));
520 const double phistart = std::atan2(y_start, x_start);
521 const double ranphi = gsl_ran_flat(
RandomGenerator.get(), -M_PI, M_PI);
523 double x_final = x_start + rantrans * std::cos(ranphi);
524 double y_final = y_start + rantrans * std::sin(ranphi);
526 double rad_final = sqrt(
square(x_final) +
square(y_final));
527 double phi_final = atan2(y_final, x_final);
539 const double reaches =
m_distortionMap->get_reaches_readout(radstart, phistart, z_start);
545 const double r_distortion =
m_distortionMap->get_r_distortion(radstart, phistart, z_start);
546 const double phi_distortion =
m_distortionMap->get_rphi_distortion(radstart, phistart, z_start) / radstart;
547 const double z_distortion =
m_distortionMap->get_z_distortion(radstart, phistart, z_start);
549 rad_final += r_distortion;
550 phi_final += phi_distortion;
551 z_final += z_distortion;
555 t_final = (
tpc_length / 2.0 - z_final) / drift_velocity;
557 x_final = rad_final * std::cos(phi_final);
558 y_final = rad_final * std::sin(phi_final);
562 const double phi_final_nodiff = phistart + phi_distortion;
563 const double rad_final_nodiff = radstart + r_distortion;
564 deltarnodiff->Fill(radstart, rad_final_nodiff - radstart);
567 deltaRphinodiff->Fill(radstart, rad_final_nodiff * phi_final_nodiff - radstart * phistart);
572 deltar->Fill(radstart, rad_final - radstart);
573 deltaphi->Fill(phistart, phi_final - phistart);
574 deltaz->Fill(z_start, z_distortion);
584 std::cout <<
"electron " <<
i <<
" g4hitid " << hiter->first <<
" f " << f << std::endl;
585 std::cout <<
"radstart " << radstart <<
" x_start: " << x_start
586 <<
", y_start: " << y_start
587 <<
",z_start: " << z_start
588 <<
" t_start " << t_start
589 <<
" t_path " << t_path
590 <<
" t_sigma " << t_sigma
591 <<
" rantime " << rantime
594 std::cout <<
" rad_final " << rad_final <<
" x_final " << x_final
595 <<
" y_final " << y_final
596 <<
" z_final " << z_final <<
" t_final " << t_final
597 <<
" zdiff " << z_final - z_start << std::endl;
603 nt->Fill(ihit, t_start, t_final, t_sigma, rad_final, z_start, z_final);
612 single_hitset_iter != single_hitset_range.second;
613 ++single_hitset_iter)
622 std::cout <<
" hitsetkey " << node_hitsetkey <<
" layer " << layer <<
" sector " << sector <<
" side " << side << std::endl;
626 single_hit_iter != single_hit_range.second;
635 std::cout <<
" adding assoc for node_hitsetkey " << node_hitsetkey <<
" single_hitkey " << single_hitkey <<
" g4hitkey " << hiter->first << std::endl;
642 if (dump_counter >= dump_interval || count_g4hits == g4hit->size())
649 temp_hitset_iter != temp_hitset_range.second;
658 std::cout <<
"PHG4TpcElectronDrift: temp_hitset with key: " << node_hitsetkey <<
" in layer " << layer
659 <<
" with sector " << sector <<
" side " << side << std::endl;
667 temp_hit_iter != temp_hit_range.second;
671 TrkrHit *temp_tpchit = temp_hit_iter->second;
672 if (
Verbosity() > 10 && layer == print_layer)
674 std::cout <<
" temp_hitkey " << temp_hitkey <<
" layer " << layer <<
" pad " <<
TpcDefs::getPad(temp_hitkey)
676 <<
" energy " << temp_tpchit->
getEnergy() <<
" eg4hit " << eg4hit << std::endl;
684 TrkrHit *node_hit = node_hitsetit->second->getHit(temp_hitkey);
689 node_hitsetit->second->addHitSpecificKey(temp_hitkey, node_hit);
697 if (
Verbosity() > 100 && layer == print_layer)
698 std::cout <<
" ihit " << ihit <<
" collected energy = " << eg4hit << std::endl;
720 std::cout <<
"From PHG4TpcElectronDrift: hitsetcontainer printout at end:" << std::endl;
724 hitset_iter != hitset_range.second;
730 if (layer != print_layer)
continue;
734 std::cout <<
"PHG4TpcElectronDrift: hitset with key: " << hitsetkey <<
" in layer " << layer <<
" with sector " << sector <<
" side " << side << std::endl;
740 hit_iter != hit_range.second;
744 TrkrHit *tpchit = hit_iter->second;
746 <<
" energy " << tpchit->
getEnergy() << std::endl;
753 std::cout <<
"From PHG4TpcElectronDrift: hittruthassoc dump:" << std::endl;
763 std::cout <<
" TruthTrackContainer results at end of event in PHG4TpcElectronDrift::process_event " << std::endl;
794 EDrift_outf.reset(
new TFile(
"ElectronDriftQA.root",
"recreate"));
824 static constexpr
double Ne_dEdx = 1.56;
825 static constexpr
double CF4_dEdx = 7.00;
830 static constexpr
double Tpc_NTot = 0.5 * Ne_NTotal + 0.5 *
CF4_NTotal;
831 static constexpr
double Tpc_dEdx = 0.5 * Ne_dEdx + 0.5 *
CF4_dEdx;
832 static constexpr
double Tpc_ElectronsPerKeV = Tpc_NTot / Tpc_dEdx;
858 if (
Verbosity()) std::cout <<
"Registering padplane " << std::endl;
861 padplane->UpdateInternalParameters();
862 if (
Verbosity()) std::cout <<
"padplane registered and parameters updated" << std::endl;