SystemResponse.h
1 #ifndef _UCORRELATOR_SYSTEM_RESPONSE_H
2 #define _UCORRELATOR_SYSTEM_RESPONSE_H
3 
4  /* oh boy, down the OO rabbit hole we go!
5  *
6  * this file defines methods for deconvolution and system responses
7  *
8  **/
9 
10 #include <vector>
11 #include <complex>
12 #include "TH2.h"
13 #include "TMutex.h"
14 #include "FFTWComplex.h"
15 #include <map>
16 #include "AnalysisWaveform.h"
17 
18 class TGraph;
19 class TF1;
20 
21 namespace AnitaResponse{
22 
23 
25  {
26 
27  public:
28  virtual void deconvolve(AnalysisWaveform *wf, const AnalysisWaveform * response) const = 0;
29 
30  //compatibility interface
31  __attribute__((deprecated))
32  virtual void deconvolve(int Nf, double df, FFTWComplex *Y, const FFTWComplex * response) const;
33 
34  virtual ~DeconvolutionMethod() { ; }
35  };
36 
37 
39  {
40 
41  public:
42 
43  virtual void deconvolve(AnalysisWaveform *wf, const AnalysisWaveform *rwf) const ;
44 
45  virtual ~NaiveDeconvolution() { ; }
46 
47  };
48 
49 
50 
55  {
56 
57  public:
58  // restoring function accepts a delta_t as parameter. Will be scaled by restoring component
59  CLEANDeconvolution(const TF1 * restoring_beam, double gain = 0.05, double threshold = 0.01, double noiselevel = 10, bool convolve_residuals = true, int maxiter = 5000)
60  : r(restoring_beam), gain(gain), threshold(threshold), noiselevel(noiselevel), convolve_residuals(convolve_residuals), max_iter(maxiter), debug(false), cached_restoring(0) {; }
61  void setThreshold(double t) { threshold = t; }
62 
63 
64  virtual void deconvolve(AnalysisWaveform *wf, const AnalysisWaveform *rwf) const;
65 
66 
67  void enableSaveIntermediate(bool enable = true) { debug = enable; }
68  std::vector<AnalysisWaveform*> * getIntermediateXcorrs() const { return debug ? &save_xcorr : 0;}
69  std::vector<AnalysisWaveform*> * getIntermediateYs() const { return debug ? &save_ys : 0;}
70  std::vector<AnalysisWaveform*> * getIntermediateSubs() const { return debug ? &save_subtracted : 0;}
71  AnalysisWaveform * getComponents() const { return &cmp; }
72 
73 
74 
75 
76  virtual ~CLEANDeconvolution() { clearIntermediate(); if (cached_restoring) delete cached_restoring; }
77 
78  private:
79  const TF1 * r;
80  double gain;
81  double threshold;
82  double noiselevel;
83  bool convolve_residuals;
84  int max_iter;
85  bool debug;
86  mutable std::vector<AnalysisWaveform*> save_xcorr;
87  mutable std::vector<AnalysisWaveform*> save_ys;
88  mutable std::vector<AnalysisWaveform*> save_subtracted;
89  mutable AnalysisWaveform cmp;
90  mutable AnalysisWaveform * cached_restoring;
91  void clearIntermediate() const;
92 
93  };
94 
95  /*
96  class RichardsonLucyDeconvolution : public DeconvolutionMethod
97  {
98  public:
99  RichardsonLucyDeconvolution(int maxiter = 100, double thresh = 0.01)
100  : maxiter(maxiter), thresh(thresh) {; }
101  virtual void deconvolve(size_t N, double df, FFTWComplex * Y,
102  const FFTWComplex * response) const ;
103 
104  private:
105  int maxiter;
106  double thresh;
107 
108  };
109  */
110 
112  {
113  public:
114  virtual void deconvolve(AnalysisWaveform *wf, const AnalysisWaveform *rwf) const ;
115  virtual ~MinimumPhaseDeconvolution() { ; }
116 
117 
118  };
119 
125  {
126 
127  public:
133  WienerDeconvolution (const TGraph * g_snr, const double * scale = 0);
134 
136  WienerDeconvolution(double noise_level = 1);
137 
139  WienerDeconvolution (const TF1 * f);
140 
141 
142  virtual void deconvolve(AnalysisWaveform *wf, const AnalysisWaveform *rwf) const ;
143 
144  protected:
145  virtual double snr(double f, double R2, int N) const;
146 
147  private:
148  const TGraph * snr_graph;
149  const double * scale;
150  const TF1 * snr_function;
151  double min,max;
152  double noise_level;
153  };
154 
156  {
157  public:
158 
159  BandLimitedDeconvolution(double minfreq, double maxfreq, int edgeorder = 0)
160  : min_freq(minfreq),max_freq(maxfreq), edge_order(edgeorder)
161  {
162  }
163 
164  virtual void deconvolve(AnalysisWaveform *wf, const AnalysisWaveform *rwf) const ;
165 
166  virtual ~BandLimitedDeconvolution() { ; }
167 
168 
169  private:
170  double min_freq, max_freq;
171  int edge_order;
172  };
173 
174 
176  {
177  public:
178  AllPassDeconvolution() { ; }
179  virtual void deconvolve(AnalysisWaveform *wf, const AnalysisWaveform *rwf) const ;
180 
181  virtual ~AllPassDeconvolution() { ; }
182 
183  };
184 
186  {
187 
188  public:
189  ImpulseResponseXCorr() { ; }
190  virtual void deconvolve(AnalysisWaveform *wf, const AnalysisWaveform *rwf) const ;
191  virtual ~ImpulseResponseXCorr() { ; }
192 
193  };
194 
196  class CLEAN : public DeconvolutionMethod
197  {
198 
199  public:
200  CLEAN(int max_loops = 1000, double loop_gain = 0.02, double thresh_factor = 1., TString restoring_beam = "(1./10) * pow(x,2) * exp(-x/1.43)", bool add_residuals = 1, bool only_return_residuals = 0);
201  virtual void deconvolve(AnalysisWaveform *wf, const AnalysisWaveform *rwf) const ;
202  virtual ~CLEAN() { ; }
203  private:
204  int fMaxLoops;
205  double fLoopGain;
206  double fThreshFactor;
207  TString fRestoringBeam;
208  bool fAddResiduals;
209  bool fOnlyReturnResiduals;
210 
211  };
212 
213  extern DeconvolutionMethod & kDefaultDeconvolution;
214 
216  {
217 
218  public:
219  virtual FFTWComplex getResponse(double f, double angle = 0) const = 0;
220  virtual FFTWComplex * getResponseArray(int N, const double * f, double angle = 0, FFTWComplex * answer = 0) const;
221  virtual FFTWComplex * getResponseArray(int N, double df, double angle = 0, FFTWComplex * answer = 0) const ;
222  virtual double getMagnitude(double f, double angle= 0) const;
223  virtual double getPhase(double f, double angle = 0) const;
224 
225  virtual AnalysisWaveform * impulseResponse(double dt = 1./2.6, int N = 256) const;
226  virtual AnalysisWaveform * convolve(const AnalysisWaveform * wf, double angle = 0) const;
227  virtual AnalysisWaveform * deconvolve(const AnalysisWaveform * wf, const DeconvolutionMethod * method = &kDefaultDeconvolution, double angle = 0) const;
228  virtual void convolveInPlace(AnalysisWaveform * wf, double angle = 0) const;
229  virtual void deconvolveInPlace(AnalysisWaveform * wf, const DeconvolutionMethod * method = &kDefaultDeconvolution, double angle = 0) const;
230 
231  virtual ~AbstractResponse() { ; }
232 
233  };
234 
237  class Response : public AbstractResponse
238  {
239  public:
240  Response(int NFreq, double df);
241  Response(const TGraph * time_domain, int npad);
242  Response(int Nfreq, double df, int nangles, const double * angles, const FFTWComplex ** responses);
243  Response(int Nfreq, double df, const FFTWComplex * response);
244 
245  void addResponseAtAngle(double angle, const FFTWComplex * response);
246 
247  virtual FFTWComplex getResponse(double f, double angle = 0) const;
248 
249 
250  const TH2 * getReal() const { return &real; }
251  const TH2 * getImag() const { return &imag; }
252 
253  virtual ~Response() { ; }
254 
255  protected:
256  mutable TMutex lock;
257  int Nfreq;
258  double df;
259  int nangles;
260  std::map<double, FFTWComplex *> responses;
261  mutable TH2D real;
262  mutable TH2D imag;
263  mutable bool dirty;
264  void recompute() const;
265  };
266 
267 
269  {
270  public:
271  void addResponse(const AbstractResponse * response) { responses.push_back(response); }
272  virtual FFTWComplex getResponse(double f, double angle = 0) const;
273  virtual ~CompositeResponse() { ; }
274 
275  private:
276  std::vector<const AbstractResponse * > responses;
277  };
278 
279 
280 }
281 
282 
283 
284 #endif
285 
WienerDeconvolution(const TGraph *g_snr, const double *scale=0)
This is a wrapper class for a complex number.
Definition: FFTWComplex.h:12
Inelasticity distributions: stores parametrizations and picks inelasticities.
Definition: Primaries.h:38
This class is intended to be the main storage vessel for ANITA waveforms. It is similar in principle ...