32 #include <gsl/gsl_randist.h>
33 #include <gsl/gsl_rng.h>
59 inline T gaus(
const T &x,
const T &
sigma)
61 return std::exp(-
square(x / sigma) / 2) / (sigma * std::sqrt(2 * M_PI));
64 static constexpr
unsigned int print_layer = 18;
97 const std::string seggeonodename =
"CYLINDERCELLGEOM_SVTX";
98 GeomContainer = findNode::getClass<PHG4TpcCylinderGeomContainer>(topNode, seggeonodename);
127 const double x_gem,
const double y_gem,
const double t_gem,
const unsigned int side,
134 double phi = atan2(y_gem, x_gem);
135 if (phi > +M_PI) phi -= 2 * M_PI;
136 if (phi < -M_PI) phi += 2 * M_PI;
138 double rad_gem =
get_r( x_gem, y_gem );
141 for (
int iregion = 0; iregion < 3; ++iregion)
144 if(iregion==0 || iregion==2){
150 if( rad_gem <=
MinRadius[iregion]-daR/2){
151 rad_gem =
MinRadius[iregion] - (1.1*daR) ;
161 unsigned int layernum = 0;
168 layeriter != layerrange.second;
171 double rad_low = layeriter->second->get_radius() - layeriter->second->get_thickness() / 2.0;
172 double rad_high = layeriter->second->get_radius() + layeriter->second->get_thickness() / 2.0;
174 if (rad_gem > rad_low && rad_gem < rad_high)
183 std::cout <<
" g4hit id " << hiter->first <<
" rad_gem " << rad_gem <<
" rad_low " << rad_low <<
" rad_high " << rad_high
184 <<
" layer " << hiter->second->get_layer() <<
" want to change to " << layernum << std::endl;
185 hiter->second->set_layer(layernum);
213 double phi_gain =
phi;
214 if(phi<0)phi_gain += 2*M_PI;
215 double gain_weight = 1.0;
217 nelec = nelec*gain_weight;
225 std::cout <<
" populate phi bins for "
226 <<
" layernum " << layernum
232 std::vector<int> pad_phibin;
233 std::vector<double> pad_phibin_share;
244 for (
unsigned int ipad = 0; ipad < pad_phibin.size(); ++ipad)
246 double pad_share = pad_phibin_share[ipad];
249 for (
unsigned int iphi = 0; iphi < pad_phibin.size(); ++iphi)
250 pad_phibin_share[iphi] /= norm1;
254 if (
Verbosity() > 100 && layernum == print_layer)
255 std::cout <<
" populate t bins for layernum " << layernum
256 <<
" with t_gem " << t_gem <<
" sigmaL[0] " <<
sigmaL[0] <<
" sigmaL[1] " <<
sigmaL[1] << std::endl;
258 std::vector<int> adc_tbin;
259 std::vector<double> adc_tbin_share;
269 for (
unsigned int it = 0;
it < adc_tbin.size(); ++
it)
271 double bin_share = adc_tbin_share[
it];
274 for (
unsigned int it = 0;
it < adc_tbin.size(); ++
it)
275 adc_tbin_share[
it] /= tnorm;
280 double phi_integral = 0.0;
281 double t_integral = 0.0;
284 for (
unsigned int ipad = 0; ipad < pad_phibin.size(); ++ipad)
286 int pad_num = pad_phibin[ipad];
287 double pad_share = pad_phibin_share[ipad];
289 for (
unsigned int it = 0;
it < adc_tbin.size(); ++
it)
291 int tbin_num = adc_tbin[
it];
292 double adc_bin_share = adc_tbin_share[
it];
295 float neffelectrons = nelec * (pad_share) * (adc_bin_share);
298 if (tbin_num >= tbins) std::cout <<
" Error making key: adc_tbin " << tbin_num <<
" ntbins " << tbins << std::endl;
299 if (pad_num >=
phibins) std::cout <<
" Error making key: pad_phibin " << pad_num <<
" nphibins " <<
phibins << std::endl;
306 phi_integral += phicenter * neffelectrons;
307 t_integral += tcenter * neffelectrons;
308 weight += neffelectrons;
309 if (
Verbosity() > 1 && layernum == print_layer)
310 std::cout <<
" tbin_num " << tbin_num <<
" tcenter " << tcenter <<
" pad_num " << pad_num <<
" phicenter " << phicenter
322 unsigned int pads_per_sector =
phibins / 12;
323 unsigned int sector = pad_num / pads_per_sector;
333 hit = hitsetit->second->getHit(hitkey);
338 hitsetit->second->addHitSpecificKey(hitkey, hit);
343 tpc_truth_clusterer.
addhitset(hitsetkey, hitkey, neffelectrons);
348 single_hit = single_hitsetit->second->getHit(hitkey);
353 single_hitsetit->second->addHitSpecificKey(hitkey, single_hit);
381 if (layernum == print_layer)
383 std::cout <<
" hit " <<
m_NHits <<
" quick centroid for this electron " << std::endl;
384 std::cout <<
" phi centroid = " << phi_integral / weight <<
" phi in " << phi <<
" phi diff " << phi_integral / weight - phi << std::endl;
385 std::cout <<
" t centroid = " << t_integral / weight <<
" t in " << t_gem <<
" t diff " << t_integral / weight - t_gem << std::endl;
401 double new_phi =
phi;
403 for (
int iregion = 0; iregion < 3; ++iregion)
410 for(
int s=0;
s<12;
s++)
421 if (new_phi<=max_phi && new_phi>=min_phi)
423 if(fabs(max_phi - new_phi) > fabs(new_phi - min_phi))
432 { new_phi += 2*M_PI; }
445 double rphi = phi * radius;
449 std::cout <<
" populate_zigzag_phibins for layer " << layernum <<
" with radius " << radius <<
" phi " << phi
450 <<
" rphi " << rphi <<
" phistepsize " << phistepsize << std::endl;
451 std::cout <<
" fcharge created: radius " << radius <<
" rphi " << rphi <<
" cloud_sig_rp " << cloud_sig_rp << std::endl;
455 const double philim_low_calc = phi - (
_nsigmas * cloud_sig_rp / radius) - phistepsize;
456 const double philim_high_calc = phi + (
_nsigmas * cloud_sig_rp / radius) + phistepsize;
459 const double philim_low =
check_phi(side, philim_low_calc, radius);
460 const double philim_high =
check_phi(side, philim_high_calc, radius);
464 int npads = phibin_high - phibin_low;
468 if (layernum == print_layer)
469 std::cout <<
" zigzags: phi " << phi <<
" philim_low " << philim_low <<
" phibin_low " << phibin_low
470 <<
" philim_high " << philim_high <<
" phibin_high " << phibin_high <<
" npads " << npads << std::endl;
472 if (npads < 0 || npads > 9) npads = 9;
478 using PadParameterSet = std::array<double, 2>;
479 std::array<PadParameterSet, 10> pad_parameters;
480 std::array<int, 10> pad_keep;
484 std::array<double, 10> overlap = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
485 double pads_phi[10] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0.};
486 double sum_of_pads_phi = 0.;
487 double sum_of_pads_absphi = 0.;
488 for (
int ipad = 0; ipad <= npads; ipad++)
490 int pad_now = phibin_low + ipad;
493 sum_of_pads_phi += pads_phi[ipad];
494 sum_of_pads_absphi += fabs(pads_phi[ipad]);
497 for (
int ipad = 0; ipad <= npads; ipad++)
499 int pad_now = phibin_low + ipad;
504 pad_keep[ipad] = pad_now;
505 double phi_now = pads_phi[ipad];
506 const double rphi_pad_now = phi_now * radius;
507 pad_parameters[ipad] = {{pad_rphi / 2.0, rphi_pad_now}};
510 if (layernum == print_layer)
511 std::cout <<
" zigzags: make fpad for ipad " << ipad <<
" pad_now " << pad_now <<
" pad_rphi/2 " << pad_rphi / 2.0
512 <<
" rphi_pad_now " << rphi_pad_now << std::endl;
522 const double pitch = pad_rphi / 2.0;
523 double x_loc_tmp = rphi_pad_now - rphi;
524 const double sigma = cloud_sig_rp;
527 if(fabs(sum_of_pads_phi)!= sum_of_pads_absphi){
528 if(phi<-M_PI/2 && phi_now>0){
529 x_loc_tmp = (phi_now - 2*M_PI) * radius - rphi;
531 if(phi>M_PI/2 && phi_now<0){
532 x_loc_tmp = (phi_now + 2*M_PI) * radius - rphi;
534 if(phi<0 && phi_now>0){
535 x_loc_tmp = (phi_now+fabs(phi)) * radius;
537 if(phi>0 && phi_now<0){
538 x_loc_tmp = (2*M_PI - phi_now +
phi) * radius;
542 const double x_loc = x_loc_tmp;
549 (pitch - x_loc) * (std::erf(x_loc / (M_SQRT2 * sigma)) - std::erf((x_loc - pitch) / (M_SQRT2 *
sigma))) / (pitch * 2) + (pitch + x_loc) * (std::erf((x_loc + pitch) / (M_SQRT2 *
sigma)) - std::erf(x_loc / (M_SQRT2 * sigma))) / (pitch * 2) + (gaus(x_loc - pitch, sigma) - gaus(x_loc, sigma)) *
square(sigma) / pitch + (gaus(x_loc + pitch, sigma) - gaus(x_loc, sigma)) *
square(sigma) / pitch;
554 for (
int ipad = 0; ipad <= npads; ipad++)
556 phibin_pad.push_back(pad_keep[ipad]);
557 phibin_pad_share.push_back(overlap[ipad]);
576 std::cout <<
" input: t " << t <<
" tbin " << tbin <<
" tstepsize " << tstepsize <<
" t center " <<
LayerGeom->
get_zcenter(tbin) <<
" tdisp " << tdisp << std::endl;
579 int min_cell_tbin = 0;
580 int max_cell_tbin =
NTBins - 1;
582 double cloud_sig_tt_inv[2];
583 cloud_sig_tt_inv[0] = 1. / cloud_sig_tt[0];
584 cloud_sig_tt_inv[1] = 1. / cloud_sig_tt[1];
592 int n_zz = int(3 * (cloud_sig_tt[0] + cloud_sig_tt[1]) / (2.0 * tstepsize) + 1);
593 if (
Verbosity() > 1000) std::cout <<
" n_zz " << n_zz <<
" cloud_sigzz[0] " << cloud_sig_tt[0] <<
" cloud_sig_tt[1] " << cloud_sig_tt[1] << std::endl;
594 for (
int it = -n_zz;
it != n_zz + 1; ++
it)
596 int cur_t_bin = tbin +
it;
597 if ((cur_t_bin < min_cell_tbin) || (cur_t_bin > max_cell_tbin))
continue;
600 std::cout <<
" it " << it <<
" cur_t_bin " << cur_t_bin <<
" min_cell_tbin " << min_cell_tbin <<
" max_cell_tbin " << max_cell_tbin << std::endl;
602 double t_integral = 0.0;
620 double tLim2 = 0.5 * M_SQRT2 * (-0.5 * tstepsize - tdisp) * cloud_sig_tt_inv[index1];
622 double t_integral1 = 0.5 * (erf(tLim1) - erf(tLim2));
626 std::cout <<
" populate_tbins: cur_t_bin " << cur_t_bin <<
" center t " <<
LayerGeom->
get_zcenter(cur_t_bin)
627 <<
" index1 " << index1 <<
" tLim1 " << tLim1 <<
" tLim2 " << tLim2 <<
" t_integral1 " << t_integral1 << std::endl;
630 tLim1 = 0.5 * M_SQRT2 * (0.5 * tstepsize - tdisp) * cloud_sig_tt_inv[index2];
631 double t_integral2 = 0.5 * (erf(tLim1) - erf(tLim2));
635 std::cout <<
" populate_tbins: cur_t_bin " << cur_t_bin <<
" center t " <<
LayerGeom->
get_zcenter(cur_t_bin)
636 <<
" index2 " << index2 <<
" tLim1 " << tLim1 <<
" tLim2 " << tLim2 <<
" t_integral2 " << t_integral2 << std::endl;
638 t_integral = t_integral1 + t_integral2;
659 double tLim1 = 0.5 * M_SQRT2 * ((it + 0.5) * tstepsize - tdisp) * cloud_sig_tt_inv[index];
660 double tLim2 = 0.5 * M_SQRT2 * ((it - 0.5) * tstepsize - tdisp) * cloud_sig_tt_inv[index];
661 t_integral = 0.5 * (erf(tLim1) - erf(tLim2));
665 std::cout <<
" populate_tbins: t_bin " << cur_t_bin <<
" center t " <<
LayerGeom->
get_zcenter(cur_t_bin)
666 <<
" index " << index <<
" tLim1 " << tLim1 <<
" tLim2 " << tLim2 <<
" t_integral " << t_integral << std::endl;
669 tbin_adc.push_back(cur_t_bin);
670 tbin_adc_share.push_back(t_integral);
686 char *calibrationsroot = getenv(
"CALIBRATIONROOT");
687 if (calibrationsroot !=
nullptr)
690 TFile *fileGain = TFile::Open(gain_maps_filename.c_str(),
"READ");
691 h_gain[0] = (TH2F*)fileGain->Get(
"RadPhiPlot0")->Clone();
692 h_gain[1] = (TH2F*)fileGain->Get(
"RadPhiPlot1")->Clone();
693 h_gain[0]->SetDirectory(
nullptr);
694 h_gain[1]->SetDirectory(
nullptr);
764 const double TBinWidth = tpc_adc_clock;
766 const double MinT = 0;
767 NTBins = (int) ((MaxT - MinT) / TBinWidth) + 1;
769 const std::array<double, 3> SectorPhi =
774 const std::array<int,3> NPhiBins =
783 SectorPhi[0] * 12 / (
double) NPhiBins[0],
784 SectorPhi[1] * 12 / (
double) NPhiBins[1],
785 SectorPhi[2] * 12 / (
double) NPhiBins[2]
790 for (
int iregion = 0; iregion < 3; ++iregion)
792 for (
int zside = 0; zside < 2;zside++)
796 for (
int isector = 0; isector <
NSectors; ++isector)
798 double sec_gap = (2*M_PI - SectorPhi[iregion]*12)/12;
799 double sec_max_phi = M_PI - SectorPhi[iregion]/2 - sec_gap - 2 * M_PI / 12 * isector;
800 double sec_min_phi = sec_max_phi - SectorPhi[iregion];