All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FFTTest_module.cc
Go to the documentation of this file.
1 //
2 // Name: FFTTest.h
3 //
4 // Purpose: FFTTest module. Test convolution/deconvolution.
5 //
6 // Created: 29-Aug-2011 H. Greenlee
7 
8 #include <iostream>
9 #include <algorithm>
10 
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Core/EDAnalyzer.h"
13 #include "art_root_io/TFileService.h"
14 #include "cetlib/search_path.h"
15 
17 
18 #include "TComplex.h"
19 #include "TFile.h"
20 #include "TH1D.h"
21 #include "TH2D.h"
22 
23 // Local functions.
24 
25 namespace {
26 
27  // Fill vector from histogram (ignore underflow/overflow bins).
28 
29  void hist_to_vector(const TH1D* h, std::vector<double>& v)
30  {
31  assert(h != 0);
32  int n = h->GetNbinsX();
33  v.resize(n);
34  for(int i=0; i<n; ++i)
35  v[i] = h->GetBinContent(i+1);
36  }
37 
38  // Fill histogram from vector (set underflow/overflow bins to zero).
39 
40  void vector_to_hist(const std::vector<double>& v, TH1D* h)
41  {
42  assert(h != 0);
43  int nvec = v.size();
44  int nbins = h->GetNbinsX();
45  int nfill = std::min(nvec, nbins);
46  h->SetBinContent(0, 0.);
47  for(int i=0; i<nfill; ++i)
48  h->SetBinContent(i+1, v[i]);
49  for(int i=nfill+1; i<=nbins+1; ++i)
50  h->SetBinContent(i, 0.);
51  }
52 
53  // Fill vector with initial delta-function at bin d.
54 
55  void fill_delta(std::vector<double>& v, int d)
56  {
57  int n = v.size();
58  assert(d >= 0 && d < n);
59  for(int i=0; i<n; ++i)
60  v[i] = 0.;
61  v[d] = 1.;
62  }
63 }
64 
65 namespace caldata
66 {
67  class FFTTest : public art::EDAnalyzer
68  {
69  public:
70 
71  // Constructor, destructor.
72 
73  explicit FFTTest(fhicl::ParameterSet const& pset);
74  virtual ~FFTTest();
75 
76  // Overrides.
77 
78  void analyze(const art::Event& evt);
79 
80  private:
81 
82  // Attributes.
83 
84  std::string fSimFile; // SimWire response file name.
85  std::string fCalFile; // CalWire response file name.
86  int fNTicks; // Number of ticks.
87 
88  // Time domain response functions.
89 
90  std::vector<double> fSimElect; // response function for the electronics
91  std::vector<double> fSimColField; // response function for the field @ collection plane
92  std::vector<double> fSimIndField; // response function for the field @ induction plane
93  std::vector<double> fSimColConv; // Collection plane convoluted response function.
94  std::vector<double> fSimIndConv; // Induction plane convoluted response function.
95 
96  // Frequency domain response functions.
97 
98  std::vector<TComplex> fSimElectF; // response function for the electronics
99  std::vector<TComplex> fSimColFieldF; // response function for the field @ collection plane
100  std::vector<TComplex> fSimIndFieldF; // response function for the field @ induction plane
101  std::vector<TComplex> fSimColConvF; // Collection plane convoluted response function.
102  std::vector<TComplex> fSimIndConvF; // Induction plane convoluted response function.
103  std::vector<TComplex> fColDeconvF; // Collection plane deconvolution.
104  std::vector<TComplex> fIndDeconvF; // Collection plane deconvolution.
105  };
106 
107  DEFINE_ART_MODULE(FFTTest)
108 
109  FFTTest::FFTTest(const fhicl::ParameterSet& pset)
110  : EDAnalyzer(pset)
111  {
112  // Get file service.
113 
114  art::ServiceHandle<art::TFileService> tfs;
115 
116  // Get FFT service.
117 
118  art::ServiceHandle<util::LArFFT> fFFT;
119  fNTicks = fFFT->FFTSize();
120  std::cout << "Number of ticks = " << fNTicks << std::endl;
121 
122  // Get simulation (convolution) response functions.
123 
124  fSimFile = pset.get<std::string>("simwire_file");
125  std::cout << "SimWire file = " << fSimFile << std::endl;
126 
127  TFile fsim(fSimFile.c_str());
128 
129  TH1D* hSimElect = dynamic_cast<TH1D*>(fsim.Get("daq/ElectronicsResponse"));
130  hist_to_vector(hSimElect, fSimElect);
131  fSimElect.resize(fNTicks, 0.);
132  fSimElectF.resize(fNTicks/2+1);
133  fFFT->DoFFT(fSimElect, fSimElectF);
134 
135  TH1D* hSimColField = dynamic_cast<TH1D*>(fsim.Get("daq/CollectionFieldResponse"));
136  hist_to_vector(hSimColField, fSimColField);
137  fSimColField.resize(fNTicks, 0.);
138  fSimColFieldF.resize(fNTicks/2+1);
139  fFFT->DoFFT(fSimColField, fSimColFieldF);
140 
141  TH1D* hSimIndField = dynamic_cast<TH1D*>(fsim.Get("daq/InductionFieldResponse"));
142  hist_to_vector(hSimIndField, fSimIndField);
143  fSimIndField.resize(fNTicks, 0.);
144  fSimIndFieldF.resize(fNTicks/2+1);
145  fFFT->DoFFT(fSimIndField, fSimIndFieldF);
146 
147  TH1D* hSimColConv = dynamic_cast<TH1D*>(fsim.Get("daq/ConvolutedCollection"));
148  hist_to_vector(hSimColConv, fSimColConv);
149  fSimColConv.resize(fNTicks, 0.);
150  fSimColConvF.resize(fNTicks/2+1);
151  fFFT->DoFFT(fSimColConv, fSimColConvF);
152 
153  TH1D* hSimIndConv = dynamic_cast<TH1D*>(fsim.Get("daq/ConvolutedInduction"));
154  hist_to_vector(hSimIndConv, fSimIndConv);
155  fSimIndConv.resize(fNTicks, 0.);
156  fSimIndConvF.resize(fNTicks/2+1);
157  fFFT->DoFFT(fSimIndConv, fSimIndConvF);
158 
159  // Get reco (deconvolution) response function.
160 
161  fhicl::ParameterSet calwire_pset = pset.get<fhicl::ParameterSet>("calwire");
162  cet::search_path sp("FW_SEARCH_PATH");
163  sp.find_file(calwire_pset.get<std::string>("ResponseFile"), fCalFile);
164  std::cout << "CalWire file = " << fCalFile << std::endl;
165 
166  TFile fcal(fCalFile.c_str());
167 
168  TH2D* respRe = dynamic_cast<TH2D*>(fcal.Get("sim/RespRe"));
169  TH2D* respIm = dynamic_cast<TH2D*>(fcal.Get("sim/RespIm"));
170  int nx = respRe->GetNbinsX();
171  int ny = respRe->GetNbinsY();
172  assert(nx == respIm->GetNbinsX());
173  assert(ny == respIm->GetNbinsY());
174  assert(nx == 2); // 1=induction, 2=collection.
175 
176  fColDeconvF.resize(ny);
177  fIndDeconvF.resize(ny);
178 
179  for(int i=0; i<ny; ++i) {
180  double ac = respRe->GetBinContent(2, i+1);
181  double bc = respIm->GetBinContent(2, i+1);
182  TComplex zc(ac, bc);
183  fColDeconvF[i] = zc;
184 
185  double ai = respRe->GetBinContent(1, i+1);
186  double bi = respIm->GetBinContent(1, i+1);
187  TComplex zi(ai, bi);
188  fIndDeconvF[i] = zi;
189  }
190 
191  // Calculate response of delta function to collection field + electronics.
192 
193  art::TFileDirectory dirc = tfs->mkdir("Collection", "Collection");
194  int nhist = std::min(200, fNTicks);
195 
196  // Input signal (delta function).
197 
198  std::vector<double> tinc(fNTicks, 0.);
199  fill_delta(tinc, nhist/2);
200  TH1D* hinc = dirc.make<TH1D>("input", "Collection Input", nhist+1, -0.5, nhist+0.5);
201  vector_to_hist(tinc, hinc);
202 
203  // Electronics response.
204 
205  std::vector<double> telectc(tinc);
206  fFFT->Convolute(telectc, fSimElectF);
207  TH1D* helectc = dirc.make<TH1D>("elect", "Collection Electronics", nhist+1, -0.5, nhist+0.5);
208  vector_to_hist(telectc, helectc);
209 
210  // Field response.
211 
212  std::vector<double> tfieldc(tinc);
213  fill_delta(tfieldc, nhist/2);
214  fFFT->Convolute(tfieldc, fSimColFieldF);
215  TH1D* hfieldc = dirc.make<TH1D>("field", "Collection Field", nhist+1, -0.5, nhist+0.5);
216  vector_to_hist(tfieldc, hfieldc);
217 
218  // Convolution of electronics and field response.
219 
220  std::vector<double> tbothc(tfieldc);
221  fFFT->Convolute(tbothc, fSimElectF);
222  TH1D* hbothc = dirc.make<TH1D>("both", "Collection Field+Electronics", nhist+1, -0.5, nhist+0.5);
223  vector_to_hist(tbothc, hbothc);
224 
225  // Shifted convolution of electronics and field response.
226 
227  double shift = fFFT->PeakCorrelation(tbothc, tinc);
228  std::cout << "Collection shift = " << shift << std::endl;
229  std::vector<double> tshiftc(tbothc);
230  fFFT->ShiftData(tshiftc, shift);
231  TH1D* hshiftc = dirc.make<TH1D>("shift", "Collection Field+Electronics+Shift", nhist+1, -0.5, nhist+0.5);
232  vector_to_hist(tshiftc, hshiftc);
233 
234  // Convolution response function read from file.
235 
236  std::vector<double> tconvc(tinc);
237  fFFT->Convolute(tconvc, fSimColConvF);
238  TH1D* hconvc = dirc.make<TH1D>("conv", "Collection Response", nhist+1, -0.5, nhist+0.5);
239  vector_to_hist(tconvc, hconvc);
240 
241  // Deconvolution.
242 
243  std::vector<double> tdeconvc(tconvc);
244  fFFT->Convolute(tdeconvc, fColDeconvF);
245  TH1D* hdeconvc = dirc.make<TH1D>("deconv", "Collection Deconvoluted", nhist+1, -0.5, nhist+0.5);
246  vector_to_hist(tdeconvc, hdeconvc);
247 
248  // Calculate response of delta function to induction field + electronics.
249 
250  art::TFileDirectory diri = tfs->mkdir("Induction", "Induction");
251 
252  // Input signal (delta function).
253 
254  std::vector<double> tini(fNTicks, 0.);
255  fill_delta(tini, nhist/2);
256  TH1D* hini = diri.make<TH1D>("input", "Induction Input", nhist+1, -0.5, nhist+0.5);
257  vector_to_hist(tini, hini);
258 
259  // Electronics response.
260 
261  std::vector<double> telecti(tini);
262  fFFT->Convolute(telecti, fSimElectF);
263  TH1D* helecti = diri.make<TH1D>("elect", "Induction Electronics", nhist+1, -0.5, nhist+0.5);
264  vector_to_hist(telecti, helecti);
265 
266  // Field response.
267 
268  std::vector<double> tfieldi(tini);
269  fFFT->Convolute(tfieldi, fSimIndFieldF);
270  TH1D* hfieldi = diri.make<TH1D>("field", "Induction Field", nhist+1, -0.5, nhist+0.5);
271  vector_to_hist(tfieldi, hfieldi);
272 
273  // Convolution of electronics and field response.
274 
275  std::vector<double> tbothi(tfieldi);
276  fFFT->Convolute(tbothi, fSimElectF);
277  TH1D* hbothi = diri.make<TH1D>("both", "Induction Field+Electronics", nhist+1, -0.5, nhist+0.5);
278  vector_to_hist(tbothi, hbothi);
279 
280  // Shifted convolution of electronics and field response.
281 
282  shift = fFFT->PeakCorrelation(tbothi, tini);
283  std::cout << "Induction shift = " << shift << std::endl;
284  std::vector<double> tshifti(tbothi);
285  fFFT->ShiftData(tshifti, shift);
286  TH1D* hshifti = diri.make<TH1D>("shift", "Induction Field+Electronics+Shift", nhist+1, -0.5, nhist+0.5);
287  vector_to_hist(tshifti, hshifti);
288 
289  // Convolution response function read from file.
290 
291  std::vector<double> tconvi(tini);
292  fFFT->Convolute(tconvi, fSimIndConvF);
293  TH1D* hconvi = diri.make<TH1D>("conv", "Induction Response", nhist+1, -0.5, nhist+0.5);
294  vector_to_hist(tconvi, hconvi);
295 
296  // Deconvolution.
297 
298  std::vector<double> tdeconvi(tconvi);
299  fFFT->Convolute(tdeconvi, fIndDeconvF);
300  TH1D* hdeconvi = diri.make<TH1D>("deconv", "Induction Deconvoluted", nhist+1, -0.5, nhist+0.5);
301  vector_to_hist(tdeconvi, hdeconvi);
302  }
303 
305  {}
306 
307  void FFTTest::analyze(const art::Event& /* evt */)
308  {}
309 }
std::vector< TComplex > fSimIndConvF
std::vector< TComplex > fSimElectF
std::string fCalFile
void analyze(const art::Event &evt)
std::vector< TComplex > fIndDeconvF
std::vector< double > fSimColField
shift
Definition: fcl_checks.sh:26
std::vector< TComplex > fColDeconvF
while getopts h
std::vector< double > fSimIndConv
FFTTest(fhicl::ParameterSet const &pset)
std::vector< double > fSimElect
std::vector< double > fSimIndField
std::vector< TComplex > fSimColFieldF
std::vector< double > fSimColConv
std::vector< TComplex > fSimColConvF
std::string fSimFile
std::vector< TComplex > fSimIndFieldF
art::ServiceHandle< art::TFileService > tfs
TCEvent evt
Definition: DataStructs.cxx:8
process_name can override from command line with o or output caldata
Definition: pid.fcl:40
BEGIN_PROLOG could also be cout