Logo coherent WaveBurst  
Library Reference Guide
Logo
DrawCCutxPE.C
Go to the documentation of this file.
1 /*
2 # Copyright (C) 2019 Gabriele Vedovato
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17 
18 // PURPOSE
19 // This is a macro used to visualize the effect of the "ccut" time-frequency cut implemented in the macro cwb_pereport.C
20 // The "ccut" time-frequency cut is used for inspiral higher modes investigations
21 // NOTE: most of the functions are extracted from the macro cwb_pereport.C
22 
23 #define PE_MAX_EVENTS 100
24 #define N_IFO 3
25 
26 std::vector<wavearray<double> > wREC[PE_MAX_EVENTS]; // reconstructed signal in the trials
27 std::vector<wavearray<double> > wINJ[PE_MAX_EVENTS]; // iwhitened injected posteriors in the trials
28 
29 double wTCOA[PE_MAX_EVENTS]; // tcoa injected posteriors in the trials
30 float wTHETA[PE_MAX_EVENTS]; // theta injected posteriors in the trials
31 float wPHI[PE_MAX_EVENTS]; // phi injected posteriors in the trials
32 float wM1[PE_MAX_EVENTS]; // m1 injected posteriors in the trials
33 float wM2[PE_MAX_EVENTS]; // m1 injected posteriors in the trials
34 float wS1[PE_MAX_EVENTS]; // spin1 OffSource injected posteriors
35 float wS2[PE_MAX_EVENTS]; // spin2 OffSource injected posteriors
36 float wRHO[PE_MAX_EVENTS]; // rho injected posteriors in the trials
37 
38 int gEVENTS; // number of read events
39 static TString gIFO[3] = {"L1","H1","V1"}; // network ifos. WARNING: this setup is hard coded !!!
40 
41 double GetInjTcoa(double geocentric_tcoa, network* NET, TString ifo, double theta, double phi);
42 
44 
45 wavearray<double> GetCCut(wavearray<double>* ts, double tcoa, double m1, double m2, double s1z, double s2z);
47 void DrawCCut(wavearray<double>* ts, double tcoa, double m1, double m2, double s1z, double s2z);
48 void DrawCCut(WSeries<double> W, double tcoa, double m1, double m2, double s1z, double s2z);
49 
50 struct uoptions {
51 
52  TString ccut; // Is used to select TF area using chirp TF cut. If="" then it is not applied.
53  // The selected TF region is defined by the parameters declared in the ccut string.
54  // format: wdm_fres:mc_lower_factor:mc_upper_factor:left_time:right_time
55  // default: 8:1.25:1.75:0.5:0.0
56 
57  // the following parameters are setup parsing the user ccut parameter. Are initialized with the default values
58  int ccut_wdm_fres;
59  double ccut_bchirp;
60  double ccut_uchirp;
61  double ccut_ltime;
62  double ccut_rtime;
63 };
64 
65 uoptions gOPT; // global User Options
66 WDM<double>* gWDM; // wdm used for chirp TF cut
67 
68 
69 // chirp tf cut default parameters
70 
71 #define CCUT_WDM_FRES 16 // the WDM freq resolution used to decompose the signal in TF domain
72 #define CCUT_BCHIRP 1.40 // mchirp factor used to select the upper region boundary Mc=Mc.ccut_bchirp
73 #define CCUT_UCHIRP 1.60 // mchirp factor used to select the upper region boundary Mc=Mc.ccut_uchirp
74 #define CCUT_LTIME 0.5 // left time from tcoa (sec) used to select the the time region: [tcoa-left_time:tcoa-right_time]
75 #define CCUT_RTIME 0.0 // right time from tcoa (sec) used to select the the time region: [tcoa-left_time:tcoa-right_time]
76 
77 
79 TLine* ftcoa; // tcoa time function
80 TLine* flchirp; // left chirp cut function
81 TLine* frchirp; // right chirp cut function
82 TF1* fbchirp; // bottom chirp cut function
83 TF1* fuchirp; // upper chirp cut function
84 
85 // options
86 
87 //#define SHOW_FFT
88 //#define SHOW_TIME
89 //#define SHOW_ENVELOPE
90 
91 #define APPLY_CCUT
92 //#define APPLY_BANDPASS
93 //#define APPLY_SYNC
94 
95 //#define SHOW_WDM_INJ
96 //#define SHOW_WDM_REC
97 #define SHOW_WDM_DIF
98 
99 #define DEBUGGING
100 
101 void DrawCCutxPE(TString ifname, int wf_id=0, int ifo_id=0, TString options="16:1.40:1.60:0.5:0.0") {
102 
103  gOPT.ccut=options;
104 
105  GetCCutParms(gOPT.ccut);
106 
107  // read waveform from output root file
108  TFile* froot = new TFile(ifname,"READ");
109  if(froot==NULL) {
110  cout << "Error : Failed to open file : " << ifname << endl;
111  gSystem->Exit(1);
112  }
113  TTree* itree = (TTree*)froot->Get("waveburst");
114  if(itree==NULL) {
115  cout << "Error : Failed to open tree waveburst from file : " << ifname << endl;
116  //continue;
117  gSystem->Exit(1);
118  }
119 
120  gnetwork* NET = new gnetwork(N_IFO,gIFO);
121 
122  wavearray<double>* sample_wREC[N_IFO];
123  for(int i=0;i<N_IFO;i++) sample_wREC[i] = new wavearray<double>;
124 
125  wavearray<double>* sample_wINJ[N_IFO];
126  for(int i=0;i<N_IFO;i++) sample_wINJ[i] = new wavearray<double>;
127 
128  double* time = new double[2*N_IFO];
129  float likelihood;
130  double tcoa=-1; // geocentric tcoa
131  float rho[2];
132  float theta[4];
133  float phi[4];
134  float ifar=0;
135  string* log = new string; // injection log
136 
137  cout.precision(14);
138  for(int k=0;k<itree->GetEntries();k++) {
139 
140  for(int i=0;i<N_IFO;i++) itree->SetBranchAddress(TString::Format("wREC_%d",i).Data(),&sample_wREC[i]);
141  for(int i=0;i<N_IFO;i++) itree->SetBranchAddress(TString::Format("wINJ_%d",i).Data(),&sample_wINJ[i]);
142  itree->SetBranchAddress("time",time);
143  itree->SetBranchAddress("theta",theta);
144  itree->SetBranchAddress("phi",phi);
145  itree->SetBranchAddress("rho",rho);
146  itree->SetBranchAddress("likelihood",&likelihood);
147  itree->SetBranchAddress("wf_tcoa",&tcoa);
148  itree->SetBranchAddress("log",&log);
149 
150  itree->GetEntry(k); // read wREC,skyprob objects
151 
152  for(int i=0;i<N_IFO;i++) {
153  wREC[gEVENTS].push_back(*sample_wREC[i]); // store reconstructed posterior sample waveform
154  wINJ[gEVENTS].push_back(*sample_wINJ[i]); // store whitened posterior sample waveform
155  }
156  wTCOA[gEVENTS]=tcoa; // store injected geocentric tcoa
157  wTHETA[gEVENTS]=theta[1]; // store OnSource sample theta
158  wPHI[gEVENTS]=phi[1]; // store OnSource sample phi
159  wRHO[gEVENTS]=rho[1]; // store OnSource sample rho
160 
161  ifar/=(24.*3600.*365.); // sec -> year
162  //cout << log->c_str() << endl;
163  TString m1 = GetParameterFromInjLog(log->c_str(), "mass1");
164  TString m2 = GetParameterFromInjLog(log->c_str(), "mass2");
165  wM1[gEVENTS]=m1.Atof(); // store injected m1
166  wM2[gEVENTS]=m2.Atof(); // store injected m2
167  TString s1 = GetParameterFromInjLog(log->c_str(), "spin1");
168  TString s2 = GetParameterFromInjLog(log->c_str(), "spin2");
169  wS1[gEVENTS]=s1.Atof(); // store injected s1
170  wS2[gEVENTS]=s2.Atof(); // store injected s2
171 
172  double mc = pow(m1.Atof()*m2.Atof(),3./5.)/pow(m1.Atof()+m2.Atof(),1./5.); // chirp mass
173  cout << gEVENTS << " m1 " << m1 << " m2 " << m2 << " mc " << mc << " ifar " << ifar << " (years) " << endl;
174 
175  gEVENTS++;
176  }
177  froot->Close();
178 
179  if(wf_id>=gEVENTS) {
180  cout << "Error : max wf_id = " << gEVENTS-1 << endl;
181  gSystem->Exit(1);
182  }
183 
184  cout << endl << "RHO " << wRHO[wf_id] << endl << endl;
185 
186  // from wdm_fres and input data rate we compute the WDM levels and init WDM used for TF transform
187  int ccut_wdm_levels = int(wREC[wf_id][ifo_id].rate()/gOPT.ccut_wdm_fres/2);
188  cout << endl << "RATE " << wREC[wf_id][ifo_id].rate() << " WDM levels " << ccut_wdm_levels << endl << endl;
189  gWDM = new WDM<double>(ccut_wdm_levels, ccut_wdm_levels, 6, 10); // init a WDM transform
190 
191  vector<double> vtcoa(N_IFO);
192  for(int n=0;n<N_IFO;n++) {
193  vtcoa[n] = GetInjTcoa(wTCOA[wf_id], NET, gIFO[n], wTHETA[wf_id], wPHI[wf_id]);
194  cout << n << "\t" << int(wINJ[wf_id][n].start()) << "\t" << vtcoa[n]-wINJ[wf_id][n].start() << endl;
195  }
196 
197  MDC = new CWB::mdc(N_IFO,gIFO);
198 
199 #ifdef APPLY_SYNC
200  double sync_phase=0, sync_time=0, sync_xcor=0;
201  //sync_xcor = CWB::mdc::TimeSync(wREC[wf_id][ifo_id], wINJ[wf_id][ifo_id], sync_time);
202  sync_xcor = CWB::mdc::TimePhaseSync(wREC[wf_id][ifo_id], wINJ[wf_id][ifo_id], sync_time, sync_phase);
203  cout << "sync_time " << sync_time << " sync_phase " << sync_phase << " sync_xcor " << sync_xcor << endl;
204 #endif
205 
206 /*
207  wINJ[wf_id][ifo_id].start(0);
208  wREC[wf_id][ifo_id].start(0);
209  MDC->DrawTime(wINJ[wf_id][ifo_id],"ALP ZOOM");
210  MDC->DrawTime(wREC[wf_id][ifo_id],"SAME",kRed);
211  return;
212 */
213 // CWB::mdc::Align(wREC[wf_id][ifo_id], wINJ[wf_id][ifo_id]);
214  wavearray<double> wDIF = CWB::mdc::GetDiff(&wREC[wf_id][ifo_id], &wINJ[wf_id][ifo_id]);
215 /*
216  MDC->DrawFFT(wINJ[wf_id][ifo_id],"ALP ZOOM");
217  MDC->DrawFFT(wREC[wf_id][ifo_id],"SAME",kRed);
218  MDC->DrawFFT(wDIF,"SAME",kGreen+2);return;
219 */
220 
221 // MDC->DrawTF(wREC[wf_id][ifo_id]); return;
222 
223  std::vector<wavearray<double> > vREC(N_IFO);
224  std::vector<wavearray<double> > vINJ(N_IFO);
225  for(int n=0;n<N_IFO;n++) {
226  vINJ[n] = wINJ[wf_id][ifo_id];
227  vREC[n] = wREC[wf_id][ifo_id];
228  }
229  vector<double> tstart,tstop;
230  tstart=vtcoa;
231  tstop=vtcoa;
232  for(int n=0;n<N_IFO;n++) tstart[n]-=0.25;
233  double FF = CWB::mdc::GetMatchFactor("ff",vREC,vINJ,tstart,tstop);
234  cout << "FF -> " << FF << endl;
235  double RE = CWB::mdc::GetMatchFactor("re",vREC,vINJ,tstart,tstop);
236  cout << "RE -> " << RE << endl;
237 
238 #ifdef APPLY_BANDPASS
239  vINJ[ifo_id] = CWB::mdc::GetBandpass(vINJ[ifo_id],80,400);
240  vREC[ifo_id] = CWB::mdc::GetBandpass(vREC[ifo_id],80,400);
241 #endif
242 
243 #ifdef APPLY_CCUT
244 
245 #ifdef SHOW_WDM_INJ
246  cout << endl;
247  wINJ[wf_id][ifo_id] = GetCCut(&wINJ[wf_id][ifo_id], vtcoa[ifo_id]-wINJ[wf_id][ifo_id].start(), wM1[wf_id], wM2[wf_id], wS1[wf_id], wS2[wf_id]);
248  cout << "-------> APPLY_CCUT wINJ Energy (time domain phase 00) -------> " << pow(wINJ[wf_id][ifo_id].rms(),2)*wINJ[wf_id][ifo_id].size() << endl;
249  cout << endl;
250 #endif
251 
252 #ifdef SHOW_WDM_REC
253  wREC[wf_id][ifo_id] = GetCCut(&wREC[wf_id][ifo_id], vtcoa[ifo_id]-wREC[wf_id][ifo_id].start(), wM1[wf_id], wM2[wf_id], wS1[wf_id], wS2[wf_id]);
254  cout << "-------> APPLY_CCUT wREC Energy (time domain phase 00) -------> " << pow(wREC[wf_id][ifo_id].rms(),2)*wREC[wf_id][ifo_id].size() << endl;
255  cout << endl;
256 #endif
257 
258 #ifdef SHOW_WDM_DIF
259  wDIF = GetCCut(&wDIF, vtcoa[ifo_id]-wREC[wf_id][ifo_id].start(), wM1[wf_id], wM2[wf_id], wS1[wf_id], wS2[wf_id]);
260  cout << "-------> APPLY_CCUT wDIF Energy (time domain phase 00) -------> " << pow(wDIF.rms(),2)*wDIF.size() << endl;
261  cout << endl;
262 #endif
263 
264 #ifdef DEBUGGING
265  cout << "END " << endl;
266  return;
267 #endif
268 
269 #endif
270 
271 #ifdef SHOW_FFT
272  MDC->DrawFFT(wINJ[wf_id][ifo_id],"ALP ZOOM");
273  MDC->DrawFFT(wREC[wf_id][ifo_id],"SAME",kRed);
274 #endif
275 
276 #ifdef SHOW_TIME
277  wINJ[wf_id][ifo_id].start(0);
278  wREC[wf_id][ifo_id].start(0);
279  MDC->DrawTime(wINJ[wf_id][ifo_id],"ALP ZOOM");
280 return;
281  MDC->DrawTime(wREC[wf_id][ifo_id],"SAME",kRed);
282 #endif
283 
284 #ifdef SHOW_ENVELOPE
285  for(int n=0;n<N_IFO;n++) {
286  vINJ[n] = CWB::mdc::GetEnvelope(&(wINJ[wf_id][ifo_id]));
287  vREC[n] = CWB::mdc::GetEnvelope(&(wREC[wf_id][ifo_id]));
288  }
289  vINJ[ifo_id].start(0);
290  vREC[ifo_id].start(0);
291 
292  MDC->DrawTime(vINJ[ifo_id],"ALP ZOOM");
293  MDC->DrawTime(vREC[ifo_id],"SAME",kRed);
294 #endif
295 
296 #ifdef SHOW_WDM_INJ
297  DrawCCut(&wINJ[wf_id][ifo_id], vtcoa[ifo_id]-wINJ[wf_id][ifo_id].start(), wM1[wf_id], wM2[wf_id], wS1[wf_id], wS2[wf_id]);
298 #endif
299 #ifdef SHOW_WDM_REC
300  DrawCCut(&wREC[wf_id][ifo_id], vtcoa[ifo_id]-wINJ[wf_id][ifo_id].start(), wM1[wf_id], wM2[wf_id], wS1[wf_id], wS2[wf_id]);
301 #endif
302 #ifdef SHOW_WDM_DIF
303  DrawCCut(&wDIF, vtcoa[ifo_id]-wINJ[wf_id][ifo_id].start(), wM1[wf_id], wM2[wf_id], wS1[wf_id], wS2[wf_id]);
304 #endif
305 
306 }
307 
308 double
309 GetInjTcoa(double geocentric_tcoa, network* NET, TString ifo, double theta, double phi) {
310 // compute coalescence time
311 
312  // Add Time Delay respect to geocenter
313  CWB::mdc MDC(NET);
314  double tdelay = MDC.GetDelay(ifo,"",phi,theta);
315  double ifo_tcoa = geocentric_tcoa+tdelay;
316 
317  return ifo_tcoa;
318 }
319 
321 // get params from log string
322 
323  TObjArray* token = log.Tokenize(TString(" "));
324  for(int i=0;i<token->GetEntries();i++) {
325  TObjString* otoken = (TObjString*)token->At(i);
326  TString stoken = otoken->GetString();
327  // exctract value
328  if(stoken==param) {
329  if(i<token->GetEntries()-1) {
330  if(stoken=="spin1" || stoken=="spin2") {
331  otoken = (TObjString*)token->At(i+3); // get spinz
332  return otoken->GetString();
333  } else {
334  otoken = (TObjString*)token->At(i+1);
335  return otoken->GetString();
336  }
337  }
338  }
339  }
340  if(token) delete token;
341 
342  return "";
343 }
344 
345 void DrawCCut(wavearray<double>* ts, double tcoa, double m1, double m2, double s1, double s2) { // apply transformation on white noise and plot it
346 
347  // produce the TF map:
348  WSeries<double> W; // TF map container
349  W.Forward(*ts, *gWDM); // apply the WDM to the time series
350 
351  DrawCCut(W, tcoa, m1, m2, s1, s2);
352 }
353 
355 
356  // initialize with the default values
357  gOPT.ccut_wdm_fres = CCUT_WDM_FRES;
358  gOPT.ccut_bchirp = CCUT_BCHIRP;
359  gOPT.ccut_uchirp = CCUT_UCHIRP;
360  gOPT.ccut_ltime = CCUT_LTIME;
361  gOPT.ccut_rtime = CCUT_RTIME;
362 
363  // read the user parameter ccut
364  TObjArray* token = TString(options).Tokenize(TString(':'));
365  if(token->GetEntries()!=5) {
366  cout << endl;
367  cout << "cwb_pereport - Error : ccut format - must be: wdm_fres:bchirp:uchirp:ltime:rtime" << endl;
368  cout << " Default setup is: 16:1.35:1.65:0.5:0.0" << endl;
369  cout << " To setup a default value use *" << endl;
370  cout << " Example: *:1.25:1.75:*:*" << endl;
371  cout << endl;
372  exit(1);
373  }
374  for(int j=0;j<token->GetEntries();j++) {
375  TObjString* tok = (TObjString*)token->At(j);
376  TString stok = tok->GetString();
377 
378  if(stok=="*") continue;
379 
380  if(j==0) {
381  TString wdm_fres=stok;
382  if(wdm_fres.IsDigit()) gOPT.ccut_wdm_fres=wdm_fres.Atoi();
383  else {cout<<"cwb_pereport - Error : wdm_fres is not integer"<<endl;exit(1);}
384  }
385  if(j==1) {
386  TString mc_lower_factor=stok;
387  if(mc_lower_factor.IsFloat()) gOPT.ccut_bchirp=mc_lower_factor.Atof();
388  else {cout<<"cwb_pereport - Error : mc_lower_factor is not float"<<endl;exit(1);}
389  }
390  if(j==2) {
391  TString mc_upper_factor=stok;
392  if(mc_upper_factor.IsFloat()) gOPT.ccut_uchirp=mc_upper_factor.Atof();
393  else {cout<<"cwb_pereport - Error : mc_upper_factor is not float"<<endl;exit(1);}
394  }
395  if(j==3) {
396  TString left_time=stok;
397  if(left_time.IsFloat()) gOPT.ccut_ltime=left_time.Atof();
398  else {cout<<"cwb_pereport - Error : left_time is not float"<<endl;exit(1);}
399  }
400  if(j==4) {
401  TString right_time=stok;
402  if(right_time.IsFloat()) gOPT.ccut_rtime=right_time.Atof();
403  else {cout<<"cwb_pereport - Error : right_time is not float"<<endl;exit(1);}
404  }
405  }
406 
407  int x=gOPT.ccut_wdm_fres; // must be power of 2
408  if(!((x != 0) && ((x & (~x + 1)) == x)) || gOPT.ccut_wdm_fres<=0) {
409  cout<<"cwb_pereport : upTDF parameter non valid : must be power of 2 : "<<gOPT.ccut_wdm_fres<<endl;
410  exit(1);
411  }
412  if(gOPT.ccut_bchirp < 0) {
413  cout<<"cwb_pereport - Error :.ccut_bchirp must be >= 0"<<endl;
414  exit(1);
415  }
416  if(gOPT.ccut_bchirp > gOPT.ccut_uchirp) {
417  cout<<"cwb_pereport - Error :.ccut_bchirp must be < ccut_uchirp"<<endl;
418  exit(1);
419  }
420  if(gOPT.ccut_rtime < 0) {
421  cout<<"cwb_pereport - Error :.ccut_rtime >=0"<<endl;
422  exit(1);
423  }
424  if(gOPT.ccut_ltime < gOPT.ccut_rtime) {
425  cout<<"cwb_pereport - Error :.ccut_ltime must be >.ccut_rtime"<<endl;
426  exit(1);
427  }
428 }
429 
430 wavearray<double> GetCCut(wavearray<double>* ts, double tcoa, double m1, double m2, double s1z, double s2z) {
431 // apply chirp TF cuts and compute total energy inside the chirp cut region
432 
433  const auto& fchirp = static_cast<double(*)(double,double,double,double,double)>(CWB::mdc::SimIMRSEOBNRv4ROMFrequencyOfTime);
434  const auto& tchirp = static_cast<double(*)(double,double,double,double,double)>(CWB::mdc::SimIMRSEOBNRv4ROMTimeOfFrequency);
435 
436  // produce the TF map:
437  WSeries<double> W; // TF map container
438  W.Forward(*ts, *gWDM); // apply the WDM to the time series
439 
440  double fmin=16;
441  double fmax= ts->rate()/2.>320 ? 320. : ts->rate()/2.;
442 
443  //#define nPx 100
444  #define nPx 30
445  double T[nPx],Fb[nPx],Fu[nPx];
446  double dF = (fmax-fmin)/nPx;
447  for(int i=0;i<nPx;i++) {
448  double F = fmin+i*dF;
449  Fb[i] = gOPT.ccut_bchirp*F; // alpha bottom
450  Fu[i] = gOPT.ccut_uchirp*F; // alpha up
451  T[i] = tcoa-tchirp(F,m1,m2,s1z,s2z);
452  }
453  TSpline3 tbchirp("tbchirp",Fb,T,nPx); // bottom chirp line (time vs freq)
454  TSpline3 tuchirp("tuchirp",Fu,T,nPx); // up chirp line (time vs freq)
455  TSpline3 fbchirp("fbchirp",T,Fb,nPx); // bottom chirp line (freq vs time)
456  TSpline3 fuchirp("fuchirp",T,Fu,nPx); // up chirp line (freq vs time)
457 
458  double df = W.resolution(); // frequency pixel resolution (hz)
459  double dt = 1./(2*df); // time pixel resolution (sec)
460 
461  int layers = W.maxLayer()+1; // numbers of frequency bins (first & last bins have df/2)
462  int slices = W.sizeZero(); // number of time bins
463 
464  double tl = tcoa-gOPT.ccut_ltime; // left time cut
465  double tr = tcoa-gOPT.ccut_rtime; // right time cut
466 
467  // rescale the phase 00/90 pixel amplitudes
468 
469  for(int i=1;i<slices;i++) { // loop over time bins
470 
471  double time = i*dt; // pixel central time
472 
473  double tm = time-dt/2; // pixel minimum time
474  double tM = time+dt/2; // pixel maximum time
475 
476  if(tm<tl-dt || tM>tr+dt) { // remove pixels outside the time interval [tl-dt:tr+dt]
477  for(int j=1;j<layers;j++) { // loop over frequency bins
478  W.putSample(0,i,j+0.01); // zero a00 pixel amplitude
479  W.putSample(0,i,-(j+0.01)); // zero a90 pixel amplitude
480  }
481  continue;
482  }
483 
484  double fb = fbchirp.Eval(time); // fbchirp frequency at pixel central time
485  double fu = fuchirp.Eval(time); // fuchirp frequency at pixel central time
486 
487  if(TMath::IsNaN(fb)) fb = ts->rate()/2.; // check if fb is NaN
488  if(TMath::IsNaN(fu)) fu = ts->rate()/2.; // check if fu is NaN
489 
490  double f1 = fbchirp.Eval(tm); // fbchirp frequency at pixel minimum time
491  double f2 = fbchirp.Eval(tM); // fbchirp frequency at pixel maximum time
492  double f3 = fuchirp.Eval(tm); // fuchirp frequency at pixel minimum time
493  double f4 = fuchirp.Eval(tM); // fuchirp frequency at pixel maximum time
494 
495  for(int j=1;j<layers;j++) { // loop over frequency bins
496 
497  double freq = j*df; // pixel central frequency
498 
499  double fm = freq-df/2; // pixel minimum frequency
500  double fM = freq+df/2; // pixel maximum frequency
501 
502  if(fm<fmin || fM>fmax) {
503  W.putSample(0,i,j+0.01); // zero a00 pixel amplitude
504  W.putSample(0,i,-(j+0.01)); // zero a90 pixel amplitude
505  continue;
506  }
507 
508  double t1 = tbchirp.Eval(fm); // fbchirp time at pixel minimum frequency
509  double t2 = tbchirp.Eval(fM); // fbchirp time at pixel maximum frequency
510  double t3 = tuchirp.Eval(fm); // fuchirp time at pixel minimum frequency
511  double t4 = tuchirp.Eval(fM); // fuchirp time at pixel maximum frequency
512 
513  // check if pixel is inside the time cut range tl,tr
514  bool ctime = (tM>tl && tm<tr) ? true : false;
515 
516  // check if pixel is inside the frequency cut range fb,fu
517  bool cfreq = (fM>fb && fm<fu) ? true : false;
518 
519  double x1=t1,x2=t2,x3=t3,x4=t4,xm=tm,xM=tM; // assign x* = t*
520  double y1=f1,y2=f2,y3=f3,y4=f4,ym=fm,yM=fM; // assign y* = f*
521 
522  // for pixels crossed by the cut times tl,tr assign new time pixel boundaries xm,xM and new f*
523  if(tl>tm && tl<tM) {xm=tl; f1 = fbchirp.Eval(xm); f3 = fuchirp.Eval(xm);}
524  if(tr>tm && tr<tM) {xM=tr; f2 = fbchirp.Eval(xM); f4 = fuchirp.Eval(xM);}
525 
526  y1=f1,y2=f2,y3=f3,y4=f4; // update y*
527 
528  // check if pixel is crossed by fbchirp,fuchirp lines
529  // a pixel is crossed by the chirp lines if at least one of t*,f* points are inside the time/freq pixel ranges
530 
531  bool cline=false; // false/true = not-crossed/crossed
532 
533  if(t1>xm && t1<xM) cline=true;
534  if(t2>xm && t2<xM) cline=true;
535  if(t3>xm && t3<xM) cline=true;
536  if(t4>xm && t4<xM) cline=true;
537 
538  if(f1>ym && f1<yM) cline=true;
539  if(f2>ym && f2<yM) cline=true;
540  if(f3>ym && f3<yM) cline=true;
541  if(f4>ym && f4<yM) cline=true;
542 
543  double Ap=(xM-xm)*(yM-ym); // area pixel (is <=0.5 = total pixel area)
544 
545  if(ctime&&cline) { // pixels crossed by fbchirp,fuchirp lines and inside the time cut range tl,tr
546 
547  // for pixels with frequency outside the frequency pixel range assign ym,yM
548  if(y1<ym) y1=ym; if(y1>yM) y1=yM;
549  if(y2<ym) y2=ym; if(y2>yM) y2=yM;
550  if(y3<ym) y3=ym; if(y3>yM) y3=yM;
551  if(y4<ym) y4=ym; if(y4>yM) y4=yM;
552 
553  // compute area Ab for pixels crossed by fbchirp line
554 
555  double Ab=0; // area pixel above the fbchirp line
556 
557  // for pixels with times t1,t2 outside the time pixel range assign xm,xM and compute the corresponding new frequencies y1,y2
558  if(t1<xm) {x1=xm; y1 = fbchirp.Eval(x1);}
559  if(t1>xM) {x1=xM; y1 = fbchirp.Eval(x1);}
560  if(t2<xm) {x2=xm; y2 = fbchirp.Eval(x2);}
561  if(t2>xM) {x2=xM; y2 = fbchirp.Eval(x2);}
562 
563  // for pixels with frequency outside the frequency pixel range assign ym,yM
564  if(y1<ym) y1=ym; if(y1>yM) y1=yM;
565  if(y2<ym) y2=ym; if(y2>yM) y2=yM;
566 
567  // compute area pixel above the fbchirp line
568  if(y1 >ym && y2==yM) Ab = (x2-xm)*(yM-y1)/2;
569  if(y1 >ym && y2 <yM) Ab = (xM-xm)*(yM-y2)+(xM-xm)*(y2-y1)/2;
570  if(y1==ym && y2==yM) Ab = (x1-xm)*(yM-ym)+(x2-x1)*(yM-ym)/2;
571  if(y1==ym && y2 <yM) Ab = Ap-(xM-x1)*(y2-ym)/2;
572 
573  // compute area Au for pixels crossed by fuchirp line
574 
575  double Au=0; // area pixel below the fuchirp line
576 
577  // for pixels with times t3,t4 outside the time pixel range assign xm,xM and compute the corresponding new frequencies y3,y4
578  if(t3<xm) {x3=xm; y3 = fuchirp.Eval(x3);}
579  if(t3>xM) {x3=xM; y3 = fuchirp.Eval(x3);}
580  if(t4<xm) {x4=xm; y4 = fuchirp.Eval(x4);}
581  if(t4>xM) {x4=xM; y4 = fuchirp.Eval(x4);}
582 
583  // for pixels with frequency outside the frequency pixel range assign ym,yM
584  if(y3<ym) y3=ym; if(y3>yM) y3=yM;
585  if(y4<ym) y4=ym; if(y4>yM) y4=yM;
586 
587  // compute area pixel below the fuchirp line
588  if(y3 >ym && y4==yM) Au = Ap-(x4-xm)*(yM-y3)/2;
589  if(y3 >ym && y4 <yM) Au = (xM-xm)*(y3-ym)+(xM-xm)*(y4-y3)/2;
590  if(y3==ym && y4==yM) Au = (xM-x4)*(yM-ym)+(x4-x3)*(yM-ym)/2;
591  if(y3==ym && y4 <yM) Au = (xM-x3)*(y4-ym)/2;
592 
593  if(Ab<0) Ab=0; if(Ab>Ap) Ab=Ap; // fix area inconsistency due to precision errors
594  if(Au<0) Au=0; if(Au>Au) Au=Au; // fix area inconsistency due to precision errors
595  double A = Ab+Au; A-=Ap; // combine Ab and Au when pixel is crossed by fbchirp fuchirp lines
596 
597  if(A<0) {cout << "GetCCut Warning: pixel area < 0 " << endl; A=0;}
598  if(A>Ap) {cout << "GetCCut Warning: pixel area > Ap " << endl; A=Ap;}
599  double R=sqrt(A/0.5); // compute the rescaling amplitude factor (0.5 is the total pixel area)
600 #ifdef DEBUGGING
601  TString tag = R==0 ? "*" : "";
602  TString sR = TString::Format("A - GetCCut Rescaling Factor: Ap %0.3f %0.3f %0.3f %0.3f \ttime %0.3f \tfreq %0.3f \tR %0.9f \t%s",Ap,Ab,Au,A,time,freq,R,tag.Data());
603  cout << sR << endl;
604 #endif
605  double a00 = W.getSample(i,j+0.01); W.putSample(a00*R,i,j+0.01); // rescaling a00 pixel amplitude
606  double a90 = W.getSample(i,-(j+0.01));W.putSample(a90*R,i,-(j+0.01)); // rescaling a90 pixel amplitude
607  }
608 
609  if((ctime && cfreq) && !cline) { // pixels inside/outside the chirp cut area not belonging to the cline pixels
610 
611  double R = (x4<=tl || x1>=tr) ? 0 : sqrt(Ap/0.5); // compute the rescaling amplitude factor (0.5 is the total pixel area)
612  // remove pixels outside the time interval [tl,tr]
613 
614 #ifdef DEBUGGING
615  TString tag = "+";
616  TString sR = TString::Format("B - GetCCut Rescaling Factor: Ap %0.3f \ttime %0.3f \tfreq %0.3f \tR %0.3f \t%s",Ap,time,freq,R,tag.Data());
617  cout << sR << endl;
618 #endif
619  double a00 = W.getSample(i,j+0.01); W.putSample(a00*R,i,j+0.01); // rescaling a00 pixel amplitude
620  double a90 = W.getSample(i,-(j+0.01));W.putSample(a90*R,i,-(j+0.01)); // rescaling a90 pixel amplitude
621  }
622 
623  //if(ctime && cfreq) {
624  //if(ctime && cline) {
625  //if((ctime && cfreq) && !cline) {
626  if((ctime && cline)||(ctime && cfreq)) {
627  } else {
628  W.putSample(0,i,j+0.01);
629  W.putSample(0,i,-(j+0.01));
630  }
631  }
632  }
633 
634  double Et=0; // Energy in time-frequency chirp cut region
635  for(int i=1;i<slices;i++) { // loop over time bins
636  for(int j=1;j<layers;j++) { // loop over frequency bins
637  double a00 = W.getSample(i,j+0.01); // read a00 pixel amplitude
638  double a90 = W.getSample(i,-(j+0.01)); // read a90 pixel amplitude
639  Et+=(a00*a00+a90*a90)/2;
640  }
641  }
642 
643  cout << "GetCCut Energy chirp cut (TF domain): " << Et << endl;
644 
645 #ifdef DEBUGGING
646  DrawCCut(W, tcoa, m1, m2, s1z, s2z);
647 #endif
648 
649  // return to time domain
650  WSeries<double> xW = W;
651  W.Inverse();
652  xW.Inverse(-2);
653  W += xW;
654  W *= 0.5;
655 
656  return W;
657 }
658 
659 void DrawCCut(WSeries<double> W, double tcoa, double m1, double m2, double s1z, double s2z) { // apply transformation on white noise and plot it
660 
661  const auto& fchirp = static_cast<double(*)(double,double,double,double,double)>(CWB::mdc::SimIMRSEOBNRv4ROMFrequencyOfTime);
662  const auto& tchirp = static_cast<double(*)(double,double,double,double,double)>(CWB::mdc::SimIMRSEOBNRv4ROMTimeOfFrequency);
663 
664  #define nPX2 100
665 
667  double SM = watconstants::SolarMass();
669  double D = G*SM/C/C/C;
670 
671  double tmax=tcoa;
672  double tmin=tmax-0.5;
673 
674  double fmin=16;
675  double fmax= W.rate()/2.>320 ? 320. : W.rate()/2.;
676 
677  #define nPx2 100
678  //#define nPx2 30
679  double T[nPx2],Fb[nPx2],Fu[nPx2];
680  double dF = (fmax-fmin)/nPx2;
681  for(int i=0;i<nPx2;i++) {
682  double F = fmin+i*dF;
683  Fb[i] = gOPT.ccut_bchirp*F; // alpha bottom
684  Fu[i] = gOPT.ccut_uchirp*F; // alpha up
685  T[i] = tcoa-tchirp(F,m1,m2,s1z,s2z);
686  }
687  TSpline3 tbchirp("tbchirp",Fb,T,nPx2); // bottom chirp line (time vs freq)
688  TSpline3 tuchirp("tuchirp",Fu,T,nPx2); // up chirp line (time vs freq)
689  TSpline3 fbchirp("fbchirp",T,Fb,nPx2); // bottom chirp line (freq vs time)
690  TSpline3 fuchirp("fuchirp",T,Fu,nPx2); // up chirp line (freq vs time)
691 
692  // plot the TF map as energy average of 0 and 90 degree phases (quadratures)
693  TString wplot_id=TString::Format("%d",int(gRandom->Uniform(0,10000000)));
694  watplot* wplot = new watplot(const_cast<char*>(wplot_id.Data()));
695  wplot->canvas->SetLogy();
696  wplot->plot(W);
697  wplot->hist2D->GetXaxis()->SetRangeUser(6.4,7.2);
698  wplot->hist2D->GetYaxis()->SetRangeUser(0,600);
699  wplot->hist2D->GetYaxis()->SetRangeUser(30,600);
700 
701  double xb[nPX2],yb[nPX2];
702  double dxb=(tmax-tmin)/nPX2;
703  for(int i=0;i<nPX2;i++) {
704  xb[i]=tmin+i*dxb;
705  //yb[i]=fbchirp->GetX(xb[i]);
706  yb[i]=fbchirp.Eval(xb[i]);
707  }
708  TGraph* grb = new TGraph(nPX2,xb,yb);
709  grb->SetLineColor(kWhite);
710  grb->SetLineWidth(3);
711  grb->SetLineStyle(2);
712  grb->Draw("same");
713 
714  double xu[nPX2],yu[nPX2];
715  double dxu=(tmax-tmin)/nPX2;
716  for(int i=0;i<nPX2;i++) {
717  xu[i]=tmin+i*dxu;
718  //yu[i]=fuchirp->GetX(xu[i]);
719  yu[i]=fuchirp.Eval(xu[i]);
720  }
721  TGraph* gru = new TGraph(nPX2,xu,yu);
722  gru->SetLineColor(kWhite);
723  gru->SetLineWidth(3);
724  gru->SetLineStyle(2);
725  gru->Draw("same");
726 
727  double p0;
728 
729  // left time chirp cut line
730  p0 = tcoa-gOPT.ccut_ltime; // left time cut
731  flchirp = new TLine(p0,0,p0,600);
732  flchirp->SetLineColor(kBlack);
733  flchirp->SetLineWidth(3);
734  flchirp->SetLineStyle(2);
735  flchirp->Draw("same");
736 
737  // right time chirp cut line
738  p0 = tcoa-gOPT.ccut_rtime; // left time cut
739  frchirp = new TLine(p0,0,p0,600);
740  frchirp->SetLineColor(kBlack);
741  frchirp->SetLineWidth(3);
742  frchirp->SetLineStyle(2);
743  frchirp->Draw("same");
744 
745  // right time chirp cut line
746  p0 = tcoa; // tcoa time
747  ftcoa = new TLine(p0,0,p0,600);
748  ftcoa->SetLineColor(kRed);
749  ftcoa->SetLineWidth(2);
750  ftcoa->SetLineStyle(1);
751  ftcoa->Draw("same");
752 }
753 
TF1 * fuchirp
Definition: DrawCCutxPE.C:83
double rho
static const double C
Definition: GNGen.cc:28
std::vector< wavearray< double > > vREC
int slices
TH1 * t1
float wM2[PE_MAX_EVENTS]
Definition: DrawCCutxPE.C:33
virtual void rate(double r)
Definition: wavearray.hh:141
#define CCUT_BCHIRP
Definition: DrawCCutxPE.C:72
double m1
int n
Definition: cwb_net.C:28
TString("c")
void putSample(DataType_t a, int n, double m)
Definition: wseries.hh:195
cout<< endl;cout<< "ts size = "<< ts.size()<< " ts rate = "<< ts.rate()<< endl;tf.Forward(ts, wdm);int levels=tf.getLevel();cout<< "tf size = "<< tf.size()<< endl;double dF=tf.resolution();double dT=1./(2 *dF);cout<< "rate(hz) : "<< RATE<< "\ layers : "<< nLAYERS<< "\ dF(hz) : "<< dF<< "\ dT(ms) : "<< dT *1000.<< endl;int itime=TIME_PIXEL_INDEX;int ifreq=FREQ_PIXEL_INDEX;int index=(levels+1) *itime+ifreq;double time=itime *dT;double freq=(ifreq >0) ? ifreq *dF :dF/4;cout<< endl;cout<< "PIXEL TIME = "<< time<< " sec "<< endl;cout<< "PIXEL FREQ = "<< freq<< " Hz "<< endl;cout<< endl;wavearray< double > x
double SolarMass()
Definition: constants.hh:202
float theta
TString mdc[4]
int layers
std::vector< wavearray< double > > vINJ
TLine * frchirp
Definition: DrawCCutxPE.C:81
int j
Definition: cwb_net.C:28
i drho i
void plot(wavearray< double > &, char *=NULL, int=1, double=0., double=0., bool=false, float=0., float=0., bool=false, float=0., bool=false)
Definition: watplot.cc:150
#define CCUT_WDM_FRES
Definition: DrawCCutxPE.C:71
std::vector< wavearray< double > > wREC[PE_MAX_EVENTS]
Definition: DrawCCutxPE.C:26
double GetDelay(TString ifo1, TString ifo2, double phi, double theta)
Definition: mdc.cc:4523
watplot * DrawTime(wavearray< double > &x, TString options="ALP", Color_t color=kBlack)
Definition: mdc.cc:2410
#define nPX2
char ifo[NIFO_MAX][8]
TH2F * hist2D
Definition: watplot.hh:193
virtual double rms()
Definition: wavearray.cc:1206
double tstart
virtual size_t size() const
Definition: wavearray.hh:145
TCanvas * canvas
Definition: watplot.hh:192
#define CCUT_LTIME
Definition: DrawCCutxPE.C:74
float phi
#define PE_MAX_EVENTS
Definition: DrawCCutxPE.C:23
TLine * flchirp
Definition: DrawCCutxPE.C:80
wavearray< double > freq
Definition: Regression_H1.C:79
double G
Definition: DrawEBHH.C:12
static double GetMatchFactor(TString match, vector< wavearray< double > > &w1, vector< wavearray< double > > &w2, vector< double > tstart=DEFAULT_VECtOR_DOUBLE, vector< double > tstop=DEFAULT_VECtOR_DOUBLE)
Definition: mdc.cc:7737
Definition: mdc.hh:248
TF1 * f2
static wavearray< double > GetEnvelope(wavearray< double > *x)
Definition: mdc.cc:7828
static const double SM
Definition: GNGen.cc:26
wavearray< double > GetCCut(wavearray< double > *ts, double tcoa, double m1, double m2, double s1z, double s2z)
Definition: DrawCCutxPE.C:430
i() int(T_cor *100))
network NET
Definition: cwb_dump_inj.C:30
bool log
Definition: WaveMDC.C:41
double D[50000]
TString GetParameterFromInjLog(TString log, TString param)
Definition: DrawCCutxPE.C:320
int gEVENTS
Definition: DrawCCutxPE.C:38
WDM< double > * gWDM
Definition: DrawCCutxPE.C:66
void GetCCutParms(TString options)
Definition: DrawCCutxPE.C:354
int k
double GetInjTcoa(double geocentric_tcoa, network *NET, TString ifo, double theta, double phi)
Definition: DrawCCutxPE.C:309
double tstop
void DrawCCut(wavearray< double > *ts, double tcoa, double m1, double m2, double s1z, double s2z)
Definition: DrawCCutxPE.C:345
static double A
Definition: geodesics.cc:26
TObjArray * token
x *double Et
Definition: ComputeSNR.C:40
double F
float wTHETA[PE_MAX_EVENTS]
Definition: DrawCCutxPE.C:30
float wS1[PE_MAX_EVENTS]
Definition: DrawCCutxPE.C:34
std::vector< wavearray< double > > wINJ[PE_MAX_EVENTS]
Definition: DrawCCutxPE.C:27
#define nPx
static wavearray< double > GetBandpass(wavearray< double > x, double bF, double eF)
Definition: mdc.cc:7889
watplot * DrawFFT(wavearray< double > &x, TString options="ALP", Color_t color=kBlack)
Definition: mdc.cc:2456
char tag[256]
Definition: cwb_merge.C:92
TFile * froot
double dt
double GravitationalConstant()
Definition: constants.hh:131
float wM1[PE_MAX_EVENTS]
Definition: DrawCCutxPE.C:32
char options[256]
double T
Definition: testWDM_4.C:11
static wavearray< double > GetDiff(wavearray< double > *w1, wavearray< double > *w2)
Definition: mdc.cc:7374
float wS2[PE_MAX_EVENTS]
Definition: DrawCCutxPE.C:35
wavearray< double > ts(N)
TLine * ftcoa
Definition: DrawCCutxPE.C:79
TF1 * fchirp
Definition: ChirpMass.C:122
double resolution(int=0)
Definition: wseries.hh:155
double m2
static TString gIFO[3]
Definition: DrawCCutxPE.C:39
void Forward(int n=-1)
param: wavelet - n is number of steps (-1 means full decomposition)
Definition: wseries.cc:246
float wRHO[PE_MAX_EVENTS]
Definition: DrawCCutxPE.C:36
double df
#define CCUT_RTIME
Definition: DrawCCutxPE.C:75
TTree * itree
#define nPx2
static double TimePhaseSync(wavearray< double > &w1, wavearray< double > &w2, double &sync_time, double &sync_phase)
Definition: mdc.cc:7610
uoptions gOPT
Definition: DrawCCutxPE.C:65
DataType_t getSample(int n, double m)
Definition: wseries.hh:185
TF1 * fbchirp
Definition: DrawCCutxPE.C:82
double ctime
double wTCOA[PE_MAX_EVENTS]
Definition: DrawCCutxPE.C:29
#define N_IFO
Definition: DrawCCutxPE.C:24
void Inverse(int n=-1)
param: n - number of steps (-1 means full reconstruction)
Definition: wseries.cc:291
size_t sizeZero()
Definition: wseries.hh:144
#define CCUT_UCHIRP
Definition: DrawCCutxPE.C:73
int maxLayer()
Definition: wseries.hh:139
float wPHI[PE_MAX_EVENTS]
Definition: DrawCCutxPE.C:31
CWB::mdc * MDC
Definition: DrawCCutxPE.C:78
exit(0)
double SpeedOfLightInVacuo()
Definition: constants.hh:114
void DrawCCutxPE(TString ifname, int wf_id=0, int ifo_id=0, TString options="16:1.40:1.60:0.5:0.0")
Definition: DrawCCutxPE.C:101