Polarimetry.cc
1 #include "Polarimetry.h"
2 #include "AnalysisWaveform.h"
3 
4 #include "TMultiGraph.h"
5 #include "TAxis.h"
6 #include "FFTtools.h"
7 
8 polarimetry::StokesAnalysis::StokesAnalysis(const StokesAnalysis & other)
9 {
10 
11  avgI = other.avgI;
12  avgQ = other.avgQ;
13  avgQ = other.avgQ;
14  avgV = other.avgV;
15 
16  dI = new TGraph(*other.dI);
17  dQ = new TGraph(*other.dQ);
18  dU = new TGraph(*other.dU);
19  dV = new TGraph(*other.dV);
20 
21  cI = new TGraph(*other.cI);
22  cQ = new TGraph(*other.cQ);
23  cU = new TGraph(*other.cU);
24  cV = new TGraph(*other.cV);
25 
26  instantaneous.Add(dI,"lp");
27  instantaneous.Add(dQ,"lp");
28  instantaneous.Add(dU,"lp");
29  instantaneous.Add(dV,"lp");
30  instantaneous.SetTitle("Instantaneous Stokes; Time (ns); Powerish");
31 
32  cumulative.Add(cI,"lp");
33  cumulative.Add(cQ,"lp");
34  cumulative.Add(cU,"lp");
35  cumulative.Add(cV,"lp");
36  cumulative.SetTitle("Cumulative Stokes; Time (ns);Powerish");
37 
38 }
39 
40 
41 polarimetry::StokesAnalysis::StokesAnalysis(const AnalysisWaveform * H, const AnalysisWaveform *V, double xcorr)
42 {
43  //figure out if we need to resample both to the same time base
44 
45  AnalysisWaveform *Hre = 0;
46  AnalysisWaveform *Vre = 0;
47 
48 
49  bool need_to_resample =V->deltaT() != H->deltaT() || H->even()->GetX()[0] != V->even()->GetX()[0] ;
50 
51  //we need to resample both onto the same base
52  if ( need_to_resample || xcorr)
53  {
54  if (need_to_resample)
55  {
56  double dt = TMath::Min(H->deltaT(), V->deltaT());
57  double t0 = TMath::Max(H->even()->GetX()[0], V->even()->GetX()[0]);
58  double t1 = TMath::Min(H->even()->GetX()[H->Neven()-1], V->even()->GetX()[V->Neven()-1]);
59 
60  int N = (t1-t0)/dt;
61 
62  Hre = new AnalysisWaveform(N, t0, dt);
63  Vre = new AnalysisWaveform(N, t0, dt);
64 
65  TGraphAligned * gHre = Hre->updateEven();
66  TGraphAligned * gVre = Vre->updateEven();
67 
68  H->evalEven(N, gHre->GetX(), gHre->GetY());
69  V->evalEven(N, gVre->GetX(), gVre->GetY());
70  }
71 
72  if (xcorr)
73  {
74 
75  if (H->Neven()!= V->Neven())
76  {
77  if (!Hre) Hre = new AnalysisWaveform(*H);
78  if (!Vre) Vre = new AnalysisWaveform(*V);
79  Vre->forceEvenSize(Hre->Neven());
80  }
81 
82  if (!H->checkIfPaddedInTime() || !V->checkIfPaddedInTime())
83  {
84  if (!Hre) Hre = new AnalysisWaveform(*H);
85  if (!Vre) Vre = new AnalysisWaveform(*V);
86  Hre->padEven(1);
87  Vre->padEven(1);
88  }
89 
90 
92  double dt = xc->deltaT();
93  int loc = 0;
94  int half = xc->Neven()/2;
95  int min = TMath::Max(0, int(half-ceil(xcorr/dt)));
96  int max = TMath::Min(int(half+ceil(xcorr/dt)), xc->Neven()-1);
97 
98 
99  xc->even()->peakVal(&loc,min,max,true);
100  Vre->updateEven()->shift(half-loc,true);
101  delete xc;
102  }
103 
104  H = Hre;
105  V = Vre;
106  }
107 
108  int N = TMath::Min(H->Neven(), V->Neven());
109 
110 
111  dI = new TGraph(N, H->even()->GetX(), H->even()->GetY());
112  dI->SetTitle("Instantaneous I");
113  dQ = new TGraph(N, H->even()->GetX(), H->even()->GetY());
114  dQ->SetTitle("Instantaneous Q");
115  dU = new TGraph(N, H->even()->GetX(), H->even()->GetY());
116  dU->SetTitle("Instantaneous U");
117  dV = new TGraph(N, H->even()->GetX(), H->even()->GetY());
118  dV->SetTitle("Instantaneous V");
119 
120 
121  FFTtools::stokesParameters(N, H->even()->GetY(), H->hilbertTransform()->even()->GetY(),
122  V->even()->GetY(), V->hilbertTransform()->even()->GetY(),
123  &avgI,&avgQ,&avgU,&avgV,
124  dI->GetY(), dQ->GetY(), dU->GetY(), dV->GetY(),
125  false);
126 
127  cI = new TGraph(dI->GetN(), dI->GetX(), dI->GetY());
128  cI->SetTitle("Cumulative I");
129  cQ = new TGraph(dQ->GetN(), dQ->GetX(), dQ->GetY());
130  cQ->SetTitle("Cumulative Q");
131  cU = new TGraph(dU->GetN(), dU->GetX(), dU->GetY());
132  cU->SetTitle("Cumulative U");
133  cV = new TGraph(dV->GetN(), dV->GetX(), dV->GetY());
134  cV->SetTitle("Cumulative V");
135 
136 
137  for (int i = 1; i < N; i++)
138  {
139  cI->GetY()[i] += cI->GetY()[i-1];
140  cQ->GetY()[i] += cQ->GetY()[i-1];
141  cU->GetY()[i] += cU->GetY()[i-1];
142  cV->GetY()[i] += cV->GetY()[i-1];
143  }
144 
145 
146  instantaneous.Add(dI,"lp");
147  instantaneous.Add(dQ,"lp");
148  instantaneous.Add(dU,"lp");
149  instantaneous.Add(dV,"lp");
150  instantaneous.SetTitle("Instantaneous Stokes; Time (ns); Powerish");
151 
152  cumulative.Add(cI,"lp");
153  cumulative.Add(cQ,"lp");
154  cumulative.Add(cU,"lp");
155  cumulative.Add(cV,"lp");
156  cumulative.SetTitle("Cumulative Stokes; Time (ns);Powerish");
157 
158  if (Hre) delete Hre;
159  if (Vre) delete Vre;
160 
161 }
162 
163 
164 int polarimetry::StokesAnalysis::computeWindowedAverage(double Ifrac, double *I, double *Q, double *U, double *V, double *PoPerr) const
165 {
166  int Imax = TMath::LocMax(dI->GetN(), dI->GetY());
167  double I0 = dI->GetY()[Imax];
168 
169  double thresh = dI->GetY()[Imax] * Ifrac;
170 
171  double Isum = 0;
172  double Qsum = 0;
173  double Usum = 0;
174  double Vsum = 0;
175 
176  double I2sum = 0;
177  double Q2sum = 0;
178  double U2sum = 0;
179  double V2sum = 0;
180 
181  int n = 0;
182  int Iend = 0;
183  for (int i = Imax; i < dI->GetN(); i++)
184  {
185  Iend = i;
186  if (dI->GetY()[i] < thresh) break;
187  Isum += dI->GetY()[i];
188  Qsum += dQ->GetY()[i];
189  Usum += dU->GetY()[i];
190  Vsum += dV->GetY()[i];
191  n++;
192  }
193 
194  for (int i = Imax-1; i >= 0; i--)
195  {
196  if (dI->GetY()[i] < thresh) break;
197  Isum += dI->GetY()[i];
198  Qsum += dQ->GetY()[i];
199  Usum += dU->GetY()[i];
200  Vsum += dV->GetY()[i];
201  n++;
202  }
203  Isum = Isum/n;
204  Qsum = Qsum/n;
205  Usum = Usum/n;
206  Vsum = Vsum/n;
207 
208 
209  double ret_err = 0;
210  if(PoPerr)
211  {
212  for (int i = Imax; i < dI->GetN(); i++)
213  {
214  if (dI->GetY()[i] < thresh) break;
215  I2sum += (dI->GetY()[i]/I0 - Isum/I0)*(dI->GetY()[i]/I0 - Isum/I0);
216  Q2sum += (dQ->GetY()[i]/I0 - Qsum/I0)*(dQ->GetY()[i]/I0 - Qsum/I0);
217  U2sum += (dU->GetY()[i]/I0 - Usum/I0)*(dU->GetY()[i]/I0 - Usum/I0);
218  V2sum += (dV->GetY()[i]/I0 - Vsum/I0)*(dV->GetY()[i]/I0 - Vsum/I0);
219  }
220 
221  for (int i = Imax-1; i >= 0; i--)
222  {
223  if (dI->GetY()[i] < thresh) break;
224  I2sum += (dI->GetY()[i]/I0 - Isum/I0)*(dI->GetY()[i]/I0 - Isum/I0);
225  Q2sum += (dQ->GetY()[i]/I0 - Qsum/I0)*(dQ->GetY()[i]/I0 - Qsum/I0);
226  U2sum += (dU->GetY()[i]/I0 - Usum/I0)*(dU->GetY()[i]/I0 - Usum/I0);
227  V2sum += (dV->GetY()[i]/I0 - Vsum/I0)*(dV->GetY()[i]/I0 - Vsum/I0);
228  }
229 
230  I2sum = I2sum/n;
231  Q2sum = Q2sum/n;
232  U2sum = U2sum/n;
233  V2sum = V2sum/n;
234 
235  //printf("max ind = %d\n", Imax);
236  double Qc = TMath::Abs(cQ->GetY()[Iend])/cI->GetY()[Iend];
237  double Uc = TMath::Abs(cU->GetY()[Iend])/cI->GetY()[Iend];
238 
239  ret_err = U2sum * pow(.5 * Qc/((Qc * Qc) + (Uc * Uc)), 2) + Q2sum * pow(.5 * Uc/((Qc * Qc) + (Uc * Uc)), 2);
240  //printf("errc = %g\n", sqrt(ret_err) * 180./TMath::Pi());
241  }
242 
243  if (I) *I = Isum;
244  if (Q) *Q = Qsum;
245  if (U) *U = Usum;
246  if (V) *V = Vsum;
247 
248  if (PoPerr) *PoPerr = sqrt(ret_err) * 180./TMath::Pi();
249 
250  return n;
251 }
252 
double evalEven(double t, EvenEvaluationType=EVAL_LINEAR) const
const AnalysisWaveform * hilbertTransform() const
void forceEvenSize(int size)
bool checkIfPaddedInTime() const
int computeWindowedAverage(double minIfrac, double *I=0, double *Q=0, double *U=0, double *V=0, double *PoPerr=0) const
Definition: Polarimetry.cc:164
TGraphAligned * updateEven()
void padEven(int factor, int where=1)
double deltaT() const
static AnalysisWaveform * correlation(const AnalysisWaveform *A, const AnalysisWaveform *B, int npadfreq=0, double scale=1, int window_normalize=0)
const TGraphAligned * even() const
This class is intended to be the main storage vessel for ANITA waveforms. It is similar in principle ...