17 if (m_spectrum.size()!=0){
35 : m_frname(
"FieldResponse")
36 , m_plane_ident(plane_ident)
53 cfg[
"short_responses"] = Json::arrayValue;
54 cfg[
"overall_short_padding"] = 100*
units::us;
55 cfg[
"long_responses"] = Json::arrayValue;
58 cfg[
"nticks"] = 10000;
70 auto jfilts = cfg[
"short_responses"];
71 if (!jfilts.isNull() and !jfilts.empty()) {
72 for (
auto jfn: jfilts) {
73 auto tn = jfn.asString();
79 auto jfilts1 = cfg[
"long_responses"];
80 if (!jfilts1.isNull() and !jfilts1.empty()) {
81 for (
auto jfn: jfilts1) {
82 auto tn = jfn.asString();
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) {
264 const int center_wire =
nwires()/2;
266 const int relwire =
int(round(relpitch/
m_pitch));
267 const int wire_index = center_wire + relwire;
269 const double remainder_pitch = relpitch - relwire*
m_pitch;
272 return std::make_pair(wire_index, impact_index);
281 if (wi.first < 0 || wi.first >= (
int)
m_bywire.size()) {
282 l->debug(
"PIR: closest relative pitch:{} outside of wire range: {}",
286 const std::vector<int>& region =
m_bywire[wi.first];
287 if (wi.second < 0 || wi.second >= (
int)region.size()) {
288 l->debug(
"PIR: relative pitch:{} outside of impact range: {}",
289 relpitch, wi.second);
292 int irind = region[wi.second];
293 if (irind < 0 || irind > (
int)
m_ir.size()) {
294 l->debug(
"PIR: relative pitch:{} no impact response for region: {}",
311 if (wi.second == 0) {
312 return std::make_pair(
m_ir[region[0]],
m_ir[region[1]]);
314 if (wi.second == (
int)region.size()-1) {
315 return std::make_pair(
m_ir[region[wi.second-1]],
m_ir[region[wi.second]]);
318 const double absimpact = m_half_extent + relpitch - wi.first*
m_pitch;
int nwires() const
The number of wires that span the pitch range.
double m_overall_short_padding
virtual WireCell::Configuration default_configuration() const
Optional, override to return a hard-coded default configuration.
double center(int ind) const
Waveform::compseq_t m_long_spectrum
boost::error_info< struct tag_errmsg, std::string > errmsg
std::size_t fft_best_length(size_t nsamples, bool keep_odd_even=false)
PlaneImpactResponse(int plane_ident=0, size_t nbins=10000, double tick=0.5 *units::us)
virtual IImpactResponse::pointer closest(double relpitch) const
Configuration find(Configuration &lst, const std::string &dotpath, const T &val)
Return dictionary in given list if it value at dotpath matches.
std::pair< IImpactResponse::pointer, IImpactResponse::pointer > TwoImpactResponses
std::pair< int, int > closest_wire_impact(double relpitch) const
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.
std::shared_ptr< Interface > pointer
static int max(int a, int b)
logptr_t logger(std::string name)
Thrown when a wrong value has been encountered.
Waveform::realseq_t m_long_waveform
std::vector< std::string > m_short
virtual TwoImpactResponses bounded(double relpitch) const
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
int nimp_per_wire() const
not in the interface
wire_region_indicies_t m_bywire
WIRECELL_FACTORY(PlaneImpactResponse, WireCell::Gen::PlaneImpactResponse, WireCell::IPlaneImpactResponse, WireCell::IConfigurable) using namespace std
Json::Value Configuration
QTextStream & bin(QTextStream &s)
array_xxc dft(const array_xxf &arr)
virtual void configure(const WireCell::Configuration &cfg)
Accept a configuration.