351 auto geo = gar::providerFrom<geo::GeometryGAr>();
354 unsigned int chan = 0;
356 std::vector<edepIDE> edepIDEaccumulator;
360 rosim::ElectronDriftInfo driftInfo;
363 for (
size_t e = 0;
e < edepCol.size(); ++
e) {
367 fDriftAlg->DriftElectronsToReadout(edepCol[
e], driftInfo);
371 auto clusterXPos = driftInfo.ClusterXPos();
372 auto clusterYPos = driftInfo.ClusterYPos();
373 auto clusterZPos = driftInfo.ClusterZPos();
374 auto clusterTime = driftInfo.ClusterTime();
375 auto clusterSize = driftInfo.ClusterSize();
379 for (
size_t c = 0;
c < clusterXPos.size(); ++
c) {
381 xyz[0] = clusterXPos[
c];
382 xyz[1] = clusterYPos[
c];
383 xyz[2] = clusterZPos[
c];
389 geo->NearestChannelInfo(xyz, cwn);
396 if (chan ==
geo->GapChannelNumber())
continue;
402 TVector3
pos = cwn.at(0).pos;
403 TVector3 pproj(0,xyz[1],xyz[2]);
405 std::vector<float> chanweight;
406 size_t ncdistrib = cwn.size();
410 MF_LOG_DEBUG(
"IonizationReadout::DriftElectronsToReadout") <<
"pproj: " << pproj.Y() <<
" " << pproj.Z() <<
std::endl;
411 for (
size_t icd=0; icd<ncdistrib; ++icd) {
426 throw cet::exception(
"IonizationReadout::DriftElectronsToReadout") <<
"Ununderstood readout chamber type " 427 << cwn.at(icd).roctype <<
"\n";
429 TVector3 dproj = pproj - cwn.at(icd).pos;
431 MF_LOG_DEBUG(
"IonizationReadout::DriftElectronsToReadout") <<
" Pad loc: " << cwn.at(icd).pos.Y() <<
434 float dist_along_padrow = dproj.Dot(cwn.at(icd).padrowdir);
435 float dist_perp_padrow = (dproj - dist_along_padrow*cwn.at(icd).padrowdir).Mag();
436 MF_LOG_DEBUG(
"IonizationReadout::DriftElectronsToReadout") <<
"along, perp: " << dist_along_padrow <<
439 dist_along_padrow = TMath::Abs(dist_along_padrow);
440 if (dist_along_padrow < prfhist->GetXaxis()->GetBinUpEdge(prfhist->GetNbinsX()) &&
441 dist_perp_padrow < prfhist->GetYaxis()->GetBinUpEdge(prfhist->GetNbinsY())) {
442 chanweight.push_back(prfhist->GetBinContent(prfhist->FindBin(dist_along_padrow,dist_perp_padrow)));
444 chanweight.push_back(0);
447 sumw += chanweight.back();
451 throw cet::exception(
"IonizationReadout::DriftElectronsToReadout") <<
452 "Weight sum is zero, even when including the closest channel " <<
std::endl;
454 float rsumw = 1.0/sumw;
455 for (
size_t i=0; i<chanweight.size(); ++i) {
456 if (chanweight.at(i)>0 && clusterSize.at(
c) > 0) {
457 edepIDEaccumulator.emplace_back(clusterSize.at(
c)*chanweight.at(i)*rsumw,
460 e, chanweight.at(i));
463 "DriftElectronsToReadout");
465 if (edepIDEaccumulator.size() > 10000)
468 edepIDEs.insert(edepIDEs.end(),edepIDEaccumulator.begin(),edepIDEaccumulator.end());
469 edepIDEaccumulator.clear();
474 MF_LOG_DEBUG(
"IonizationReadout::DriftElectronsToReadout")
488 edepIDEs.insert(edepIDEs.end(),edepIDEaccumulator.begin(),edepIDEaccumulator.end());
std::vector< gar::geo::ChanWithPos > ChanWithNeighbors
TH2F * fIOROCPRF
pad response function for IOROC
TH2F * fHFILLPRF
pad response function for hole-filler chamber
const gar::detinfo::DetectorClocks * fTime
electronics clock
double TickPeriod() const
A single tick period in nano-second, frequency is in MHz.
virtual double G4ToElecTime(double g4_time) const =0
Given Geant4 time [ns], returns relative time [ns] w.r.t. electronics time T0.
bool fUsePRF
switch to turn on PRF modeling, otherwise just use the arrival pad
virtual double TPCG4Time2TDC(double g4time) const =0
Given G4 time [ns], returns corresponding TPC electronics clock count [tdc].
void CombineIDEs(std::vector< edepIDE > &edepIDEs, std::vector< sdp::EnergyDeposit > const &edepCol)
void CheckChannelToEnergyDepositMapping(unsigned int const &channel, sdp::EnergyDeposit const &edep, std::string const &id)
TH2F * fOOROCPRF
pad response function for OOROC
std::unique_ptr< ElectronDriftAlg > fDriftAlg
algorithm to drift ionization electrons
virtual const ElecClock & TPCClock() const =0
Borrow a const TPC clock with time set to Trigger time [ns].
TH2F * fIROCPRF
pad response function for IROC
LArSoft geometry interface.
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)