99 auto ifr = Factory::find_tn<IFieldResponse>(
m_frname);
105 const size_t nshort =
m_short.size();
106 for (
size_t ind=0; ind<nshort; ++ind) {
108 auto iw = Factory::find_tn<IWaveform>(
name);
110 l->critical(
"from {} got {} us sample period expected {} us",
114 auto wave = iw->waveform_samples();
115 if (wave.size() != n_short_length) {
116 l->debug(
"PIR: short response {} has different number of samples ({}) than expected ({})",
name, wave.
size(), n_short_length);
117 wave.resize(n_short_length, 0);
122 for (
size_t ibin=0; ibin < n_short_length; ++ibin) {
123 short_spec[ibin] *= spec[ibin];
131 const size_t nlong =
m_long.size();
132 for (
size_t ind=0; ind<nlong; ++ind) {
134 auto iw = Factory::find_tn<IWaveform>(
name);
136 l->critical(
"from {} got {} us sample period expected {} us",
140 auto wave = iw->waveform_samples();
141 if (wave.size() != n_long_length) {
142 l->debug(
"PIR: long response {} has different number of samples ({}) than expected ({})",
name, wave.
size(), n_long_length);
143 wave.resize(n_long_length, 0);
148 for (
size_t ibin=0; ibin < n_long_length; ++ibin) {
149 long_spec[ibin] *= spec[ibin];
158 const auto& fr = ifr->field_response();
160 const int npaths = pr.paths.size();
172 const int n_wires = npaths/n_per;
173 const int n_wires_half = n_wires / 2;
180 std::abs(pr.paths.back().pitchpos));
182 m_pitch = 2.0*
std::abs(pr.paths[n_per-1].pitchpos - pr.paths[0].pitchpos);
186 const int rawresp_size = pr.paths[0].current.size();
187 const double rawresp_min = fr.tstart;
188 const double rawresp_tick = fr.period;
189 const double rawresp_max = rawresp_min + rawresp_size*rawresp_tick;
190 Binning rawresp_bins(rawresp_size, rawresp_min, rawresp_max);
193 std::map<int, region_indices_t> wire_to_ind;
194 for (
int ipath = 0; ipath < npaths; ++ipath) {
196 const int wirenum =
int(ceil(path.
pitchpos/pr.pitch));
197 wire_to_ind[wirenum].push_back(ipath);
201 for (
int rind=0; rind<rawresp_size; ++rind) {
202 const double time = rawresp_bins.center(rind);
207 if (bin>= n_short_length) {
208 l->warn(
"PIR: out of bounds field response bin={}, ntbins={}, time={} us, tick={} us", bin, n_short_length, time/
units::us,
m_tick/
units::us);
215 const double induced_current = path.
current[rind];
219 const double induced_charge = induced_current*rawresp_tick;
222 wave[
bin] += induced_charge;
240 for (
int irelwire=-n_wires_half; irelwire <= n_wires_half; ++irelwire) {
241 auto direct = wire_to_ind[irelwire];
242 auto other = wire_to_ind[-irelwire];
244 std::vector<int>
indices(direct.begin(), direct.end());
245 for (
auto it =
other.rbegin()+1; it !=
other.rend(); ++it) {
double m_overall_short_padding
std::shared_ptr< IImpactResponse > pointer
Access subclass facet by pointer.
boost::error_info< struct tag_errmsg, std::string > errmsg
std::size_t fft_best_length(size_t nsamples, bool keep_odd_even=false)
Configuration find(Configuration &lst, const std::string &dotpath, const T &val)
Return dictionary in given list if it value at dotpath matches.
double pitchpos
The position in the pitch direction to the starting point of the path.
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
static int max(int a, int b)
Thrown when a wrong value has been encountered.
std::vector< std::string > m_short
WireCell::Waveform::realseq_t current
An array holding the induced current for the path on the wire-of-interest.
std::vector< std::string > m_long
std::vector< IImpactResponse::pointer > m_ir
wire_region_indicies_t m_bywire
QTextStream & bin(QTextStream &s)