ImpactZipper.cxx
Go to the documentation of this file.
2 #include "WireCellUtil/Testing.h"
3 
4 #include <iostream> // debugging.
5 using namespace std;
6 
7 using namespace WireCell;
8 Gen::ImpactZipper::ImpactZipper(IPlaneImpactResponse::pointer pir, BinnedDiffusion& bd)
9  :m_pir(pir), m_bd(bd)
10 {
11 
12 }
13 
14 
15 
17 {
18 }
19 
20 
22 {
23  const double pitch_range = m_pir->pitch_range();
24 
25  const auto pimpos = m_bd.pimpos();
26  const auto rb = pimpos.region_binning();
27  const auto ib = pimpos.impact_binning();
28  const double wire_pos = rb.center(iwire);
29 
30  const int min_impact = ib.edge_index(wire_pos - 0.5*pitch_range);
31  const int max_impact = ib.edge_index(wire_pos + 0.5*pitch_range);
32  const int nsamples = m_bd.tbins().nbins();
33  Waveform::compseq_t total_spectrum(nsamples, Waveform::complex_t(0.0,0.0));
34 
35 
36  int nfound=0;
37  const bool share=true;
38  const Waveform::complex_t complex_one_half(0.5,0.0);
39 
40  // The BinnedDiffusion is indexed by absolute impact and the
41  // PlaneImpactResponse relative impact.
42  for (int imp = min_impact; imp <= max_impact; ++imp) {
43 
44  // ImpactData
45  auto id = m_bd.impact_data(imp);
46  if (!id) {
47  // common as we are scanning all impacts covering a wire
48  // fixme: is there a way to predict this to avoid the query?
49  //std::cerr << "ImpactZipper: no data for absolute impact number: " << imp << std::endl;
50  continue;
51  }
52 
53  const Waveform::compseq_t& charge_spectrum = id->spectrum();
54  // for interpolation
55  const Waveform::compseq_t& weightcharge_spectrum = id->weight_spectrum();
56 
57  if (charge_spectrum.empty()) {
58  // should not happen
59  std::cerr << "ImpactZipper: no charge for absolute impact number: " << imp << std::endl;
60  continue;
61  }
62  if (weightcharge_spectrum.empty()) {
63  // weight == 0, should not happen
64  std::cerr << "ImpactZipper: no weight charge for absolute impact number: " << imp << std::endl;
65  continue;
66  }
67 
68  const double imp_pos = ib.center(imp);
69  const double rel_imp_pos = imp_pos - wire_pos;
70  //std::cerr << "IZ: " << " imp=" << imp << " imp_pos=" << imp_pos << " rel_imp_pos=" << rel_imp_pos << std::endl;
71 
72  Waveform::compseq_t conv_spectrum(nsamples, Waveform::complex_t(0.0,0.0));
73  if (share) { // fixme: make a configurable option
74  TwoImpactResponses two_ir = m_pir->bounded(rel_imp_pos);
75  if (!two_ir.first || !two_ir.second) {
76  //std::cerr << "ImpactZipper: no impact response for absolute impact number: " << imp << std::endl;
77  continue;
78  }
79  // fixme: this is average, not interpolation.
80  Waveform::compseq_t rs1 = two_ir.first->spectrum();
81  Waveform::compseq_t rs2 = two_ir.second->spectrum();
82 
83  for (int ind=0; ind < nsamples; ++ind) {
84  //conv_spectrum[ind] = complex_one_half*(rs1[ind]+rs2[ind])*charge_spectrum[ind];
85 
86  // linear interpolation: wQ*rs1 + (Q-wQ)*rs2
87  conv_spectrum[ind] = weightcharge_spectrum[ind]*rs1[ind]+(charge_spectrum[ind]-weightcharge_spectrum[ind])*rs2[ind];
88  /* debugging */
89  /* if(iwire == 1000 && ind>1000 && ind<2000) { */
90  /* std::cerr<<"rs1 spectrum: "<<imp<<"|"<<ind<<": "<<std::abs(rs1[ind])<<std::endl; */
91  /* std::cerr<<"rs2 spectrum: "<<imp<<"|"<<ind<<": "<<std::abs(rs2[ind])<<std::endl; */
92  /* std::cerr<<"rs1 charge spectrum "<<ind<<": "<<weightcharge_spectrum[ind]<<std::endl; */
93  /* std::cerr<<"rs2 charge spectrum "<<ind<<": "<<charge_spectrum[ind]-weightcharge_spectrum[ind]<<std::endl; */
94  /* //std::cerr<<"rs1 charge spectrum "<<ind<<": "<<complex_one_half*charge_spectrum[ind]<<std::endl; */
95  /* //std::cerr<<"rs2 charge spectrum "<<ind<<": "<<complex_one_half*charge_spectrum[ind]<<std::endl; */
96  /* } */
97  }
98  }
99  else {
100  auto ir = m_pir->closest(rel_imp_pos);
101  if (! ir) {
102  // std::cerr << "ImpactZipper: no impact response for absolute impact number: " << imp << std::endl;
103  continue;
104  }
105  Waveform::compseq_t response_spectrum = ir->spectrum();
106  for (int ind=0; ind < nsamples; ++ind) {
107  conv_spectrum[ind] = response_spectrum[ind]*charge_spectrum[ind];
108  }
109  }
110 
111  ++nfound;
112  // std::cerr << "ImpactZipper: found:"<<nfound<<" for absolute impact number " << imp
113  // << " csize=" << csize << " rsize=" << rsize << " rebin=" << rebinfactor
114  // << std::endl;
115 
116  Waveform::increase(total_spectrum, conv_spectrum);
117  }
118  //std::cerr << "ImpactZipper: found " << nfound << " in abs impact: [" << min_impact << ","<< max_impact << "]\n";
119 
120  // Clear memory assuming next call is iwire+1.
121  // fixme: this is a dumb way to go. Better to make an iterator.
122  m_bd.erase(0, min_impact);
123 
124  if (!nfound) {
125  return Waveform::realseq_t(nsamples, 0.0);
126  }
127 
128  auto waveform = Waveform::idft(total_spectrum);
129 
130  return waveform;
131 }
Sequence< real_t > realseq_t
Definition: Waveform.h:31
double center(int ind) const
Definition: Binning.h:86
const Binning & region_binning() const
Definition: Pimpos.h:109
STL namespace.
void erase(int begin_impact_index, int end_impact_index)
IPlaneImpactResponse::pointer m_pir
Definition: ImpactZipper.h:18
const Binning & impact_binning() const
Definition: Pimpos.h:113
void increase(Sequence< Val > &seq, Val scalar)
Increase (shift) sequence values by scalar.
Definition: Waveform.h:129
std::pair< IImpactResponse::pointer, IImpactResponse::pointer > TwoImpactResponses
const Pimpos & pimpos() const
std::shared_ptr< Interface > pointer
Definition: Interface.h:16
ImpactData::pointer impact_data(int bin) const
Definition: Main.h:22
realseq_t idft(compseq_t spec)
Definition: Waveform.cxx:149
Pimpos pimpos(nwires, min_wire_pitch, max_wire_pitch)
const Binning & tbins() const
Waveform::realseq_t waveform(int wire) const
BinnedDiffusion & m_bd
Definition: ImpactZipper.h:19
std::complex< float > complex_t
The type for the spectrum in each bin.
Definition: Waveform.h:21
int nbins() const
Definition: Binning.h:42
Sequence< complex_t > compseq_t
A complex-valued sequence, eg for discrete spectrum powers.
Definition: Waveform.h:34
QTextStream & endl(QTextStream &s)