Logo coherent WaveBurst  
Library Reference Guide
Logo
mdc.cc
Go to the documentation of this file.
1 /*
2 # Copyright (C) 2019 Gabriele Vedovato, Francesco Salemi
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 //#define NEW_CODE_FOR_SEOBNRv4P_AND_SEOBNRv4PHM // uncomment this line to enable the SEOBNRv4P_AND_SEOBNRv4PHM
19  // corrently available only in the following branch:
20  // https://git.ligo.org/serguei.ossokine/lalsuite/tree/SEOBNRv4PHM-review-rebase-Sep2019
21 
22 #include "mdc.hh"
23 #include "constants.hh"
24 #include "TSpline.h"
25 
26 #ifdef _USE_LAL
27 
28 #include <lal/Interpolate.h>
29 
30 // LAL Stuff
31 #define FAILMSG( stat, func, file, line, id ) \
32  do { \
33  if ( lalDebugLevel & LALERROR ) \
34  { \
35  LALPrintError( "Error[0]: file %s, line %d, %s\n" \
36  "\tLAL_CALL: Function call `%s' failed.\n", file, line, id, func ); \
37  } \
38  } while( 0 )
39 
40 #define LAL_CALL( function, statusptr ) \
41  ((function),lal_errhandler(statusptr,#function,__FILE__,__LINE__,"$Id$"))
42 
43 LALStatus blank_status;
44 
45 typedef int ( *lal_errhandler_t )(
46  LALStatus *,
47  const char *func,
48  const char *file,
49  const int line,
50  volatile const char *id
51  );
52 
53 int LAL_ERR_ABRT(
54  LALStatus *stat,
55  const char *func,
56  const char *file,
57  const int line,
58  volatile const char *id
59  )
60 {
61  if ( stat->statusCode )
62  {
63  FAILMSG( stat, func, file, line, id );
64  abort();
65  }
66  return 0;
67 }
68 
69 int LAL_ERR_EXIT(
70  LALStatus *stat,
71  const char *func,
72  const char *file,
73  const int line,
74  volatile const char *id
75  )
76 {
77  if ( stat->statusCode )
78  {
79  FAILMSG( stat, func, file, line, id );
80  exit( 1 );
81  }
82  return stat->statusCode;
83 }
84 
85 //#define LAL_ERR_DFLT LAL_ERR_ABRT
86 lal_errhandler_t lal_errhandler = LAL_ERR_ABRT;
87 
88 // see LAL binj.c
89 static
90 ProcessParamsTable **add_process_param(ProcessParamsTable **proc_param, const ProcessTable *process,
91  const char *type, const char *param, const char *value) {
92  *proc_param = XLALCreateProcessParamsTableRow(process);
93  snprintf((*proc_param)->program, sizeof((*proc_param)->program), "%s", "cWB");
94  snprintf((*proc_param)->type, sizeof((*proc_param)->type), "%s", type);
95  snprintf((*proc_param)->param, sizeof((*proc_param)->param), "--%s", param);
96  snprintf((*proc_param)->value, sizeof((*proc_param)->value), "%s", value);
97  return &(*proc_param)->next;
98 }
99 
100 #define ADD_PROCESS_PARAM(proc_param, process, type, param, value) \
101  do { proc_param = add_process_param(proc_param, process, type, param, value); } while(0)
102 
103 #endif
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /* BEGIN_HTML
107 <p>The mdc class is designed to easily produce mdc data for simulation
108 
109 Overview:
110 <ol style="list-style-type: upper-roman;">
111  <li><a href="#init">Init</a></li>
112  <li><a href="#conf">Configuration</a>
113  <ol>
114  <li><a href="#conf:setparms">Set Injection Params</a></li>
115  <li><a href="#conf:waveform">Add Waveforms</a></li>
116  <li><a href="#conf:skydistribution">Set SkyDistribution</a></li>
117  </ol>
118  </li>
119  <li><a href="#getdata">Get Data</a></li>
120  <li><a href="#writeframe">Write Frame</a></li>
121 </ol>
122 
123 <h3><a name="init">I. Init</a></h3>
124 Object mdc must be instantiate setting the network detectors:
125 <br><br>
126 <pre>
127  root[] char wf_name[256];
128  root[] waveform wf;
129  root[] vector<mdcpar> par;
130  root[] int nIFO = 3; // number of detectors
131  root[] TString ifo[3] = {"L1","H1","V1"};
132  root[] mdc MDC(nIFO,ifo); // create a mdc object
133 </pre>
134 <h3><a name="conf">II. Configuration</a></h3>
135 In the configuration phase must be define injection parameters, waveforms and sky distribution:
136 <br>
137 <h3><a name="conf:setparms">II.1 Set Injection Params</a></h3>
138 <br>
139 <pre>
140  root[] // --------------------------------------------------------
141  root[] // define injection parameters
142  root[] // --------------------------------------------------------
143  root[] MDC.SetInjHrss(2.5e-21);
144  root[] MDC.SetInjRate(0.0333333);
145  root[] MDC.SetInjJitter(10.0);
146 </pre>
147 <h3><a name="conf:setparms">II.2 Add Waveforms</a></h3>
148 <br>
149 <pre>
150  root[] // --------------------------------------------------------
151  root[] // Add SinGaussian waveform
152  root[] // --------------------------------------------------------
153  root[] par.resize(2);
154  root[] par[0].name="frequency"; par[0].value=235.;
155  root[] par[1].name="Q"; par[1].value=8.9;
156  root[] MDC.AddWaveform(MDC_SG, par);
157  root[] MDC.Print(); // list defined waveforms
158 </pre>
159 <h3><a name="conf:setparms">II.3 Set SkyDistribution</a></h3>
160 <br>
161 <pre>
162  root[] // --------------------------------------------------------
163  root[] // define sky distribution
164  root[] // --------------------------------------------------------
165  root[] par.resize(3);
166  root[] par[0].name="entries";par[0].value=100000; // pool of events
167  root[] par[1].name="rho_min";par[1].value=1; // min rho // Kpc
168  root[] par[2].name="rho_max";par[2].value=100; // max rho // Kpc
169  root[] MDC.SetSkyDistribution(MDC_RANDOM,par,seed);
170 </pre>
171 <h3><a name="getdata">III. Get Data</a></h3>
172 <br>
173 <pre>
174  root[] // --------------------------------------------------------
175  root[] // get data
176  root[] // --------------------------------------------------------
177  root[] waveform x;
178  root[] x.start(0);x.rate(16384);x.size(600*x.rate());
179  root[] MDC.Get(x,ifo[0]);
180 </pre>
181 <h3><a name="writeframe">IV. Write Frame</a></h3>
182 <br>
183 <pre>
184  root[] // --------------------------------------------------------
185  root[] // write frame
186  root[] // --------------------------------------------------------
187  root[] TString frDir = "frames";
188  root[] TString frLabel = "TEST";
189  root[] size_t gps = 123456789;
190  root[] size_t length = 1000; // sec
191  root[] bool log = true;
192  root[] TString ofName = MDC.WriteFrameFile(frDir, frLabel, gps, length, log);
193 </pre>
194 
195 </p>
196 
197 END_HTML */
198 ////////////////////////////////////////////////////////////////////////////////
199 
200 ClassImp(CWB::mdc)
201 
202 //______________________________________________________________________________
203 CWB::mdc::mdc() {
204 //
205 // mdc default constructor
206 //
207 
208  Init();
209  net=NULL;
210 }
211 
212 //______________________________________________________________________________
214 //
215 // mdc constructor
216 //
217 // Input: nIFO - number of detectors
218 // ifo - array of detector names
219 //
220 
221  Init();
222  net = new network;
223 
224  for(int n=0;n<nIFO;n++) net->add(new detector(const_cast<char*>(ifo[n].Data())));
225 }
226 
227 //______________________________________________________________________________
229 //
230 // mdc constructor
231 //
232 // Input: nIFO - number of detectors
233 // pD - array of detector objects
234 //
235 
236  Init();
237  net = new network;
238 
239  for(int n=0; n<nIFO; n++) {
240  detector* _pD = NULL;
241  if(pD[n]->isBuiltin()) _pD = new detector(pD[n]->Name);
242  else _pD = new detector(pD[n]->getDetectorParams());
243  this->net->add(_pD);
244  }
245 }
246 
247 //______________________________________________________________________________
249 //
250 // mdc constructor
251 //
252 // Input: net - network object
253 //
254 
255  Init();
256 
257  if(net!=NULL) {
258 
259  this->net = new network;
260 
261  int nIFO=net->ifoListSize();
262  for(int n=0; n<nIFO; n++) {
263  detector* pD = NULL;
264  if(net->getifo(n)->isBuiltin()) pD = new detector(net->getifo(n)->Name);
265  else pD = new detector(net->getifo(n)->getDetectorParams());
267  pD->setPolarization(polarization);
268  this->net->add(pD);
269  }
270  } else {
271  this->net = NULL;
272  }
273 }
274 
275 //______________________________________________________________________________
277 //
278 // mdc copy constructor
279 //
280 
281  *this = value;
282 }
283 
284 //______________________________________________________________________________
286 //
287 // mdc destructor
288 //
289 
290  if(net!=NULL) {
291  for(int n=0;n<(int)net->ifoListSize();n++) delete net->getifo(n);
292  delete net;
293  }
294  if(inj!=NULL) delete inj;
296  if(inj_tree!=NULL) delete inj_tree;
297 
298  if(psp!=NULL) delete psp;
299  if(stft!=NULL) delete stft;
300  if(pts!=NULL) delete pts;
301 }
302 
303 //______________________________________________________________________________
304 CWB::mdc&
306 //
307 // mdc copy constructor
308 //
309 
310  if(value.net!=NULL) {
311  if(net==NULL) net = new network;
312  else {for(int n=0;n<(int)net->ifoListSize();n++) delete net->getifo(n);}
313  *(net)=*(value.net);
314  net->ifoList.resize(0);
315  int nIFO=value.net->ifoListSize();
316  for(int n=0; n<nIFO; n++) {
317  detector* pD = value.net->getifo(n);
318  if(value.net->getifo(n)->isBuiltin()) net->add(new detector(pD->Name));
319  else net->add(new detector(pD->getDetectorParams()));
321  net->getifo(n)->setPolarization(polarization);
322  }
323  }
324 
325  if(value.inj!=NULL) {
326  int nIFO=net->ifoListSize();
327  if(inj!=NULL) delete inj;
328  inj = new injection(nIFO);
329  inj_tree = inj->setTree();
330  if(value.inj_tree!=NULL) {
331  inj->output(inj_tree,net,1,false);
332  delete inj;
333  inj = new injection(inj_tree,nIFO);
334  }
335  }
336 
337 // if(psp!=NULL) delete psp; psp=NULL;
338 // if(stft!=NULL) delete stft; stft=NULL;
339 // if(pts!=NULL) delete pts; pts=NULL;
340 
343 
344  inspCLB = value.inspCLB;
345  inspXML = value.inspXML;
346  inspDIR = value.inspDIR;
347  inspName = value.inspName;
348  inspOptions = value.inspOptions;
349  waveName = value.waveName;
350 
351  inj_rate = value.inj_rate;
352  inj_offset = value.inj_offset;
353  inj_jitter = value.inj_jitter;
354  inj_hrss = value.inj_hrss;
355  srcList_seed = value.srcList_seed;
356 
357  wfList.clear(); this->wfList = value.wfList;
358  mdcList.clear(); this->mdcList = value.mdcList;
359  mdcType.clear(); this->mdcType = value.mdcType;
360  xmlType.clear(); this->xmlType = value.xmlType;
361  mdcTime.clear(); this->mdcTime = value.mdcTime;
362  mdcName.clear(); this->mdcName = value.mdcName;
363  srcList.clear(); this->srcList = value.srcList;
364  nameList.clear(); this->nameList = value.nameList;
365  thList.clear(); this->thList = value.thList;
366  phList.clear(); this->phList = value.phList;
367  psiList.clear(); this->psiList = value.psiList;
368  rhoList.clear(); this->rhoList = value.rhoList;
369  iotaList.clear(); this->iotaList = value.iotaList;
370  hrssList.clear(); this->hrssList = value.hrssList;
371  gpsList.clear(); this->gpsList = value.gpsList;
372  IDList.clear(); this->IDList = value.IDList;
373  idList.clear(); this->idList = value.idList;
374 
375  return *this;
376 }
377 
378 //______________________________________________________________________________
379 void
381 //
382 // mdc init
383 //
384 // Input: seed - seed for random generation
385 //
386 
387  inj=NULL;
388  inj_tree=NULL;
389  psp=NULL;
390  stft=NULL;
391  pts=NULL;
392  inspCLB="";
393  inspXML="";
394  inspDIR="";
395  inspName="";
396  inspOptions="";
397  waveName="";
398  xml_filename="";
399 
400  epzoom = EPZOOM;
401 
405  inj_offset = 0.;
408  srcList_seed = 0;
409  gRandom->SetSeed(seed);
410 
411  wfList.clear();
412  mdcList.clear();
413  mdcType.clear();
414  xmlType.clear();
415  mdcTime.clear();
416  mdcName.clear();
417  srcList.clear();
418  nameList.clear();
419  thList.clear();
420  phList.clear();
421  psiList.clear();
422  rhoList.clear();
423  iotaList.clear();
424  hrssList.clear();
425  gpsList.clear();
426  IDList.clear();
427  idList.clear();
428 }
429 
430 //______________________________________________________________________________
431 double
432 CWB::mdc::GetPar(TString name, vector<mdcpar> par, bool& error) {
433 //
434 // Return Waveform parameter
435 //
436 //
437 // Input: name - parameter name
438 // par - vector of parameters
439 //
440 // Return: parameter value
441 //
442 
443  for(int i=0;i<(int)par.size();i++) {
444  if(par[i].name.CompareTo(name)==0) return par[i].value;
445  }
446  error=true;
447  return 0.;
448 }
449 
450 //______________________________________________________________________________
451 TString
452 CWB::mdc::GetParString(TString name, vector<mdcpar> par, bool& error) {
453 //
454 // Return Waveform string parameter
455 //
456 //
457 // Input: name - parameter name
458 // par - vector of parameters
459 //
460 // Return: parameter string
461 //
462 
463  for(int i=0;i<(int)par.size();i++) {
464  if(par[i].name.CompareTo(name)==0) return par[i].svalue;
465  }
466  error=true;
467  return "";
468 }
469 
470 //______________________________________________________________________________
471 mdcid
472 CWB::mdc::AddWaveform(MDC_TYPE mdc_type, vector<mdcpar> par, TString uname) {
473 //
474 // Add Waveform to this object
475 //
476 //
477 // Input: mdc_type - name of mdc
478 // par - input mdc parameters
479 //
480 // mdc_type & par can be one of the following choices :
481 //
482 // MDC_SG/MDC_SGL = Linear SinGaussian
483 // MDC_SGC = Circular SinGaussian
484 // MDC_SGE = Elliptical SinGaussian // created as SGC (ellipticity must be defined by iota)
485 // vector<mdcpar> par(2);
486 // ` par[0].name="frequency"; par[0].value=XXX; // Hz
487 // par[1].name="Q"; par[1].value=YYY;
488 //
489 // MDC_CG/MDC_CGL = Linear CosGaussian
490 // MDC_CGC = Circular CosGaussian
491 // MDC_CGE = Elliptical CosGaussian // created as CGC (ellipticity must be defined by iota)
492 // vector<mdcpar> par(2);
493 // ` par[0].name="frequency"; par[0].value=XXX; // Hz
494 // par[1].name="Q"; par[1].value=YYY;
495 //
496 // MDC_RD/MDC_RDL = Linear RingDown
497 // MDC_RDC = Circular RingDown
498 // MDC_RDE = Elliptical RingDown // created as RGC (ellipticity must be defined by iota)
499 // vector<mdcpar> par(2);
500 // ` par[0].name="frequency"; par[0].value=XXX; // Hz
501 // par[1].name="tau"; par[1].value=YYY;
502 //
503 // MDC_SGE_LAL = LAL SinGaussian (see definition in LALSimBurst.c)
504 // Difference from MDC_SGE : LAL use CG instead of SG !!!
505 // force eccentricity=0 --> circularly polarized
506 // force polarization=0
507 // NOTE : created as SGC (ellipticity must be defined by iota)
508 // polarization=0 (polarization is defined by psi)
509 // vector<mdcpar> par(2);
510 // ` par[0].name="frequency"; par[0].value=XXX; // Hz
511 // par[1].name="Q"; par[1].value=YYY;
512 //
513 // MDC_WNB = White Noise Burst
514 // vector<mdcpar> par(x);
515 // par[0].name="frequency"; par[0].value=XXX; // Hz : initial frequency
516 // par[1].name="bandwidth"; par[1].value=YYY; // Hz
517 // par[2].name="duration"; par[2].value=ZZZ; // sec
518 // par[3].name="pseed"; par[3].value=ppp; // (opt) seed fo hp component (def=0)
519 // par[4].name="xseed"; par[4].value=xxx; // (opt) seed fo hx component (def=0)
520 // par[5].name="mode"; par[5].value=mmm; // (opt) 0/1 a/symmetric respect central freq
521 // // 0 = (default)
522 //
523 // MDC_WNB_LAL = LAL White Noise Burst (see definition in LALSimBurst.c)
524 // Difference from MDC_WNB : LAL has a gaussian envelope also in frequency
525 // NOtE : LAL seed = waveform_number = hseed*10000000000+lseed
526 // vector<mdcpar> par(5);
527 // par[0].name="frequency"; par[0].value=XXX; // Hz : central frequency
528 // par[1].name="bandwidth"; par[1].value=YYY; // Hz
529 // par[2].name="duration"; par[2].value=ZZZ; // sec
530 // par[3].name="lseed"; par[3].value=ppp; // low seed (max 10 int digits)
531 // par[4].name="hseed"; par[4].value=xxx; // high seed (max 10 int digits)
532 //
533 // MDC_GA = Gaussian Burst
534 // vector<mdcpar> par(1);
535 // par[0].name="duration"; par[0].value=XXX; // sec
536 //
537 // MDC_GA_LAL = LAL Gaussian (see definition in LALSimBurst.c)
538 // vector<mdcpar> par(1);
539 // par[0].name="duration"; par[0].value=XXX; // sec
540 //
541 // MDC_SC_LAL = LAL Generates cosmic string cusp waveforms (see definition in XLALGenerateStringCusp, LALSimBurst.c)
542 // vector<mdcpar> par(1);
543 // par[0].name="frequency"; par[0].value=XXX; // High frequency cut-off (Hertz)
544 // par[1].name="amplitude"; par[1].value=YYY; // amplitude (strain)
545 //
546 // MDC_EBBH = Eccentric Binary Black Holes // created as Circular (ellipticity must be defined by iota)
547 // // are generated with hrss @ distance GM/c^2 meters
548 // // custom hrss is disabled
549 // vector<mdcpar> par(1);
550 // par[0].name="file_name"; // ebbh list file name [.lst/.root]
551 // // .lst format : one event for each line
552 // // -> m1 m2 rp0 e0 (hp,hx are generated 'On The Fly')
553 // // .root format : one event for each entry
554 // // -> id m1 m2 rp0 e0 hp hx
555 // par[1].name="tree cuts"; // optional : used .root file to select tree entries
556 //
557 // or
558 //
559 // vector<mdcpar> par(1);
560 // par[0].name="ebbh parameters"; // ebbh parameters : id m1 m2 rp0 e0 dist(Kpc) redshift
561 //
562 // uname - is the name of waveform, if uname="" then uses the builtin name (default)
563 // not enable for MDC_EBBH
564 //
565 // Return: the name of waveform
566 //
567 //
568 // Note : For the elliptically polarized MDC's, they were produced as follows:
569 //
570 // h(t) = F_+ h_+(t) + F_x h_x(t)
571 //
572 // where
573 //
574 // h_+ = 0.5*(1+cos(iota) * A(t) cos(Phi(t))
575 // h_x = cos(iota) * A(t) sin(Phi(t))
576 //
577 // See Patrick's document here: (https://dcc.ligo.org/LIGO-P1000041)
578 //
579 
580  // check if mdc_type is in the MDC_TYPE list
581  if(mdc_type<0 || mdc_type>=MDC_USER) {
582  cout << "CWB::mdc::AddWaveform - Error : mdc type " << mdc_type << " not allowed !!!" << endl;
583  exit(1);
584  }
585 
586  char wf_name[128];
587  waveform wf;
588  mdcid waveid = {"",0,0};
589 
590  // get number of decimals to be used to format the waveform name
591  bool error=false;
592  int decimals = (int)GetPar("decimals",par,error);
593  if(error) decimals = -1; // default format (like BurstMDC)
594 
595  if((mdc_type==MDC_RDE) ||
596  (mdc_type==MDC_RDC) ||
597  (mdc_type==MDC_RD)) {
598 
599  error=false;
600  double frequency = GetPar("frequency",par,error);
601  double tau = GetPar("tau",par,error);
602  double iota=0.;
603  if(mdc_type==MDC_RDE) iota = 0.; // iota can be customized with SetSkyDistribution
604  if(mdc_type==MDC_RDC) iota = 0.;
605  if(mdc_type==MDC_RD) iota = 90.;
606 
607  if(error) {
608  cout << "CWB::mdc::AddWaveform - "
609  << "Error : num par must be at least 2 [frequency,tau]" << endl;
610  exit(1);
611  }
612 
613  int d1 = decimals==-1 ? 0 : decimals;
614  int d2 = decimals==-1 ? 1 : decimals;
615 
616  if(mdc_type==MDC_RD) sprintf(wf_name, "RD_%.*f_%.*f",d1,frequency,d2,tau);
617  if(mdc_type==MDC_RDC) sprintf(wf_name,"RDC_%.*f_%.*f",d1,frequency,d2,tau);
618  if(mdc_type==MDC_RDE) sprintf(wf_name,"RDE_%.*f_%.*f",d1,frequency,d2,tau);
619 
620  wf.type = mdc_type;
621  wf.name = wf_name;
622  wf.name.ReplaceAll(".","d");
623  if(uname!="") wf.name = uname;
624  wf.hp = GetRD(frequency,tau,iota,0);
625  wf.hx = GetRD(frequency,tau,iota,1);
626  wf.hpPath = wf.name;
627  wf.hxPath = wf.name;
628  wf.par=par;
629  return AddWaveform(wf);
630 
631  } else
632  if((mdc_type==MDC_SGC) ||
633  (mdc_type==MDC_SGE) ||
634  (mdc_type==MDC_SG)) {
635 
636  error=false;
637  double frequency = GetPar("frequency",par,error);
638  double Q = GetPar("Q" ,par,error);
639 
640  if(error) {
641  cout << "CWB::mdc::AddWaveform - Error : num par must be 2 [frequency,Q]" << endl;
642  exit(1);
643  }
644 
645  int d1 = decimals==-1 ? 0 : decimals;
646  int d2 = decimals==-1 ? 1 : decimals;
647 
648  if(mdc_type==MDC_SG) sprintf(wf_name, "SG%.*fQ%.*f",d1,frequency,d2,Q);
649  if(mdc_type==MDC_SGC) sprintf(wf_name,"SGC%.*fQ%.*f",d1,frequency,d2,Q);
650  if(mdc_type==MDC_SGE) sprintf(wf_name,"SGE%.*fQ%.*f",d1,frequency,d2,Q);
651 
652  wf.type = mdc_type;
653  wf.name = wf_name;
654  wf.name.ReplaceAll(".","d");
655  if(decimals==-1) wf.name.ReplaceAll("d0","");
656  if(uname!="") wf.name = uname;
657  wf.hp = GetSGQ(frequency,Q);
658  if(mdc_type==MDC_SG) { // iota = 90
659  wf.hx = wf.hp;
660  wf.hx = 0;
661  wf.hpPath = wf.name;
662  wf.hxPath = "";
663  } else { // iota = 0; for MDC_SGE iota can be customized with SetSkyDistribution
664  wf.hx = GetCGQ(frequency,Q);
665  wf.hpPath = wf.name;
666  wf.hxPath = wf.name;
667  }
668  wf.par=par;
669  return AddWaveform(wf);
670 
671  } else
672  if((mdc_type==MDC_CGC) ||
673  (mdc_type==MDC_CGE) ||
674  (mdc_type==MDC_CG)) {
675 
676  error=false;
677  double frequency = GetPar("frequency",par,error);
678  double Q = GetPar("Q" ,par,error);
679 
680  if(error) {
681  cout << "CWB::mdc::AddWaveform - Error : num par must be 2 [frequency,Q]" << endl;
682  exit(1);
683  }
684 
685  int d1 = decimals==-1 ? 0 : decimals;
686  int d2 = decimals==-1 ? 1 : decimals;
687 
688  if(mdc_type==MDC_CG) sprintf(wf_name, "CG%.*fQ%.*f",d1,frequency,d2,Q);
689  if(mdc_type==MDC_CGC) sprintf(wf_name,"CGC%.*fQ%.*f",d1,frequency,d2,Q);
690  if(mdc_type==MDC_CGE) sprintf(wf_name,"CGE%.*fQ%.*f",d1,frequency,d2,Q);
691 
692  wf.type = mdc_type;
693  wf.name = wf_name;
694  wf.name.ReplaceAll(".","d");
695  if(decimals==-1) wf.name.ReplaceAll("d0","");
696  if(uname!="") wf.name = uname;
697  wf.hp = GetCGQ(frequency,Q);
698  if(mdc_type==MDC_CG) { // iota = 90
699  wf.hx = wf.hp;
700  wf.hx = 0;
701  wf.hpPath = wf.name;
702  wf.hxPath = "";
703  } else { // iota = 0; for MDC_CGE iota can be customized with SetSkyDistribution
704  wf.hx = GetSGQ(frequency,Q);
705  wf.hpPath = wf.name;
706  wf.hxPath = wf.name;
707  }
708  wf.par=par;
709  return AddWaveform(wf);
710 
711  } else
712  if(mdc_type==MDC_WNB) {
713 
714  error=false;
715  double frequency = GetPar("frequency",par,error);
716  double bandwidth = GetPar("bandwidth",par,error);
717  double duration = GetPar("duration" ,par,error);
718 
719  if(error) {
720  cout << "CWB::mdc::AddWaveform - "
721  << "Error : WNB par must at least "
722  << "[frequency,bandwidth,duration]" << endl;
723  exit(1);
724  }
725 
726  error=false; int pseed = (int)GetPar("pseed",par,error); if(error) pseed=0;
727  error=false; int xseed = (int)GetPar("xseed",par,error); if(error) xseed=0;
728  error=false; bool mode = (bool)GetPar("mode",par,error); if(error) mode=0;
729 
730  int d1 = decimals==-1 ? 0 : decimals;
731  int d2 = decimals==-1 ? 0 : decimals;
732  int d3 = decimals==-1 ? 3 : decimals;
733 
734  sprintf(wf_name,"WNB%.*f_%.*f_%.*f",d1,frequency,d2,bandwidth,d3,duration);
735 
736  wf.type = mdc_type;
737  wf.name = wf_name;
738  wf.name.ReplaceAll(".","d");
739  if(uname!="") wf.name = uname;
740  wf.hp = GetWNB(frequency,bandwidth,duration,pseed,mode);
741  wf.hpPath = wf.name;
742  wf.hx = GetWNB(frequency,bandwidth,duration,xseed,mode);
743  wf.hxPath = wf.name;
744  wf.par=par;
745  return AddWaveform(wf);
746 
747  } else
748  if(mdc_type==MDC_GA) {
749 
750  error=false;
751  double duration = GetPar("duration" ,par,error);
752 
753  if(error) {
754  cout << "CWB::mdc::AddWaveform - "
755  << "Error : num par must at least 1 "
756  << "[duration]" << endl;
757  exit(1);
758  }
759 
760  int d1 = decimals==-1 ? 1 : decimals;
761 
762  sprintf(wf_name,"GA%.*f",d1,1000.*duration);
763 
764  wf.type = mdc_type;
765  wf.name = wf_name;
766  wf.name.ReplaceAll(".","d");
767  if(uname!="") wf.name = uname;
768  wf.hp = GetGA(duration);
769  wf.hpPath = wf.name;
770  wf.hx = wf.hp;
771  wf.hx = 0;
772  wf.hxPath = "";
773  wf.par=par;
774  return AddWaveform(wf);
775 
776  } else
777  if(mdc_type==MDC_GA_LAL) { // use LAL GA waveform
778 
779 #if LAL_VERSION_MAJOR > 6 || (LAL_VERSION_MAJOR == 6 && \
780  (LAL_VERSION_MINOR > 15 || (LAL_VERSION_MINOR == 15 && \
781  LAL_VERSION_MICRO >= 0 ))) // LAL_VERSION >= 6.15.0
782 #ifdef _USE_LAL
783  error=false;
784  double duration = GetPar("duration",par,error);
785 
786  if(error) {
787  cout << "CWB::mdc::AddWaveform - "
788  << "Error : wrong input LAL GA parameters : "
789  << "[duration,decimals(opt)]" << endl;
790  exit(1);
791  }
792 
793  // create & populate SimBurst structure
794  SimBurst *sim_burst = XLALCreateSimBurst();
795  strcpy(sim_burst->waveform, "Gaussian");
796  sim_burst->duration = duration;
797  mdcpar mpar={"normalization",1};par.push_back(mpar); // force normalization
798  waveid = AddWaveform(MDC_GA_LAL, sim_burst, par, uname);
799  XLALDestroySimBurst(sim_burst);
800  return waveid;
801 #else
802  cout << "CWB::mdc::AddWaveform - "
803  << "Error : MDC_GA_LAL is enabled only with LAL" << endl;
804  exit(1);
805 #endif
806 #else
807  cout << "CWB::mdc::AddWaveform - MDC_GA_LAL can not be used with LAL ver < 6.15.0" << endl;
808  exit(1);
809 #endif
810 
811  } else
812  if(mdc_type==MDC_SGE_LAL) { // use LAL SG waveform
813 
814 #ifdef _USE_LAL
815  error=false;
816  double frequency = GetPar("frequency",par,error);
817  double Q = GetPar("Q",par,error);
818 
819  if(error) {
820  cout << "CWB::mdc::AddWaveform - "
821  << "Error : wrong input LAL SG parameters : "
822  << "[frequency,Q,decimals(opt)]" << endl;
823  exit(1);
824  }
825 
826  // create & populate SimBurst structure
827  SimBurst *sim_burst = XLALCreateSimBurst();
828  strcpy(sim_burst->waveform, "SineGaussian");
829  sim_burst->frequency = frequency;
830  sim_burst->q = Q;
831  sim_burst->hrss = 1;
832  // force eccentricity=0 --> circularly polarized (it is a SG parameter)
833  // the ellipticity is applied elsewhere using iota
834  sim_burst->pol_ellipse_e=0.;
835  // force polarization=0 (it is a SG parameter)
836  // the polarization is applied elsewhere using psi
837  sim_burst->pol_ellipse_angle=0.;
838  mdcpar mpar={"normalization",1};par.push_back(mpar); // force normalization
839  waveid = AddWaveform(MDC_SGE_LAL, sim_burst, par, uname);
840  XLALDestroySimBurst(sim_burst);
841  return waveid;
842 #else
843  cout << "CWB::mdc::AddWaveform - "
844  << "Error : MDC_SGE_LAL is enabled only with LAL" << endl;
845  exit(1);
846 #endif
847 
848  } else
849  if(mdc_type==MDC_WNB_LAL) { // use LAL WNB waveform != from cWB WNB
850 
851 #ifdef _USE_LAL
852  error=false;
853  double frequency = GetPar("frequency",par,error);
854  double bandwidth = GetPar("bandwidth",par,error);
855  double duration = GetPar("duration" ,par,error);
856  // LAL waveform_number = hseed*10000000000+lseed
857  int lseed = (int)GetPar("lseed" ,par,error);
858  int hseed = (int)GetPar("hseed" ,par,error);
859 
860  if(error) {
861  cout << "CWB::mdc::AddWaveform - "
862  << "Error : wrong input LAL WNB parameters : "
863  << "[frequency,bandwidth,duration,lseed,hseed,decimals(opt)]" << endl;
864  exit(1);
865  }
866 
867  // create & populate SimBurst structure
868  SimBurst *sim_burst = XLALCreateSimBurst();
869  strcpy(sim_burst->waveform, "BTLWNB");
870  sim_burst->frequency = frequency;
871  sim_burst->duration = duration;
872  sim_burst->bandwidth = bandwidth;
873  sim_burst->egw_over_rsquared = 1;
874  sim_burst->waveform_number = hseed*10000000000+lseed;
875  mdcpar mpar={"normalization",1};par.push_back(mpar); // force normalization
876  waveid = AddWaveform(MDC_WNB_LAL, sim_burst, par, uname);
877  XLALDestroySimBurst(sim_burst);
878  return waveid;
879 #else
880  cout << "CWB::mdc::AddWaveform - "
881  << "Error : MDC_WNB_LAL is enabled only with LAL" << endl;
882  exit(1);
883 #endif
884 
885  } else
886  if(mdc_type==MDC_SC_LAL) { // use LAL cosmic string cusp waveform
887 
888 #if LAL_VERSION_MAJOR > 6 || (LAL_VERSION_MAJOR == 6 && \
889  (LAL_VERSION_MINOR > 15 || (LAL_VERSION_MINOR == 15 && \
890  LAL_VERSION_MICRO >= 0 ))) // LAL_VERSION >= 6.15.0
891 #ifdef _USE_LAL
892  error=false;
893  double frequency = GetPar("frequency",par,error);
894  double amplitude = GetPar("amplitude",par,error);
895 
896  if(error) {
897  cout << "CWB::mdc::AddWaveform - "
898  << "Error : wrong input LAL SC parameters : "
899  << "[frequency,amplitude,decimals(opt)]" << endl;
900  exit(1);
901  }
902 
903  // create & populate SimBurst structure
904  SimBurst *sim_burst = XLALCreateSimBurst();
905  strcpy(sim_burst->waveform, "StringCusp");
906  sim_burst->frequency = frequency;
907  if(amplitude>0) {
908  sim_burst->amplitude = amplitude;
909  } else {
910  sim_burst->amplitude = 1;
911  mdcpar mpar={"normalization",1};par.push_back(mpar); // force normalization
912  }
913  waveid = AddWaveform(MDC_SC_LAL, sim_burst, par, uname);
914  XLALDestroySimBurst(sim_burst);
915  return waveid;
916 #else
917  cout << "CWB::mdc::AddWaveform - "
918  << "Error : MDC_SC_LAL is enabled only with LAL" << endl;
919  exit(1);
920 #endif
921 #else
922  cout << "CWB::mdc::AddWaveform - MDC_SC_LAL can not be used with LAL ver < 6.15.0" << endl;
923  exit(1);
924 #endif
925 
926  } else
927  if(mdc_type==MDC_EBBH) {
928 
929 #ifdef _USE_EBBH
930 
931  if(par.size()<1) {
932  cout << "CWB::mdc::AddWaveform - "
933  << "Error : num par must at least 1 "
934  << "[file name (.lst/.root) : list of eBBH mdc]" << endl;
935  exit(1);
936  }
937 
938  TString fName = par[0].name; // get list file name of eBBH mdc
939 
940  if(fName.EndsWith(".lst")) { // read lst file
941 
942  ifstream in;
943  in.open(fName,ios::in);
944  if (!in.good()) {
945  cout << "CWB::mdc::AddWaveform - Error Opening File : " << fName << endl;
946  exit(1);
947  }
948 
949  // get number of entries
950  int entries=0;
951  char str[1024];
952  while(true) {
953  in.getline(str,1024);
954  if (!in.good()) break;
955  if(str[0] != '#') entries++;
956  }
957  cout << "entries " << entries << endl;
958  in.clear(ios::goodbit);
959  in.seekg(0, ios::beg);
960 
961  double m1,m2,rp0,e0,dist,redshift;
962  int id;
963  int fpos=0;
964  while (1) {
965  fpos=in.tellg();
966  in.getline(str,1024);
967  if(str[0] == '#') continue;
968  if (!in.good()) break;
969 
970  dist=0;
971  redshift=0;
972  std::stringstream linestream(str);
973  if(!(linestream >> id >> m1 >> m2 >> rp0 >> e0 >> dist >> redshift)) {
974  linestream.str(str);
975  linestream.clear(); // clear stringstream error status
976  if(!(linestream >> id >> m1 >> m2 >> rp0 >> e0 >> dist)) {
977  linestream.str(str);
978  linestream.clear(); // clear stringstream error status
979  if(!(linestream >> id >> m1 >> m2 >> rp0 >> e0)) {
980  cout << "CWB::mdc::AddWaveform - Wrong Format for File : " << fName << endl;
981  cout << "input line : " << endl;
982  cout << str << endl;
983  cout << "must be : " << endl;
984  cout << "event# " << "id " << " m1 " << " m2 " << " rp0 " << " e0 " << endl;
985  cout << "or : " << endl;
986  cout << "event# " << "id " << " m1 " << " m2 " << " rp0 " << " e0 " << " dist " << endl;
987  cout << "or : " << endl;
988  cout << "event# " << "id " << " m1 " << " m2 " << " rp0 " << " e0 " << " dist " << " redshift " << endl;
989  exit(1);
990  }
991  }
992  }
993 
994  wf.type = mdc_type;
995  wf.name = "eBBH";
996  wf.hpPath = "eBBH";
997  wf.hxPath = "eBBH";
998  wf.par.resize(1);
999  wf.par[0].name=str;
1000  wf.par[0].value=MDC_EBBH;
1001  waveid = AddWaveform(wf);
1002  }
1003 
1004  in.close();
1005  return waveid;
1006 
1007  } else
1008  if(fName.EndsWith(".root")) { // read root file
1009 
1010  TFile* efile = new TFile(fName);
1011  if(efile==NULL) {
1012  cout << "CWB::mdc::AddWaveform - Error opening root file : " << fName.Data() << endl;
1013  exit(1);
1014  }
1015 
1016  int id;
1017  double m1,m2,rp0,e0,dist,redshift;
1020 
1021  TTree* etree = (TTree *) efile->Get("ebbh");
1022  if(etree==NULL) {
1023  cout << "CWB::mdc::AddWaveform - file : " << fName.Data()
1024  << " not contains tree ebbh" << endl;
1025  exit(1);
1026  }
1027 
1028  etree->SetBranchAddress("id",&id);
1029  etree->SetBranchAddress("m1",&m1);
1030  etree->SetBranchAddress("m2",&m2);
1031  etree->SetBranchAddress("rp0",&rp0);
1032  etree->SetBranchAddress("e0",&e0);
1033  etree->SetBranchAddress("hp",&hp);
1034  etree->SetBranchAddress("hx",&hx);
1035  int dstatus = (etree->GetBranch("dist")==NULL) ? 0 : etree->SetBranchAddress("dist",&dist);
1036  int rstatus = (etree->GetBranch("redshift")==NULL) ? 0 : etree->SetBranchAddress("redshift",&redshift);
1037 
1038  TString ecut = "";
1039  if(par.size()==2) ecut = par[1].name; // get tree selection cut of eBBH mdc
1040  etree->Draw("Entry$",ecut,"goff");
1041  double* entry = etree->GetV1();
1042  int esize = etree->GetSelectedRows();
1043  for(int i=0;i<esize;i++) {
1044  etree->GetEntry(entry[i]);
1045  char str[256];
1046  if(rstatus) sprintf(str,"%d %f %f %f %f %f %f",id,m1,m2,rp0,e0,dist,redshift);
1047  else if(dstatus) sprintf(str,"%d %f %f %f %f %f",id,m1,m2,rp0,e0,dist);
1048  else sprintf(str,"%d %f %f %f %f",id,m1,m2,rp0,e0);
1049 
1050  //cout << id << " " << m1 << " " << m2 << " " << rp0 << " " << e0 << endl;
1051 
1052  wf.type = mdc_type;
1053  wf.name = "eBBH";
1054  wf.hpPath = "eBBH";
1055  wf.hxPath = "eBBH";
1056  wf.par.resize(2);
1057  wf.par[0].name=str;
1058  wf.par[0].value=MDC_EBBH;
1059  wf.par[1].name=fName;
1060  wf.par[1].value=entry[i];
1061  waveid = AddWaveform(wf);
1062  }
1063  delete hp;
1064  delete hx;
1065  delete efile;
1066  return waveid;
1067 
1068  } else { // eBBH values are defined in the par[0].name
1069 
1070  char str[1024];
1071  sprintf(str,par[0].name.Data());
1072  double m1,m2,rp0,e0,dist,redshift;
1073  int id;
1074  dist=0;
1075  redshift=0;
1076  std::stringstream linestream(str);
1077  if(!(linestream >> id >> m1 >> m2 >> rp0 >> e0 >> dist >> redshift)) {
1078  linestream.str(str);
1079  linestream.clear(); // clear stringstream error status
1080  if(!(linestream >> id >> m1 >> m2 >> rp0 >> e0 >> dist)) {
1081  linestream.str(str);
1082  linestream.clear(); // clear stringstream error status
1083  if(!(linestream >> id >> m1 >> m2 >> rp0 >> e0)) {
1084  cout << "CWB::mdc::AddWaveform - Wrong Input Parameter Format : " << str << endl;
1085  cout << "input line : " << endl;
1086  cout << str << endl;
1087  cout << "must be : " << endl;
1088  cout << "event# " << "id " << " m1 " << " m2 " << " rp0 " << " e0 " << endl;
1089  cout << "or : " << endl;
1090  cout << "event# " << "id " << " m1 " << " m2 " << " rp0 " << " e0 " << " dist " << endl;
1091  cout << "or : " << endl;
1092  cout << "event# " << "id " << " m1 " << " m2 " << " rp0 " << " e0 " << " dist " << " redshift " << endl;
1093  exit(1);
1094  }
1095  }
1096  }
1097 
1098  wf.type = mdc_type;
1099  wf.name = "eBBH";
1100  wf.hpPath = "eBBH";
1101  wf.hxPath = "eBBH";
1102  wf.par.resize(1);
1103  wf.par[0].name=str;
1104  wf.par[0].value=MDC_EBBH;
1105  waveid = AddWaveform(wf);
1106  }
1107 
1108 #else
1109  cout << "CWB::mdc::AddWaveform - Error : MDC_EBBH not enabled !!!" << endl;
1110  exit(1);
1111 #endif
1112 
1113  return waveid;
1114  }
1115 
1116  cout << "CWB::mdc::AddWaveform - Warning : waveform not added !!!" << endl;
1117  return waveid;
1118 }
1119 
1120 #ifdef _USE_LAL
1121 //______________________________________________________________________________
1122 mdcid
1123 CWB::mdc::AddWaveform(MDC_TYPE mdc_type, SimBurst* sim_burst, vector<mdcpar> par, TString uname) {
1124 //
1125 // Add LAL SimBurst Waveform to this object
1126 //
1127 //
1128 // Input: mdc_type - name of mdc
1129 //
1130 // MDC_SGE_LAL = LAL SinGaussian
1131 // Difference from MDC_SGE : LAL use CG instead of SG !!!
1132 // Uses eccentricity instead of ellipticity !!!
1133 //
1134 // MDC_WNB_LAL = LAL White Noise Burst
1135 // Difference from MDC_WNB : LAL has a gaussian envelope also in frequency
1136 //
1137 // MDC_GA_LAL = LAL Gaussian Burst
1138 //
1139 // MDC_SC_LAL = LAL Cosmic String Cusp
1140 //
1141 // sim_burst - The LAL SimBurst structure describes a burst injection
1142 // (see LIGOMetadataTables.h)
1143 //
1144 // par - number of decimals used to format the waveform name
1145 // if not defined ; used default format
1146 // vector<mdcpar> par(1);
1147 // par[0].name="decimals"; par[0].value=XXX;
1148 // par[1].name="normalization"; par[1].value=X; // X= 0/1 = disabled/enabled
1149 //
1150 // uname - is the name of waveform, if uname="" then uses the builtin name (default)
1151 //
1152 // Return: the name of the waveform
1153 //
1154 
1155  // check if mdc_type is in the MDC_TYPE list
1156  if(mdc_type<0 || mdc_type>=MDC_USER) {
1157  cout << "CWB::mdc::AddWaveform - Error : mdc type " << mdc_type << " not allowed !!!" << endl;
1158  exit(1);
1159  }
1160  if(sim_burst==NULL) {
1161  cout << endl << "CWB::mdc::AddWaveform - "
1162  << "Error in LAL AddWaveform : SimBurst is NULL" << endl;
1163  exit(1);
1164  }
1165 
1166  char wf_name[128];
1167  waveform wf;
1168 
1169  // get number of decimals to be used to format the waveform name
1170  bool error=false;
1171  int decimals = (int)GetPar("decimals",par,error);
1172  if(error) decimals = -1; // default format (like BurstMDC)
1173  error=false;
1174  int normalization = (int)GetPar("normalization",par,error);
1175  if(error) normalization = 0; // default : use normalization defined in sim_burst
1176 
1177  REAL8TimeSeries *hp=NULL;
1178  REAL8TimeSeries *hx=NULL;
1179 
1180  REAL8 deltaT = 1./MDC_SAMPLE_RATE;
1181 
1182  /* Get waveform from LAL : see GenerateBurst.c */
1183  int ret = XLALGenerateSimBurst(&hp, &hx, sim_burst, deltaT);
1184  if( ret==XLAL_FAILURE ) {
1185  cout << endl << "CWB::mdc::AddWaveform - "
1186  << "Error in LAL AddWaveform : check sim burst parameters" << endl;
1187  exit(1);
1188  }
1189  if(hp->data->length!=hx->data->length) {
1190  cout << "CWB::mdc::AddWaveform - Error : LAL hp,hx size not equal !!!" << endl;
1191  exit(1);
1192  }
1193 
1194  // create waveform arrays hp,hx
1195  wf.hp.resize(hp->data->length);
1196  wf.hp.rate(MDC_SAMPLE_RATE);
1197  wf.hx=wf.hp;
1198 
1199  double sum;
1200  // fill hp
1201  wf.hp=0; sum=0;
1202  for(int i=0;i<wf.hp.size();i++) {wf.hp[i]=hp->data->data[i]; sum+=pow(wf.hp[i],2);}
1203  if(normalization&&sum>0) wf.hp *= sqrt(MDC_SAMPLE_RATE/sum/2.); // normalization -> 1/sqrt(2)
1204  // fill hx
1205  wf.hx=0; sum=0;
1206  for(int i=0;i<wf.hx.size();i++) {wf.hx[i]=hx->data->data[i]; sum+=pow(wf.hx[i],2);}
1207  if(normalization&&sum>0) wf.hx *= sqrt(MDC_SAMPLE_RATE/sum/2.); // normalization -> 1/sqrt(2)
1208 
1209  XLALDestroyREAL8TimeSeries(hp);
1210  XLALDestroyREAL8TimeSeries(hx);
1211 
1212  if(mdc_type==MDC_SGE_LAL) {
1213 
1214  int d1 = decimals==-1 ? 0 : decimals;
1215  int d2 = decimals==-1 ? 1 : decimals;
1216 
1217  wf.par.resize(4);
1218  wf.par[0].name="frequency"; wf.par[0].value=sim_burst->frequency;
1219  wf.par[1].name="Q"; wf.par[1].value=sim_burst->q;
1220  wf.par[2].name="eccentricity"; wf.par[2].value=sim_burst->pol_ellipse_e;
1221  wf.par[3].name="phase"; wf.par[3].value=sim_burst->pol_ellipse_angle;
1222 
1223  sprintf(wf_name, "LAL_SGE%.*fQ%.*f",d1,wf.par[0].value,d2,wf.par[1].value);
1224 
1225  wf.type = mdc_type;
1226  wf.name = wf_name;
1227  wf.name.ReplaceAll(".","d");
1228  if(decimals==-1) wf.name.ReplaceAll("d0","");
1229  if(uname!="") wf.name = uname;
1230  wf.hpPath = wf.name;
1231  wf.hxPath = wf.name;
1232  mdcid waveid = AddWaveform(wf);
1233  return waveid;
1234 
1235  } else
1236  if(mdc_type==MDC_WNB_LAL) {
1237 
1238  int d1 = decimals==-1 ? 0 : decimals;
1239  int d2 = decimals==-1 ? 0 : decimals;
1240  int d3 = decimals==-1 ? 3 : decimals;
1241 
1242  wf.par.resize(3);
1243  wf.par[0].name="frequency"; wf.par[0].value=sim_burst->frequency;
1244  wf.par[1].name="bandwidth"; wf.par[1].value=sim_burst->bandwidth;
1245  wf.par[2].name="duration"; wf.par[2].value=sim_burst->duration;
1246 
1247  sprintf(wf_name,"LAL_WNB%.*f_%.*f_%.*f",d1,wf.par[0].value,d2,wf.par[1].value,d3,wf.par[2].value);
1248 
1249  wf.type = mdc_type;
1250  wf.name = wf_name;
1251  wf.name.ReplaceAll(".","d");
1252  if(uname!="") wf.name = uname;
1253  wf.hpPath = wf.name;
1254  wf.hxPath = wf.name;
1255  mdcid waveid = AddWaveform(wf);
1256  return waveid;
1257 
1258  } else
1259  if(mdc_type==MDC_GA_LAL) {
1260 
1261  int d1 = decimals==-1 ? 1 : decimals;
1262 
1263  wf.par.resize(1);
1264  wf.par[0].name="duration"; wf.par[0].value=sim_burst->duration;
1265 
1266  sprintf(wf_name,"LAL_GA%.*f",d1,1000.*wf.par[0].value);
1267 
1268  wf.type = mdc_type;
1269  wf.name = wf_name;
1270  wf.name.ReplaceAll(".","d");
1271  if(uname!="") wf.name = uname;
1272  wf.hpPath = wf.name;
1273  wf.hxPath = wf.name;
1274  mdcid waveid = AddWaveform(wf);
1275  return waveid;
1276  } else
1277  if(mdc_type==MDC_SC_LAL) {
1278 
1279  int d1 = decimals==-1 ? 1 : decimals;
1280 
1281  wf.par.resize(2);
1282  wf.par[0].name="frequency"; wf.par[0].value=sim_burst->frequency;
1283  wf.par[1].name="amplitude"; wf.par[1].value=sim_burst->amplitude;
1284 
1285  sprintf(wf_name,"LAL_SC%.*f",d1,wf.par[0].value);
1286 
1287  wf.hx=0; // string cup waveforms are linearly polarized
1288  wf.type = mdc_type;
1289  wf.name = wf_name;
1290  wf.name.ReplaceAll(".","d");
1291  if(uname!="") wf.name = uname;
1292  wf.hpPath = wf.name;
1293  wf.hxPath = wf.name;
1294  mdcid waveid = AddWaveform(wf);
1295  return waveid;
1296  }
1297 
1298  cout << "CWB::mdc::AddWaveform - Warning : LAL waveform not added !!!" << endl;
1299  mdcid waveid = {"",0,0};
1300  return waveid;
1301 }
1302 #endif
1303 
1304 //______________________________________________________________________________
1305 void
1307 //
1308 // Add Waveform to this object
1309 //
1310 //
1311 // Input: mdc_name - name of mdc
1312 // hp_fName - name of the input text file which contains hp component
1313 //
1314 // NOTE: the input text file is composed by two columns of ascii values (time hp/hx)
1315 //
1316 
1317  AddWaveform(mdc_name, hp_fName, "");
1318  return;
1319 }
1320 
1321 //______________________________________________________________________________
1322 void
1323 CWB::mdc::AddWaveform(TString mdc_name, TString hp_fName, TString hx_fName) {
1324 //
1325 // Add Waveform to this object
1326 //
1327 //
1328 // Input: mdc_name - name of mdc
1329 // hp_fName - name of the input text file which contains hp component
1330 // hx_fName - name of the input text file which contains hx component
1331 //
1332 // NOTE: the input text file is composed by two columns of ascii values (time hp/hx)
1333 //
1334 
1335  waveform wf;
1336  wf.type=MDC_USER;
1337  wf.name=mdc_name;
1338  ReadWaveform(wf.hp, hp_fName);
1339  wf.hpPath=hp_fName;
1340  if(hx_fName.Sizeof()>1) {
1341  ReadWaveform(wf.hx, hx_fName);
1342  wf.hxPath=hx_fName;
1343  } else {
1344  wf.hx=wf.hp; wf.hx=0;
1345  wf.hxPath="";
1346  }
1347 
1348  if(wf.hp.size()!=wf.hx.size()) {
1349  cout << "CWB::mdc::AddWaveform - Error : hp,hx size not equal !!!" << endl;
1350  exit(1);
1351  }
1352  if(wf.hp.rate()!=wf.hx.rate()) {
1353  cout << "CWB::mdc::AddWaveform - Error : hp,hx rate not equal !!!" << endl;
1354  exit(1);
1355  }
1356 
1357  // check if waveform is already declared in the wfList
1358  int ID=-1;
1359  for(int i=0;i<(int)wfList.size();i++) if(wfList[i].name.CompareTo(mdc_name)==0) {ID=i;break;}
1360 
1361  if(ID==-1) { // waveform is not in the list
1362  wfList.push_back(wf);
1363  } else {
1364  wfList[ID].list.push_back(wf);
1365  }
1366 
1367  return;
1368 }
1369 
1370 //______________________________________________________________________________
1371 void
1372 CWB::mdc::AddWaveform(TString mdc_name, TString hp_fName, double srate, vector<mdcpar> par) {
1373 //
1374 // Add Waveform to this object
1375 //
1376 //
1377 // Input: mdc_name - name of mdc
1378 // hp_fName - name of the input text file which contains hp component
1379 // srate - sample rate of the input waveform (Hz)
1380 // par - these parameters are only for infos and are stored in the waveform structure
1381 //
1382 // NOTE: the input text file s composed by a column of ascii values (hp/hx)
1383 // at constant sample rate (srate)
1384 //
1385 
1386  AddWaveform(mdc_name, hp_fName, "", srate, par);
1387  return;
1388 }
1389 
1390 //______________________________________________________________________________
1391 void
1392 CWB::mdc::AddWaveform(TString mdc_name, TString hp_fName, TString hx_fName,
1393  double srate, vector<mdcpar> par) {
1394 //
1395 // Add Waveform to this object
1396 //
1397 //
1398 // Input: mdc_name - name of mdc
1399 // hp_fName - name of the input text file which contains hp component
1400 // hx_fName - name of the input text file which contains hx component
1401 // srate - sample rate of the input waveform (Hz)
1402 // par - these parameters are only for infos and are stored in the waveform structure
1403 // only hrss is used to modify the input waveform :
1404 // - hrss<0 : wf-hrss is not modify
1405 // - hrss=0 : wf-hrss is normalized to 1 (default)
1406 // - hrss>0 : wf-hrss is normalized to hrss
1407 //
1408 // NOTE: the input text file s composed by a column of ascii values (hp/hx)
1409 // at constant sample rate (srate)
1410 //
1411 
1412  waveform wf;
1413  wf.type=MDC_USER;
1414  wf.name=mdc_name;
1415  ReadWaveform(wf.hp, hp_fName, srate);
1416  wf.hpPath=hp_fName;
1417  if(hx_fName.Sizeof()>1) {
1418  ReadWaveform(wf.hx, hx_fName, srate);
1419  wf.hxPath=hx_fName;
1420  } else {
1421  wf.hx=wf.hp; wf.hx=0;
1422  wf.hxPath="";
1423  }
1424 
1425  if(wf.hp.size()!=wf.hx.size()) {
1426  cout << "CWB::mdc::AddWaveform - Error : hp,hx size not equal !!!" << endl;
1427  exit(1);
1428  }
1429  if(wf.hp.rate()!=wf.hx.rate()) {
1430  cout << "CWB::mdc::AddWaveform - Error : hp,hx rate not equal !!!" << endl;
1431  exit(1);
1432  }
1433 
1434  // extract hrss from parameters
1435  bool error=false;
1436  double hrss_par = GetPar("hrss",par,error);
1437  if(error) hrss_par=0.;
1438 
1439  // normalization
1440  double hrssp=0; for (int i=0;i<(int)wf.hp.size();i++) hrssp+=wf.hp[i]*wf.hp[i];
1441  double hrssc=0; for (int i=0;i<(int)wf.hx.size();i++) hrssc+=wf.hx[i]*wf.hx[i];
1442  hrssp=sqrt(hrssp/wf.hp.rate());
1443  hrssc=sqrt(hrssc/wf.hx.rate());
1444  double hrss=sqrt(hrssp*hrssp+hrssc*hrssc);
1445 
1446  // if(hrss_par=0) hrss is normalized to 1
1447  if(hrss_par==0) {
1448  for(int i=0;i<(int)wf.hp.size();i++) {wf.hp[i]/=hrss;wf.hx[i]/=hrss;}
1449  hrssp /= hrss;
1450  hrssc /= hrss;
1451  hrss = 1.;
1452  }
1453  // if(hrss_par>0) hrss is normalized to hrss_par
1454  if(hrss_par>0) {
1455  for(int i=0;i<(int)wf.hp.size();i++) {wf.hp[i]/=hrss/hrss_par;wf.hx[i]/=hrss/hrss_par;}
1456  hrssp /= hrss/hrss_par;
1457  hrssc /= hrss/hrss_par;
1458  hrss = hrss_par;
1459  }
1460 
1461  // set htss,hrssp,hrssc and add par to waveform
1462  bool bhrss=false;
1463  vector<mdcpar> wfpar;
1464  for(int i=0;i<par.size();i++) {
1465  if(par[i].name=="hrss") {par[i].value=hrss;bhrss=true;}
1466  wfpar.push_back(par[i]);
1467  }
1468  mdcpar upar = {"hrss",1.,""}; if(!bhrss) wfpar.push_back(upar);
1469  mdcpar ppar = {"hrssp",hrssp,""}; wfpar.push_back(ppar);
1470  mdcpar cpar = {"hrssc",hrssc,""}; wfpar.push_back(cpar);
1471  wf.par=wfpar;
1472 
1473  // check if waveform is already declared in the wfList
1474  int ID=-1;
1475  for(int i=0;i<(int)wfList.size();i++) if(wfList[i].name.CompareTo(mdc_name)==0) {ID=i;break;}
1476 
1477  if(ID==-1) { // waveform is not in the list
1478  wfList.push_back(wf);
1479  } else {
1480  wfList[ID].list.push_back(wf);
1481  }
1482 
1483  return;
1484 }
1485 
1486 //______________________________________________________________________________
1487 mdcid
1489 //
1490 // Add Waveform to this object
1491 //
1492 //
1493 // Input: wf - waveform structure
1494 
1495  if(wf.hp.size()!=wf.hx.size()) {
1496  cout << "CWB::mdc::AddWaveform - Error : hp,hx size not equal !!!" << endl;
1497  exit(1);
1498  }
1499  if(wf.hp.rate()!=wf.hx.rate()) {
1500  cout << "CWB::mdc::AddWaveform - Error : hp,hx rate not equal !!!" << endl;
1501  exit(1);
1502  }
1503 
1504  // check if wf mdc type is in the MDC_TYPE list
1505  if(wf.type<0 || wf.type>MDC_USER) {
1506  cout << "CWB::mdc::AddWaveform - Error : mdc type not allowed !!!" << endl;
1507  exit(1);
1508  }
1509 
1510  // check if waveform is already declared in the wfList
1511  int ID=-1;
1512  for(int i=0;i<(int)wfList.size();i++) if(wfList[i].name.CompareTo(wf.name)==0) {ID=i;break;}
1513 
1514  if(ID==-1) { // waveform is not in the list
1515  wfList.push_back(wf);
1516  } else {
1517  wfList[ID].list.push_back(wf);
1518  }
1519 
1520  mdcid waveid;
1521  waveid.name = wf.name;
1522  waveid.ID = ID==-1 ? wfList.size()-1 : ID;
1523  waveid.id = ID==-1 ? 0 : wfList[ID].list.size();
1524  return waveid;
1525 }
1526 
1527 //______________________________________________________________________________
1528 TString
1530 //
1531 // Get burst/inspiral mdc data of the detector = ifo
1532 //
1533 //
1534 // Input: x - the input start/stop gps time are obtained from the wavearray values
1535 // start = x.start(); stop = x.start()+x.size()/x.rate()
1536 // ifo - name of the detector defined in the network
1537 //
1538 // Output: x - x.data contains the mdc data
1539 //
1540 // Return: log - ascii string with mdc parameters
1541 //
1542 
1543  TString listLog;
1544 #ifdef _USE_LAL
1545  if(inspOptions!="") listLog=GetInspiral(x, ifo); // new inspiral mdc
1546  else listLog=GetBurst(x, ifo); // built-in mdc
1547 #else
1548  listLog=GetBurst(x, ifo); // built-in mdc
1549 #endif
1550 
1551  return listLog;
1552 }
1553 
1554 //______________________________________________________________________________
1555 TString
1557 //
1558 // Get burst mdc data of the detector = ifo
1559 //
1560 //
1561 // Input: x - the input start/stop gps time are obtained from the wavearray values
1562 // start = x.start(); stop = x.start()+x.size()/x.rate()
1563 // ifo - name of the detector defined in the network
1564 //
1565 // Output: x - x.data contains the mdc data
1566 //
1567 // Return: log - ascii string with mdc parameters
1568 //
1569 
1570  if(net==NULL) {
1571  cout << "CWB::mdc::GetBurst - Error : Dummy method : network is not initialized " << endl;
1572  exit(1);
1573  }
1574  if(x.rate()!=MDC_SAMPLE_RATE) {
1575  cout << "CWB::mdc::GetBurst - Error : x.rate() != " << MDC_SAMPLE_RATE << endl;
1576  exit(1);
1577  }
1578 
1579  TString listLog="";
1580  double deg2rad = TMath::Pi()/180.;
1581  double rad2deg = 180./TMath::Pi();
1582 
1583  double dt = 1./x.rate();
1584 
1585  double start = x.start();
1586  double stop = x.start()+x.size()*dt;
1587 
1588  x=0.;
1589 
1590  mdcList.clear();
1591  mdcType.clear();
1592  mdcTime.clear();
1593  srcList.clear();
1594 
1595  srcList = GetSourceList(start, stop);
1596 
1597  // fill mdcType list
1599  mdcType=xmlType;
1600  } else {
1601  for(int i=0;i<(int)wfList.size();i++) {
1602  bool save=true;
1603  for(int j=0; j<(int)mdcType.size(); j++){
1604  if(wfList[i].name.CompareTo(mdcType[j])==0) {save = false; break;}
1605  }
1606  if(save) {
1607  mdcType.push_back(wfList[i].name.Data());
1608  }
1609  }
1610  }
1611 
1612  for(int k=0;k<(int)srcList.size();k++) {
1613 
1614  double gps = srcList[k].gps;
1615  double theta = srcList[k].theta;
1616  double phi = srcList[k].phi;
1617  double psi = srcList[k].psi;
1618  double rho = srcList[k].rho;
1619  double iota = srcList[k].iota;
1620  double hrss = srcList[k].hrss;
1621 
1622  //cout.precision(14);
1623  //cout << "wf : " << srcList[k].wf.name.Data() << " type :" << srcList[k].wf.type
1624  // << " gps : " << gps << " theta : " << theta << " phi : " << phi
1625  // << " psi : " << psi << " rho : " << rho << " iota : " << iota << endl;
1626 
1627  double fPlus = GetAntennaPattern(ifo, phi, theta, psi, "hp");
1628  double fCross = GetAntennaPattern(ifo, phi, theta, psi, "hx");
1629  double tShift = 0.;
1631  // Time Delay is computed respect to geocenter
1632  // this is required to be LAL compliant
1633  tShift = GetDelay(ifo,"",phi,theta);
1634  } else {
1635  // Time Delay is computed respect to the first detector in the network
1636  tShift = GetDelay(ifo,net->ifoName[0],phi,theta);
1637  }
1638 
1639  // if allowed then set ellipticity
1640  bool ellipticity=false;
1641  // if MDC_XMLFILE than hp,hx already contains the eccentricity rescaling
1642  if((srcList[k].wf.type==MDC_SGE_LAL)&&(sky_distribution!=MDC_XMLFILE)) ellipticity=true;
1643  if(srcList[k].wf.type==MDC_SGE) ellipticity=true;
1644  if(srcList[k].wf.type==MDC_CGE) ellipticity=true;
1645  if(srcList[k].wf.type==MDC_RDE) ellipticity=true;
1646  if(srcList[k].wf.type==MDC_EBBH) ellipticity=true;
1647  if(srcList[k].wf.type==MDC_USER) ellipticity=true;
1648  double ePlus = ellipticity ? (1+cos(iota*deg2rad)*cos(iota*deg2rad))/2 : 1.;
1649  double eCross = ellipticity ? cos(iota*deg2rad) : 1.;
1650  // if ellipticity=false we force iota to be 90
1651  if(!ellipticity) srcList[k].iota=90;
1652  // for circular waves we force iota to be 0
1653  if(srcList[k].wf.type==MDC_RDC) srcList[k].iota=0;
1654  if(srcList[k].wf.type==MDC_SGC) srcList[k].iota=0;
1655  if(srcList[k].wf.type==MDC_CGC) srcList[k].iota=0;
1656 
1657  waveform wf = srcList[k].wf;
1658 
1659  // build waveform vector
1660  int iShift = fabs(tShift)*wf.hp.rate();
1661  wavearray<double> w(wf.hp.size()+iShift); // add iShift to take into account time shift
1662  w.rate(wf.hp.rate());w=0;
1663  double SimHpHp=0;
1664  double SimHcHc=0;
1665  double SimHpHc=0;
1666  iShift = tShift<0 ? iShift : 0;
1667  for(int i=0;i<(int)wf.hp.size();i++) {
1668  w[i+iShift] = ePlus*fPlus*wf.hp[i]+eCross*fCross*wf.hx[i];
1669  SimHpHp+=wf.hp[i]*wf.hp[i];
1670  SimHcHc+=wf.hx[i]*wf.hx[i];
1671  SimHpHc+=wf.hp[i]*wf.hx[i];
1672  }
1673  SimHpHp*=dt;
1674  SimHcHc*=dt;
1675  SimHpHc*=dt;
1676  double SrcHrss=sqrt(SimHpHp+SimHcHc);
1677  std::stringstream linestream;
1678  int id; double m1,m2,rp0,e0,dist=0.;
1679  switch(srcList[k].wf.type) {
1680  case MDC_EBBH :
1681  // check if distance is already defined by the user
1682  linestream.str(wf.par[0].name.Data());
1683  if(!(linestream >> id >> m1 >> m2 >> rp0 >> e0 >> dist)) {
1684  // distance is not defined
1685  // for eBBH hp,hx are already scaled to 10 Kpc
1686  // add distance in Kpc to par string
1687  char pars[256];
1688  sprintf(pars,"%s %g",srcList[k].wf.par[0].name.Data(),rho);
1689  srcList[k].wf.par[0].name = pars;
1690  }
1691  break;
1692  case MDC_WNB_LAL :
1694  // for MDC_WNB_LAL the hrss is not present in the sim_table
1695  hrss=SrcHrss;
1696  srcList[k].hrss=hrss;
1697  }
1698  break;
1699  case MDC_SGE_LAL :
1701  // if MDC_XMLFILE than iota is computed from the eccentricity
1702  // (see SetSkyDistribution MDC_XMLFILE)
1703  double eccentricity = iota>1e-10 ? iota : 1e-10;
1704  // in GetBurstLog the iota is reverted to eccentricity
1705  srcList[k].iota = (1.-sqrt(1-eccentricity*eccentricity))/eccentricity;
1706  srcList[k].iota = acos(srcList[k].iota)*rad2deg;
1707  // if MDC_XMLFILE than hp,hx contain the eccentricity rescaling
1708  // SimHpHp,SimHcHc,SimHpHc must be rescaled according to the eccentricity
1709 /*
1710  double ePlus = (1+cos(iota*deg2rad)*cos(iota*deg2rad))/2;
1711  double eCross = cos(iota*deg2rad);
1712  SimHpHp *= 1./(ePlus*ePlus);
1713  SimHcHc *= fabs(eCross)>1e-5 ? 1./(eCross*eCross) : 0.;
1714  SimHpHc *= fabs(eCross)>1e-5 ? 1./(ePlus*eCross) : 0.;
1715 */
1716  //double eccentricity = cosi2e(cos(iota*deg2rad));
1717  double E = eccentricity;
1718  double A = 1./sqrt(2-E*E);
1719  double B = A*sqrt(1-E*E);
1720  SimHpHp *= 1./(A*A)/2.;
1721  SimHcHc *= fabs(B)>1e-5 ? 1./(B*B)/2. : 0.;
1722  SimHpHc *= fabs(B)>1e-5 ? 1./(A*B)/2. : 0.;
1723  if(SimHcHc==0) SimHcHc=SimHpHp;
1724 
1725  //cout << "A " << A << " B " << B << " E " << E << endl;
1726  //cout << "SimHpHp : " << SimHpHp << " " << " SimHcHc " << SimHcHc << " SimHpHc " << SimHpHc << endl;
1727  //cout << "hrss : " << hrss << " " << " sqrt(SimHpHp+SimHcHc) " << sqrt(SimHpHp+SimHcHc) << endl;
1728  }
1729  break;
1730  default :
1731  if(inj_hrss>0) {
1732  // scaled source to hrss (variable for each source) or inj_hrss (fixed for all source) : @ 10Kpc
1733  SimHpHp *= hrss>0 ? pow(hrss/SrcHrss,2) : pow(inj_hrss/SrcHrss,2);
1734  SimHcHc *= hrss>0 ? pow(hrss/SrcHrss,2) : pow(inj_hrss/SrcHrss,2);
1735  SimHpHc *= hrss>0 ? pow(hrss/SrcHrss,2) : pow(inj_hrss/SrcHrss,2);
1736  w *= hrss>0 ? hrss/SrcHrss : inj_hrss/SrcHrss;
1737  } else {
1738  // the hrss @ 10Kpc is the one which is defined by hp,hc waveforms
1739  srcList[k].hrss = SrcHrss;
1740  }
1741  }
1742  // scale amplitude with the inverse of distance (standard candle @ 10Kpc)
1743  if(rho>0) {
1744  SimHpHp*=100./pow(rho,2);
1745  SimHcHc*=100./pow(rho,2);
1746  SimHpHc*=100./pow(rho,2);
1747  w*=10./rho;
1748  }
1749 
1750  TimeShift(w, tShift);
1751 
1752  // compute the number of samples (sT) of the mdc central time T
1753  double T = GetCentralTime(wf);
1754  int sT = TMath::Nint(T*w.rate());
1755 
1756  // offset (oS) of inj time respect to beginning of array
1757  // iShift must be subtracted !!!
1758  int oS = (srcList[k].gps-start)*x.rate()-iShift;
1759 
1760  // add waveform to mdc vector : T @ gps time
1761  for(int i=0;i<(int)w.size();i++) {
1762  int j=i+oS-sT;
1763  if (j>=(int)x.size()) break;
1764  if (j>=0) x[j]=w[i];
1765  }
1766 
1767  // add waveform log string to mdc log string
1768  TString log = GetBurstLog(srcList[k], start, SimHpHp, SimHcHc, SimHpHc);
1769  listLog = listLog+log;
1770 
1771  // add infos to lists
1772  mdcList.push_back(log.Data());
1773 // mdcType.push_back(srcList[k].wf.name.Data());
1774  mdcTime.push_back(srcList[k].gps);
1775 /*
1776  bool save=true;
1777  for(int j=0; j<(int)mdcType.size(); j++){
1778  if(srcList[k].wf.name.CompareTo(mdcType[j])==0) {save = false; break;}
1779  }
1780  if(save) {
1781  mdcType.push_back(srcList[k].wf.name.Data());
1782  }
1783 */
1784  }
1785 
1786  return listLog;
1787 }
1788 
1789 //______________________________________________________________________________
1790 void
1792 //
1793 // Read Waveform from input ascii file
1794 //
1795 //
1796 // Input: fName - name of the input text file which contains hp component
1797 //
1798 // Output: x - wavearray x.data contains waveform data
1799 //
1800 // NOTE: the input text file is composed by two columns of ascii values
1801 //
1802 
1803  Long_t id,fsize,flags,mt;
1804  int estat = gSystem->GetPathInfo(fName.Data(),&id,&fsize,&flags,&mt);
1805  if (estat!=0) {
1806  cout << "CWB::mdc::ReadWaveform - File : " << fName.Data() << " Not Exist" << endl;
1807  exit(1);
1808  }
1809 
1810  // read Waveform
1811  ifstream in;
1812  in.open(fName.Data(),ios::in);
1813  if (!in.good()) {cout << "CWB::mdc::ReadWaveform - Error Opening File : " << fName.Data() << endl;exit(1);}
1814 
1815  int size=0;
1816  char* str = new char[fsize+1];
1817  TObjArray* tok;
1818  while(true) {
1819  in.getline(str,fsize+1);
1820  if (!in.good()) break;
1821  if(str[0] != '#') size++;
1822  else continue;
1823  tok = TString(str).Tokenize(TString(' '));
1824  if(tok->GetEntries()!=2) {
1825  cout << "CWB::mdc::ReadWaveform - Input file with bad format : must be 2 columns " << endl;
1826  exit(1);
1827  }
1828  delete tok;
1829  }
1830  in.clear(ios::goodbit);
1831  in.seekg(0, ios::beg);
1832 
1834  w.resize(size);
1836 
1837  int cnt=0;
1838  double tMin=1.e30;
1839  double tMax=0.;
1840  while (1) {
1841  int fpos = in.tellg();
1842  in.getline(str,1024);
1843  if (!in.good()) break;
1844  if(str[0] != '#') {
1845  in.seekg(fpos, ios::beg);
1846  in >> t.data[cnt] >> w.data[cnt];
1847  if (!in.good()) break;
1848  if(t[cnt]<tMin) tMin=t[cnt];
1849  if(t[cnt]>tMax) tMax=t[cnt];
1850  cnt++;
1851  fpos=in.tellg();
1852  in.seekg(fpos+1, ios::beg);
1853  }
1854  }
1855  in.close();
1856  delete [] str;
1857 
1858  // convert to rate MDC_SAMPLE_RATE
1859 
1860  x.rate(MDC_SAMPLE_RATE);
1861  x.start(0.);
1862  int offset = 0.05*x.rate();
1863  x.resize(offset+int(x.rate()*(tMax-tMin)));
1864  x=0.;
1865 
1866  double dt=1./x.rate();
1868  for (int i=0;i<(int)r.size();i++) r[i] = tMin+(i-offset)*dt;
1869 
1870  CWB::Toolbox::convertSampleRate(t, w, r, x);
1871 
1872  return;
1873 }
1874 
1875 //______________________________________________________________________________
1876 void
1878 //
1879 // Read Waveform from input ascii file
1880 //
1881 //
1882 // Input: fName - name of the input text file which contains hp component
1883 // srate - sample rate of the input waveform (Hz)
1884 //
1885 // Output: x - wavearray x.data contains waveform data
1886 //
1887 // NOTE: the input text file s composed by a column of ascii values
1888 // at constant sample rate (srate)
1889 //
1890 
1891  Long_t id,fsize,flags,mt;
1892  int estat = gSystem->GetPathInfo(fName.Data(),&id,&fsize,&flags,&mt);
1893  if (estat!=0) {
1894  cout << "CWB::mdc::ReadWaveform - File : " << fName.Data() << " Not Exist" << endl;
1895  exit(1);
1896  }
1897 
1898  // read Waveform
1899  ifstream in;
1900  in.open(fName.Data(),ios::in);
1901  if (!in.good()) {cout << "CWB::mdc::ReadWaveform - Error Opening File : " << fName.Data() << endl;exit(1);}
1902 
1903  int size=0;
1904  char* str = new char[fsize+1];
1905  TObjArray* tok;
1906  while(true) {
1907  in.getline(str,fsize+1);
1908  if (!in.good()) break;
1909  if(str[0] != '#') size++;
1910  tok = TString(str).Tokenize(TString(' '));
1911  if((tok->GetEntries()!=1)&&(size>1)) {
1912  cout << "CWB::mdc::ReadWaveform - Input file with bad format : must be 1 column " << endl;
1913  exit(1);
1914  }
1915  if((tok->GetEntries()>1)&&(size==1)) { // all data are in one line
1916  x.resize(tok->GetEntries());
1917  x.rate(srate);
1918  for(int i=0;i<x.size();i++) { // get data from line
1919  TString stok = ((TObjString*)tok->At(i))->GetString();
1920  x[i]=stok.Atof(); // fill array
1921  }
1922  size=0;break;
1923  }
1924  delete tok;
1925  }
1926  in.clear(ios::goodbit);
1927  in.seekg(0, ios::beg);
1928 
1929  if(size>0) { // data are written with 1 column format
1930  x.resize(size);
1931  x.rate(srate);
1932 
1933  int cnt=0;
1934  while (1) {
1935  in.getline(str,1024);
1936  if (!in.good()) break;
1937  if(str[0] != '#') {
1938  x[cnt]=TString(str).Atof();
1939  cnt++;
1940  }
1941  }
1942  }
1943  in.close();
1944 
1945  // resample data if is not equals to the default
1946  if(srate!=MDC_SAMPLE_RATE) {
1949  y*=x.rms()/y.rms(); // set y energy = x energy
1950  x=y;
1951  }
1952 
1953  delete [] str;
1954 
1955  return;
1956 }
1957 
1958 //______________________________________________________________________________
1959 void
1960 CWB::mdc::GetSourceCoordinates(double gps, double& theta, double& phi, double& psi, double& rho,
1961  double& iota, double& hrss, int& ID, int& id) {
1962 //
1963 // Get source coordinates (earth system) from the user defined sky distribution
1964 //
1965 //
1966 // Output: gps - time (sec)
1967 // theta - latitude (degrees)
1968 // phi - longitude (degrees)
1969 // psi - polarization (degrees)
1970 // rho - distance (KPc)
1971 // iota - elliptical inclination angle (degrees)
1972 // hrss - sqrt(hp^2+hx^2)
1973 //
1974 
1975  GetSourceCoordinates(theta, phi, psi, rho, iota, hrss, ID, id);
1976 
1977  if((sky_distribution==MDC_GWGC)||
1980 
1981  if(gps>0) phi=sm.RA2phi(phi,gps); // celestial 2 earth coordinates
1982  }
1983 
1984  return;
1985 }
1986 
1987 //______________________________________________________________________________
1988 void
1989 CWB::mdc::GetSourceCoordinates(double& theta, double& phi, double& psi, double& rho,
1990  double& iota, double& hrss, int& ID, int& id) {
1991 //
1992 // Get source coordinates (earth system) from the user defined sky distribution
1993 //
1994 //
1995 // Output: theta - latitude (degrees)
1996 // phi - longitude (degrees)
1997 // psi - polarization (degrees)
1998 // rho - distance (KPc)
1999 // iota - elliptical inclination angle (degrees)
2000 // hrss - sqrt(hp^2+hx^2)
2001 //
2002 
2003  if((sky_distribution==MDC_GWGC)||
2008 
2009  if(thList.size()==0) {
2010  cout << "CWB::mdc::GetSourceCoordinates - Error : injections not defined !!!" << endl;
2011  exit(1);
2012  }
2013 
2014  int id = gRandom->Uniform(0,thList.size());
2015 
2016  theta = thList[id];
2017  phi = phList[id];
2018  psi = psiList[id];
2019  rho = rhoList[id];
2020  iota = iotaList[id];
2021  hrss = hrssList[id];
2022  ID = IDList[id];
2023  id = idList[id];
2024 
2025  GeographicToCwb(phi,theta,phi,theta);
2026 
2027  } else {
2028 
2029  if(inj==NULL) {
2030  cout << "CWB::mdc::GetSourceCoordinates - Error : distribution not defined !!!" << endl;
2031  exit(1);
2032  }
2033  }
2034 
2035  return;
2036 }
2037 
2038 //______________________________________________________________________________
2039 waveform
2041 //
2042 // Return waveform randomly selected from the input list
2043 //
2044 
2045  ID = (int)gRandom->Uniform(0,wfList.size());
2046  id = (int)gRandom->Uniform(0,1+wfList[ID].list.size());
2047 
2048  waveform wf = id==0 ? wfList[ID] : wfList[ID].list[id-1];
2049  GetWaveform(wf); // if hp,hx are empty -> fill waveforms
2050  return wf;
2051 }
2052 
2053 //______________________________________________________________________________
2054 vector<source>
2056 //
2057 // Get a list of waveforms in the interval [start, stop]
2058 //
2059 //
2060 // Input: start - start time
2061 // stop - stop time
2062 //
2063 // Return the source list
2064 //
2065 
2066  if((stop-start)<=2*inj_length) {
2067  cout << "CWB::mdc::GetSourceList - Warning : buffer too small (stop-start)<=2*inj_length !!!" << endl;
2068  exit(1);
2069  }
2070 
2071  // fix random choice setting seed=start+srcList_seed
2072  gRandom->SetSeed(int(start)+srcList_seed);
2073 
2074  source src;
2075 
2076  double timeStep = inj_rate>0 ? 1./inj_rate : 1./MDC_INJ_RATE;
2077 
2078  int iStart=int(0.5+start/timeStep);
2079  int iStop=int(stop/timeStep);
2080 
2081  if(iStart==0) iStart+=1;
2082  vector<source> src_list;
2083 
2085 
2086  if(inj_tree==NULL) {
2087  cout << "CWB::mdc::GetSourceList - Error : injection object is NULL" << endl;
2088  exit(1);
2089  }
2090 
2091  // gps are valid if are inside the range [start+inj_length, stop-inj_length]
2092  // inj_length is the scratch
2093  char cut[128];sprintf(cut,"time[0]>=%f && time[0]<%f",start+inj_length,stop-inj_length);
2094  inj_tree->Draw("Entry$",cut,"goff");
2095  int entries = inj_tree->GetSelectedRows();
2096  float phi[4];
2097  float theta[4];
2098  float psi[2];
2099  double time[2*NIFO_MAX];
2100  int type[2];
2101 
2102  inj_tree->SetBranchAddress("phi",phi);
2103  inj_tree->SetBranchAddress("theta",theta);
2104  inj_tree->SetBranchAddress("psi",psi);
2105  inj_tree->SetBranchAddress("time",time);
2106  inj_tree->SetBranchAddress("type",type);
2107 
2108  double* entry = inj_tree->GetV1();
2109  for(int i=0;i<entries;i++) {
2110  inj_tree->GetEntry(entry[i]);
2111  src.theta = theta[0];
2112  src.phi = phi[0];
2113  src.psi = psi[0];
2114  src.gps = time[0];
2115  src.rho = 10.;
2116  src.iota = 0.;
2117  src.hrss = 0.;
2118  int TYPE = (type[0]-1)<mdcName.size() ? type[0]-1 : 0;
2119  int ID = GetWaveformID(mdcName[TYPE])!=-1 ? GetWaveformID(mdcName[TYPE]) : 0;
2120  int id = (int)gRandom->Uniform(0,1+wfList[ID].list.size());
2121  src.wf = GetWaveform(ID,id);
2122  src_list.push_back(src);
2123  }
2125  for(int i=0;i<(int)gpsList.size();i++) {
2126  // gps are valid if are inside the range [start+inj_length, stop-inj_length]
2127  // inj_length is the scratch
2128  src.gps = gpsList[i];
2129  if(src.gps<=start+inj_length) continue;
2130  if(src.gps>=stop-inj_length) continue;
2131  src.theta = thList[i];
2132  src.phi = phList[i];
2133  src.psi = psiList[i];
2134  src.rho = rhoList[i];
2135  src.iota = iotaList[i];
2136  src.hrss = hrssList[i];
2137  src.ID = IDList[i];
2138  src.id = idList[i];
2139  if(src.ID<0) { // select waveform by name (default)
2140  src.ID = GetWaveformID(nameList[i])!=-1 ? GetWaveformID(nameList[i]) : 0;
2141  } else { // select waveform by ID,id
2142  src.ID = (src.ID < wfList.size()) ? src.ID : 0;
2143  }
2144  if(src.id<0) { // select waveform by name (default)
2145  src.id = (int)gRandom->Uniform(0,1+wfList[src.ID].list.size());
2146  } else { // select waveform by ID,id
2147  src.id = (src.id <= wfList[src.ID].list.size()) ? src.id : 0;
2148  }
2149  src.wf = GetWaveform(src.ID,src.id);
2150  src_list.push_back(src);
2151  }
2152  } else {
2153  for(int i=iStart;i<=iStop;i++) {
2154  if(gpsList.size()>0) src.gps=gpsList[0]; // fix gps
2155  else src.gps=inj_offset+i*timeStep+gRandom->Uniform(-inj_jitter,inj_jitter);
2156  // gps are valid if are inside the range [start+inj_length, stop-inj_length]
2157  // inj_length is the scratch
2158  if(src.gps<=start+inj_length) continue;
2159  if(src.gps>=stop-inj_length) continue;
2160  GetSourceCoordinates(src.gps, src.theta, src.phi, src.psi, src.rho, src.iota, src.hrss, src.ID, src.id);
2161  src.wf = GetSourceWaveform(src.ID, src.id);
2162 
2163  if(src.wf.par.size() && src.wf.par[0].value==MDC_EBBH) { // eBBH waveform
2164  int id; double m1,m2,rp0,e0,dist=0.;
2165  std::stringstream linestream(src.wf.par[0].name.Data());
2166  // get user defined distance
2167  if((linestream >> id >> m1 >> m2 >> rp0 >> e0 >> dist)) src.rho=dist;
2168  }
2169 
2170  src_list.push_back(src);
2171  if(gpsList.size()>0) break; // fix gps, only one injection
2172  }
2173  }
2174 
2175  return src_list;
2176 }
2177 
2178 //______________________________________________________________________________
2179 TString
2180 CWB::mdc::GetBurstLog(source src, double FrameGPS, double SimHpHp, double SimHcHc, double SimHpHc) {
2181 //
2182 // Get Log string
2183 //
2184 // Input: src - source structure
2185 // FrameGPS - Frame gps time
2186 // SimHpHp - Energy of hp component
2187 // SimHcHc - Energy of hc component
2188 // SimHpHc - Cross component of hp hc
2189 //
2190 
2191  if(net==NULL) {
2192  cout << "CWB::mdc::GetBurstLog - Error : Dummy method : network is not initialized " << endl;
2193  exit(1);
2194  }
2195 
2196  double deg2rad = TMath::Pi()/180.;
2197 
2198  // log burstMDC parameters
2199  char logString[10000]="";
2200 
2201  char GravEn_SimID[1024];
2202  double hrss = src.hrss>0 ? src.hrss : inj_hrss;
2203  TString hpPath = src.wf.hpPath.Sizeof()>1 ? src.wf.hpPath : src.wf.name;
2204  sprintf(GravEn_SimID,"%s",hpPath.Data());
2205  if(src.wf.hxPath.Sizeof()>1) sprintf(GravEn_SimID,"%s;%s",GravEn_SimID,src.wf.hxPath.Data());
2206  // scale amplitude with the inverse of distance (standard candle @ 10Kpc)
2207  //double SimHrss = src.rho>0 ? 10.*sqrt(SimHpHp+SimHcHc)/src.rho : sqrt(SimHpHp+SimHcHc);
2208  double SimHrss = sqrt(SimHpHp+SimHcHc);
2209  double SimEgwR2 = 0.0;
2210  double GravEn_Ampl = src.rho>0 ? 10.*hrss/src.rho : hrss;
2211  double Internal_x = cos(src.iota*deg2rad);
2212  double Internal_phi = 0.0;
2213  double External_x = cos(src.theta*deg2rad); // DOM
2214  double External_phi = src.phi*deg2rad;
2215  double External_psi = src.psi*deg2rad;
2216 
2217  double EarthCtrGPS = src.gps;
2218  char SimName[64]; strcpy(SimName,src.wf.name.Data());
2219 
2220  sprintf(logString,"%s",GravEn_SimID);
2221  sprintf(logString,"%s %e",logString,SimHrss);
2222  sprintf(logString,"%s %e",logString,SimEgwR2);
2223  sprintf(logString,"%s %e",logString,GravEn_Ampl);
2224  sprintf(logString,"%s %e",logString,Internal_x);
2225  sprintf(logString,"%s %e",logString,Internal_phi);
2226  sprintf(logString,"%s %e",logString,External_x);
2227  sprintf(logString,"%s %e",logString,External_phi);
2228  sprintf(logString,"%s %e",logString,External_psi);
2229 
2230  sprintf(logString,"%s %10.6f",logString,FrameGPS);
2231  sprintf(logString,"%s %10.6f",logString,EarthCtrGPS);
2232  sprintf(logString,"%s %s",logString,SimName);
2233  sprintf(logString,"%s %e",logString,SimHpHp);
2234  sprintf(logString,"%s %e",logString,SimHcHc);
2235  sprintf(logString,"%s %e",logString,SimHpHc);
2236 
2237  int nIFO=net->ifoListSize();
2238  TString refIFO=net->ifoName[0];
2239  for(int i=0;i<nIFO;i++) {
2240  TString ifo=net->ifoName[i];
2241  double IFOctrGPS = EarthCtrGPS;
2243  // Time Delay is computed respect to geocenter
2244  // this is required to be LAL compliant
2245  IFOctrGPS += GetDelay(ifo,"",src.phi,src.theta);
2246  } else {
2247  // Time Delay is computed respect to the first detector in the network
2248  IFOctrGPS += GetDelay(ifo,refIFO,src.phi,src.theta);
2249  }
2250  double IFOfPlus = GetAntennaPattern(ifo, src.phi, src.theta, src.psi, "hp");
2251  double IFOfCross = GetAntennaPattern(ifo, src.phi, src.theta, src.psi, "hx");
2252  if(src.wf.name=="eBBH") { // if MDC is eBBH add auxiliary infos
2253  int id; double m1,m2,rp0,e0,distance=0.;
2254  std::stringstream linestream(src.wf.par[0].name.Data());
2255  linestream >> id >> m1 >> m2 >> rp0 >> e0 >> distance;
2256  // compute effective distance
2257  double cosiota = cos(src.iota*deg2rad);
2258  double eff_dist = distance / sqrt(pow(IFOfPlus*(1.+pow(cosiota,2)),2)/4.+pow(IFOfCross*cosiota,2));
2259  sprintf(logString,"%s %s %10.6f %e %e %g",logString,ifo.Data(),IFOctrGPS,IFOfPlus,IFOfCross,eff_dist/1000.);
2260  } else {
2261  sprintf(logString,"%s %s %10.6f %e %e",logString,ifo.Data(),IFOctrGPS,IFOfPlus,IFOfCross);
2262  }
2263  }
2264 
2265  if(src.wf.name=="eBBH") { // if MDC is eBBH add auxiliary infos
2266  int id; double m1,m2,rp0,e0,distance=0.,redshift=0.;
2267  std::stringstream linestream(src.wf.par[0].name.Data());
2268  linestream >> id >> m1 >> m2 >> rp0 >> e0 >> distance >> redshift;
2269  sprintf(logString, "%s ebbh ",logString);
2270  sprintf(logString, "%s mass1 %g ",logString, m1);
2271  sprintf(logString, "%s mass2 %g ",logString, m2);
2272  sprintf(logString, "%s rp0 %g ",logString, rp0);
2273  sprintf(logString, "%s e0 %g ",logString, e0);
2274  sprintf(logString, "%s distance %g ",logString, distance/1000.); // converted in Mpc (compatible with LAL)
2275  sprintf(logString, "%s redshift %g ",logString, redshift);
2276  // chirp mass (solar units)
2277  double M = (m1+m2);
2278  double mu = (m1*m2)/(m1+m2);
2279  double eta = mu/M;
2280  double mchirp = pow(mu,3./5)*pow(M,2./5);
2281  sprintf(logString, "%s mchirp %g ",logString, mchirp);
2282  } else {
2283  // distance is converted in Mpc (compatible with LAL)
2284  if(src.rho>0) sprintf(logString, "%s distance %g ",logString, src.rho/1000.);
2285  }
2286 
2287  return logString;
2288 }
2289 
2290 //______________________________________________________________________________
2291 watplot*
2292 CWB::mdc::Draw(int ID, int id, TString polarization, MDC_DRAW type, TString options, Color_t color) {
2293 //
2294 // Draw waveform in time/frequency domain
2295 //
2296 //
2297 // Input: ID - major id of waveform list
2298 // id - minor id of waveform list (Ex : the list WNB with different random waveforms)
2299 // polarization - hp/hx
2300 // type - MDC_TIME, MDC_FFT, MDC_TF
2301 // options - graphic options
2302 // color - option for MDC_TIME, MDC_FFT
2303 //
2304 
2305  watplot* plot=NULL;
2306  polarization.ToUpper();
2307  waveform wf = GetWaveform(ID,id);
2308  if(wf.status) {
2309  if(polarization.Contains("HP")) plot=Draw(wf.hp,type,options,color);
2310  if(polarization.Contains("HX")) plot=Draw(wf.hx,type,options,color);
2311  }
2312  return plot;
2313 }
2314 
2315 //______________________________________________________________________________
2316 watplot*
2318 //
2319 // Draw waveform in time/frequency domain
2320 //
2321 //
2322 // Input: name - waveform name
2323 // polarization - hp/hx
2324 // type - MDC_TIME, MDC_FFT, MDC_TF
2325 // options - graphic options
2326 // color - option for MDC_TIME, MDC_FFT
2327 //
2328 
2329  watplot* plot=NULL;
2330  polarization.ToUpper();
2331  waveform wf = GetWaveform(name,id);
2332  if(wf.status) {
2333  if(polarization.Contains("HP")) plot=Draw(wf.hp,type,options,color);
2334  if(polarization.Contains("HX")) plot=Draw(wf.hx,type,options,color);
2335  }
2336  return plot;
2337 }
2338 
2339 //______________________________________________________________________________
2340 watplot*
2341 CWB::mdc::Draw(TString ifo, double gpsStart, double gpsEnd, int id,
2342  MDC_DRAW type, TString options, Color_t color) {
2343 //
2344 // Draw waveform in time/frequency domain contained in the interval [gpsStart,gpsEnd]
2345 //
2346 //
2347 // Input: ifo - detector name
2348 // gpsStart - start interval time
2349 // gpsEnd - stop interval time
2350 // id - sequential numer of the waveform contained in the interval
2351 // type - MDC_TIME, MDC_FFT, MDC_TF
2352 // options - graphic options
2353 // color - option for MDC_TIME, MDC_FFT
2354 //
2355 
2357  y.rate(MDC_SAMPLE_RATE);
2358  y.start(gpsStart);
2359  y.resize((gpsEnd-gpsStart)*y.rate());
2360  Get(y,ifo);
2361 
2362  if((int)mdcTime.size()==0) {
2363  cout << "CWB::mdc::Draw : Error - No events in the selected period" << endl;
2364  exit(1);
2365  }
2366  if(id>=(int)mdcTime.size()) id=(int)mdcTime.size()-1;
2367  double tOffset = mdcTime[id]-y.start();
2368  double tWindow = inj_length;
2369  int iStart = (tOffset-tWindow/2)*y.rate(); if(iStart<0) iStart=0;
2370  int iEnd = (tOffset+tWindow/2)*y.rate(); if(iEnd>y.size()) iEnd=y.size();
2371 
2372  // make an array centered around the selected event
2373  wavearray<double> x(tWindow*y.rate());
2374  x.rate(y.rate());
2375  for(int i=iStart;i<iEnd;i++) x[i-iStart]=y[i];
2376 
2377  watplot* plot=NULL;
2378 
2379  if(type==MDC_TIME) plot=DrawTime(x,options,color);
2380  if(type==MDC_FFT) plot=DrawFFT(x,options,color);
2381  if(type==MDC_TF) DrawTF(x);
2382 
2383  return plot;
2384 }
2385 
2386 //______________________________________________________________________________
2387 watplot*
2389 //
2390 // Draw waveform in time/frequency domain
2391 //
2392 //
2393 // Input: x - wavearray which contains waveform data
2394 // type - MDC_TIME, MDC_FFT, MDC_TF
2395 // options - graphic options
2396 // color - option for MDC_TIME, MDC_FFT
2397 //
2398 
2399  watplot* plot=NULL;
2400 
2401  if(type==MDC_TIME) plot=DrawTime(x,options,color);
2402  if(type==MDC_FFT) plot=DrawFFT(x,options,color);
2403  if(type==MDC_TF) DrawTF(x,options);
2404 
2405  return plot;
2406 }
2407 
2408 //______________________________________________________________________________
2409 watplot*
2411 //
2412 // Draw waveform in time domain
2413 //
2414 //
2415 // Input: x - wavearray which contains waveform data
2416 // options - draw options (same as TGraph)
2417 // if contains ZOOM then the interval around the signal is showed
2418 //
2419 
2420  if(x.rate()<=0) {
2421  cout << "CWB::mdc::DrawTime : Error - rate must be >0" << endl;
2422  exit(1);
2423  }
2424 
2425  options.ToUpper();
2426  options.ReplaceAll(" ","");
2427  if(stft!=NULL) delete stft;
2428  if(options.Contains("SAME")&&(pts!=NULL)) {
2429  } else {
2430  if(pts!=NULL) delete pts;
2431  char name[32];sprintf(name,"TIME-gID:%d",int(gRandom->Rndm(13)*1.e9));
2432  pts = new watplot(const_cast<char*>(name),200,20,800,500);
2433  }
2434  double tStart,tStop;
2435  if(options.Contains("ZOOM")) {
2436  options.ReplaceAll("ZOOM","");
2437  GetTimeRange(x, tStart, tStop, epzoom);
2438  tStart+=x.start();
2439  tStop+=x.start();
2440  } else {
2441  tStart=x.start();
2442  tStop=x.start()+x.size()/x.rate();
2443  }
2444  if(!options.Contains("SAME")) {
2445  if(!options.Contains("A")) options=options+" A";
2446  if(!options.Contains("L")) options=options+" L";
2447  if(!options.Contains("P")) options=options+" P";
2448  }
2449  pts->plot(x, const_cast<char*>(options.Data()), color, tStart, tStop);
2450 
2451  return pts;
2452 }
2453 
2454 //______________________________________________________________________________
2455 watplot*
2457 //
2458 // Draw waveform spectrum
2459 //
2460 //
2461 // Input: x - wavearray which contains waveform data
2462 // options - draw options (same as TGraph)
2463 // if contains ZOOM then the interval around the signal is showed
2464 // if contains NOLOGX/NOLOGY X/Y axis are linear
2465 //
2466 
2467  options.ToUpper();
2468  options.ReplaceAll(" ","");
2469  if(stft!=NULL) delete stft;
2470  if(options.Contains("SAME")&&(pts!=NULL)) {
2471  } else {
2472  if(pts!=NULL) delete pts;
2473  char name[32];sprintf(name,"FREQ-gID:%d",int(gRandom->Rndm(13)*1.e9));
2474  pts = new watplot(const_cast<char*>(name),200,20,800,500);
2475  }
2476 
2477  double fLow = 32.;
2478  double fHigh = x.rate()/2.;
2479  double tStart,tStop;
2480  if(options.Contains("ZOOM")) {
2481  options.ReplaceAll("ZOOM","");
2482  GetTimeRange(x, tStart, tStop, epzoom);
2483  tStart+=x.start();
2484  tStop+=x.start();
2485  } else {
2486  tStart=x.start();
2487  tStop=x.start()+x.size()/x.rate();
2488  }
2489  bool logx = true;
2490  if(options.Contains("NOLOGX")) {logx=false;options.ReplaceAll("NOLOGX","");}
2491  bool logy = true;
2492  if(options.Contains("NOLOGY")) {logy=false;options.ReplaceAll("NOLOGY","");}
2493  pts->plot(x, const_cast<char*>(options.Data()), color, tStart, tStop, true, fLow, fHigh);
2494  pts->canvas->SetLogx(logx);
2495  pts->canvas->SetLogy(logy);
2496 
2497  return pts;
2498 }
2499 
2500 //______________________________________________________________________________
2501 void
2503 //
2504 // Draw waveform spectrogram
2505 //
2506 //
2507 // Input: x - wavearray which contains waveform data
2508 // options - draw options (same as TH2D)
2509 //
2510 
2511  int nfact=4;
2512  int nfft=nfact*512;
2513  int noverlap=nfft-10;
2514  double fparm=nfact*6;
2515 
2516  double tStart,tStop;
2517  if(options.Contains("ZOOM")) {
2518  options.ReplaceAll("ZOOM","");
2519  GetTimeRange(x, tStart, tStop, epzoom);
2520  tStart+=x.start();
2521  tStop+=x.start();
2522  } else {
2523  tStart=x.start();
2524  tStop=x.start()+x.size()/x.rate();
2525  }
2526 
2527  if(stft!=NULL) delete stft;
2528  if(pts!=NULL) delete pts;
2529  stft = new CWB::STFT(x,nfft,noverlap,"amplitude","gauss",fparm);
2530 
2531  double fLow = 32.;
2532  double fHigh = x.rate()/2.;
2533  stft->Draw(tStart,tStop,fLow,fHigh,0,0,1);
2534  stft->GetCanvas()->SetLogy(true);
2535 
2536  return;
2537 }
2538 
2539 //______________________________________________________________________________
2540 waveform
2542 //
2543 // Get waveform
2544 //
2545 //
2546 // Input: ID - major id of waveform list
2547 // id - minor id of waveform list (Ex : the list WNB with different random waveforms)
2548 //
2549 // Return waveform structure
2550 //
2551 
2552  waveform wf;
2553 
2554  // check if waveform is declared in the wfList
2555  if(ID<0||ID>=(int)wfList.size()) {
2556  cout << "CWB::mdc::GetWaveform - Error : ID " << ID << " not in the list" << endl;
2557  wf.status=false;
2558  return wf;
2559  }
2560 
2561  id = (id<0||id>(int)wfList[ID].list.size()) ? 0 : id;
2562  if((int)wfList[ID].list.size()==0) {
2563  wf=wfList[ID];
2564  } else {
2565  wf = id==0 ? wf=wfList[ID] : wfList[ID].list[id-1];
2566  }
2567 
2568  GetWaveform(wf); // if hp,hx are empty -> fill waveforms
2569 
2570  wf.status=true;
2571  return wf;
2572 }
2573 
2574 //______________________________________________________________________________
2575 void
2577 //
2578 // if hp,hx are empty -> fill waveforms
2579 // only MDC_EBBH is implemented
2580 //
2581 
2582  if((wf.hp.size()==0)&&(wf.hx.size()==0)) {
2583 #ifdef _USE_EBBH
2584  if(wf.par[0].value==MDC_EBBH) { // Get eBBH waveform
2585  int id;
2586  double m1,m2,rp0,e0,dist=0.,redshift=0.;
2587  std::stringstream linestream(wf.par[0].name.Data());
2588  if(!(linestream >> id >> m1 >> m2 >> rp0 >> e0 >> dist >> redshift)) {
2589  linestream.str(wf.par[0].name.Data());
2590  linestream.clear(); // clear stringstream error status
2591  if(!(linestream >> id >> m1 >> m2 >> rp0 >> e0 >> dist)) {
2592  linestream.str(wf.par[0].name.Data());
2593  linestream.clear(); // clear stringstream error status
2594  if(!(linestream >> id >> m1 >> m2 >> rp0 >> e0)) {
2595  cout << "CWB::mdc::GetWaveform - Wrong eBBH parameter format : " << endl;
2596  cout << "input line : " << endl;
2597  cout << wf.par[0].name.Data() << endl;
2598  cout << "must be : " << endl;
2599  cout << "event# " << "id " << " m1 " << " m2 " << " rp0 " << " e0 " << endl;
2600  cout << "or : " << endl;
2601  cout << "event# " << "id " << " m1 " << " m2 " << " rp0 " << " e0 " << " dist " << endl;
2602  cout << "or : " << endl;
2603  cout << "event# " << "id " << " m1 " << " m2 " << " rp0 " << " e0 " << " dist " << " redshift " << endl;
2604  exit(1);
2605  }
2606  }
2607  }
2608 
2609  if(wf.par.size()==1) { // create eBBH on the fly
2610 
2611  getEBBH(m1,m2,rp0,e0,wf.hp,wf.hx);
2612 
2613  // the distance of source is G*M/c^2 meters
2615  double M = watconstants::SolarMass();
2617  double pc = watconstants::Parsec();
2618  double distance_source_Kpc = (m1+m2)*G*M/(c*c)/pc/1.e3;
2619 
2620  // rescale hp,hx to 10 Kpc
2621  wf.hp*=distance_source_Kpc/10.;
2622  wf.hx*=distance_source_Kpc/10.;
2623 
2624  } else
2625  if(wf.par.size()==2) { // read eBBH from file
2626 
2627  TString fName = wf.par[1].name; // get root file name
2628  int entry = int(wf.par[1].value); // get tree entry number
2629 
2630  TFile* efile = new TFile(fName);
2631  if(efile==NULL) {
2632  cout << "CWB::mdc::GetWaveform - Error opening root file : " << fName.Data() << endl;
2633  exit(1);
2634  }
2635 
2638 
2639  TTree* etree = (TTree *) efile->Get("ebbh");
2640  if(etree==NULL) {
2641  cout << "CWB::mdc::GetWaveform - file : " << fName.Data()
2642  << " not contains tree ebbh" << endl;
2643  exit(1);
2644  }
2645 
2646  etree->SetBranchAddress("hp",&hp);
2647  etree->SetBranchAddress("hx",&hx);
2648 
2649  etree->GetEntry(entry);
2650 
2651  if(hp->size()!=hx->size()) {
2652  cout << "CWB::mdc::GetWaveform - Error : hp,hx size not equal !!!" << endl;
2653  exit(1);
2654  }
2655  if(hp->rate()!=hx->rate()) {
2656  cout << "CWB::mdc::GetWaveform - Error : hp,hx rate not equal !!!" << endl;
2657  exit(1);
2658  }
2659 
2660  wf.hp = *hp;
2661  wf.hx = *hx;
2662 
2663  delete hp;
2664  delete hx;
2665  delete efile;
2666 
2667  } else {
2668  cout << "CWB::mdc::GetWaveform - Error : wrong number of parameters not !!!" << endl;
2669  exit(1);
2670  }
2671  }
2672 #endif
2673  if((wf.hp.size()==0)&&(wf.hx.size()==0)) {
2674  cout << "CWB::mdc::GetWaveform - Error : hp,hp are empty !!!" << endl;
2675  exit(1);
2676  }
2677  }
2678 }
2679 
2680 //______________________________________________________________________________
2681 waveform
2683 //
2684 // Get waveform
2685 //
2686 //
2687 // Input: name - name of waveform
2688 // id - minor id of waveform
2689 //
2690 // Return waveform structure
2691 //
2692 
2693  waveform wf;
2694 
2695  // check if waveform is declared in the wfList
2696  int ID=-1;
2697  for(int i=0;i<(int)wfList.size();i++) if(wfList[i].name.CompareTo(name)==0) {ID=i;break;}
2698  if(ID<0) {
2699  wf.status=false;
2700  return wf;
2701  } else {
2702  id = (id<0||id>(int)wfList[ID].list.size()-1) ? 0 : id;
2703  if((int)wfList[id].list.size()==0) {
2704  wf=wfList[ID];
2705  } else {
2706  wf=wfList[ID].list[id];
2707  }
2708 
2709  GetWaveform(wf); // if hp,hx are empty -> fill waveforms
2710 
2711  wf.status=true;
2712  return wf;
2713  }
2714 }
2715 
2716 //______________________________________________________________________________
2717 int
2719 //
2720 // Get waveform
2721 //
2722 //
2723 // Input: name - name of waveform
2724 //
2725 // Return waveform ID
2726 //
2727 
2728  // check waveform name declared in the wfList
2729  int ID=-1;
2730  for(int i=0;i<(int)wfList.size();i++) if(wfList[i].name.CompareTo(name)==0) {ID=i;break;}
2731  return ID;
2732 }
2733 
2734 //______________________________________________________________________________
2735 void
2736 CWB::mdc::Print(int level) {
2737 //
2738 // Print list of waveforms
2739 //
2740 //
2741 // Input: level - if level=0 only the waveforms with major id are listed
2742 //
2743 
2744  cout << endl;
2745  for(int i=0;i<(int)wfList.size();i++) {
2746  printf("ID : %02i (x% 3i) \t%s\n",i,(int)wfList[i].list.size()+1,wfList[i].name.Data());
2747  printf("% 3i - ",1);
2748  for(int k=0;k<(int)wfList[i].par.size();k++)
2749  if(wfList[i].par[k].svalue!="") {
2750  printf("%s = %s ",wfList[i].par[k].name.Data(),wfList[i].par[k].svalue.Data());
2751  } else {
2752  printf("%s = %g ",wfList[i].par[k].name.Data(),wfList[i].par[k].value);
2753  }
2754  printf("\n");
2755  if(level>0) {
2756  for(int j=0;j<(int)wfList[i].list.size();j++) {
2757  printf("% 3i - ",j+2);
2758  for(int k=0;k<(int)wfList[i].par.size();k++)
2759  if(wfList[i].list[j].par[k].svalue!="") {
2760  printf("%s = %s ",wfList[i].list[j].par[k].name.Data(),wfList[i].list[j].par[k].svalue.Data());
2761  } else {
2762  printf("%s = %g ",wfList[i].list[j].par[k].name.Data(),wfList[i].list[j].par[k].value);
2763  }
2764  printf("\n");
2765  }
2766  }
2767  }
2768  cout << endl;
2769  return;
2770 }
2771 
2772 //______________________________________________________________________________
2773 double
2775 //
2776 // Get mdc central time
2777 //
2778 //
2779 // Input: wf - waveform structure which contains the waveform data
2780 //
2781 // Retun central time
2782 //
2783 
2784  wavearray<double> z=wf.hp; z+=wf.hx;
2785  return GetCentralTime(z);
2786 }
2787 
2788 //______________________________________________________________________________
2789 double
2791 //
2792 // Get mdc central time
2793 //
2794 //
2795 // Input: x - wavearray which contains the waveform data
2796 //
2797 // Retun central time
2798 //
2799 
2800  double a;
2801  double E=0.,T=0.;
2802  int size=(int)x.size();
2803  double rate=x.rate();
2804  for(int j=0;j<size;j++) {
2805  a = x[j];
2806  T += a*a*j/rate; // central time
2807  E += a*a; // energy
2808  }
2809  T = E>0 ? T/E : 0.5*size/rate;
2810 
2811  return T;
2812 }
2813 
2814 //______________________________________________________________________________
2815 double
2817 //
2818 // Get mdc central frequency
2819 //
2820 //
2821 // Input: wf - waveform structure which contains the waveform data
2822 //
2823 // Retun central frequency
2824 //
2825 
2826  wavearray<double> z=wf.hp; z+=wf.hx;
2827  return GetCentralFrequency(z);
2828 }
2829 
2830 //______________________________________________________________________________
2831 double
2833 //
2834 // Get mdc central frequency
2835 //
2836 //
2837 // Input: x - wavearray which contains the waveform data
2838 //
2839 // Retun central frequency
2840 //
2841 
2842  double a;
2843  double E=0.,F=0.;
2844  int size=(int)x.size();
2845  double rate=x.rate();
2846  x.FFTW(1);
2847  double dF=(rate/(double)size)/2.;
2848  for(int j=0;j<size/2;j+=2) {
2849  a = x[j]*x[j]+x[j+1]*x[j+1];
2850  F += a*j*dF; // central frequency
2851  E += a; // energy
2852  }
2853  F = E>0 ? F/E : 0.5*rate;
2854 
2855  return F;
2856 }
2857 
2858 //______________________________________________________________________________
2859 double
2860 CWB::mdc::GetTimeRange(wavearray<double> x, double& tMin, double& tMax, double efraction) {
2861 //
2862 // Get mdc time interval
2863 //
2864 //
2865 // Input: x - wavearray which contains the waveform data
2866 //
2867 // Output: tMin - start time interval
2868 // tMax - stop time interval
2869 //
2870 
2871  if(efraction<0) efraction=0;
2872  if(efraction>1) efraction=1;
2873 
2874  int N = x.size();
2875 
2876  double E = 0; // signal energy
2877  double avr = 0; // average
2878  for(int i=0;i<N;i++) {avr+=i*x[i]*x[i]; E+=x[i]*x[i];}
2879  int M=int(avr/E); // central index
2880 
2881  // search range which contains percentage P of the total energy E
2882  int jB=0;
2883  int jE=N-1;
2884  double a,b;
2885  double sum = ((M>=0)&&(M<N)) ? x[M]*x[M] : 0.;
2886  for(int j=1; j<N; j++) {
2887  a = ((M-j>=0)&&(M-j<N)) ? x[M-j] : 0.;
2888  b = ((M+j>=0)&&(M+j<N)) ? x[M+j] : 0.;
2889  if(a) jB=M-j;
2890  if(b) jE=M+j;
2891  sum += a*a+b*b;
2892  if(sum/E > efraction) break;
2893  }
2894 
2895  tMin = jB/x.rate();
2896  tMax = jE/x.rate();
2897 
2898  return tMax-tMin;
2899 }
2900 
2901 //______________________________________________________________________________
2902 void
2904 //
2905 // apply time shift
2906 //
2907 //
2908 // Input: x - wavearray which contains the waveform data
2909 // time - time shift (sec)
2910 //
2911 
2912  if(tShift==0) return;
2913 
2914  // search begin,end of non zero data
2915  int ibeg=0; int iend=0;
2916  for(int i=0;i<(int)x.size();i++) {
2917  if(x[i]!=0 && ibeg==0) ibeg=i;
2918  if(x[i]!=0) iend=i;
2919  }
2920  int ilen=iend-ibeg+1;
2921  // create temporary array for FFTW & add scratch buffer + tShift
2922  int ishift = fabs(tShift)*x.rate();
2923  int isize = 2*ilen+2*ishift;
2924  isize = isize + (isize%4 ? 4 - isize%4 : 0); // force to be multiple of 4
2925  wavearray<double> w(isize);
2926  w.rate(x.rate()); w=0;
2927  // copy x data !=0 in the middle of w array & set x=0
2928  for(int i=0;i<ilen;i++) {w[i+ishift+ilen/2]=x[ibeg+i];x[ibeg+i]=0;}
2929 
2930  double pi = TMath::Pi();
2931  // apply time shift to waveform vector
2932  w.FFTW(1);
2933  TComplex C;
2934  double df = w.rate()/w.size();
2935  //cout << "tShift : " << tShift << endl;
2936  for (int ii=0;ii<(int)w.size()/2;ii++) {
2937  TComplex X(w[2*ii],w[2*ii+1]);
2938  X=X*C.Exp(TComplex(0.,-2*pi*ii*df*tShift)); // Time Shift
2939  w[2*ii]=X.Re();
2940  w[2*ii+1]=X.Im();
2941  }
2942  w.FFTW(-1);
2943 
2944  // copy shifted data to input x array
2945  for(int i=0;i<(int)w.size();i++) {
2946  int j=ibeg-(ishift+ilen/2)+i;
2947  if((j>=0)&&(j<(int)x.size())) x[j]=w[i];
2948  }
2949 
2950  return;
2951 }
2952 
2953 //______________________________________________________________________________
2954 void
2956 //
2957 // apply phase shift
2958 //
2959 //
2960 // Input: x - wavearray which contains the waveform data
2961 // pShift - phase shift (degrees)
2962 //
2963 
2964  if(pShift==0) return;
2965 
2966  // search begin,end of non zero data
2967  int ibeg=0; int iend=0;
2968  for(int i=0;i<(int)x.size();i++) {
2969  if(x[i]!=0 && ibeg==0) ibeg=i;
2970  if(x[i]!=0) iend=i;
2971  }
2972  int ilen=iend-ibeg+1;
2973  // create temporary array for FFTW & add scratch buffer + tShift
2974  int isize = 2*ilen;
2975  isize = isize + (isize%4 ? 4 - isize%4 : 0); // force to be multiple of 4
2976  wavearray<double> w(isize);
2977  w.rate(x.rate()); w=0;
2978  // copy x data !=0 in the middle of w array & set x=0
2979  for(int i=0;i<ilen;i++) {w[i+isize/4]=x[ibeg+i];x[ibeg+i]=0;}
2980 
2981  // apply phase shift to waveform vector
2982  w.FFTW(1);
2983  TComplex C;
2984  //cout << "pShift : " << pShift << endl;
2985  pShift*=TMath::Pi()/180.;
2986  for (int ii=0;ii<(int)w.size()/2;ii++) {
2987  TComplex X(w[2*ii],w[2*ii+1]);
2988  X=X*C.Exp(TComplex(0.,-pShift)); // Phase Shift
2989  w[2*ii]=X.Re();
2990  w[2*ii+1]=X.Im();
2991  }
2992  w.FFTW(-1);
2993 
2994  // copy shifted data to input x array
2995  for(int i=0;i<(int)w.size();i++) {
2996  int j=ibeg-isize/4+i;
2997  if((j>=0)&&(j<(int)x.size())) x[j]=w[i];
2998  }
2999 
3000  return;
3001 }
3002 
3003 //______________________________________________________________________________
3005 CWB::mdc::GetSGQ(double frequency, double Q) {
3006 //
3007 // Get SinGaussian
3008 //
3009 //
3010 // Input: frequency - SG frequency (Hz)
3011 // Q - SG Q factor
3012 //
3013 // Return wavearray data containing the waveform
3014 //
3015 
3017  x.rate(MDC_SAMPLE_RATE);
3018  x=0;
3019  double amplitude=1.;
3020  double duration = Q/(TMath::TwoPi()*frequency);
3021  AddSGBurst(x, amplitude, frequency, duration,0);
3022 
3023  return x;
3024 }
3025 
3026 //______________________________________________________________________________
3028 CWB::mdc::GetCGQ(double frequency, double Q) {
3029 //
3030 // Get CosGaussian
3031 //
3032 //
3033 // Input: frequency - CG frequency (Hz)
3034 // Q - CG Q factor
3035 //
3036 // Return wavearray data containing the waveform
3037 //
3038 
3040  x.rate(MDC_SAMPLE_RATE);
3041  x=0;
3042  double amplitude=1.;
3043  double duration = Q/(TMath::TwoPi()*frequency);
3044  AddCGBurst(x, amplitude, frequency, duration,0);
3045 
3046  return x;
3047 }
3048 
3049 #define GA_FORMULA_WNB "[0]*TMath::Exp(-TMath::Power((x-[2])/[1],2)/2)"
3050 
3051 //______________________________________________________________________________
3053 CWB::mdc::GetWNB(double frequency, double bandwidth, double duration, int seed, bool mode) {
3054 //
3055 // Get White Band Gaussian Noise
3056 //
3057 //
3058 // Input: frequency - start white band frequency (Hz)
3059 // bandwidth - (Hz)
3060 // duration - (sec)
3061 // mode - if mode=1 -> apply Patrik Sutton Method
3062 // simmetric respect to the central frequency
3063 // if mode=0 -> asymmetric respect to the central frequency
3064 //
3065 // Return wavearray data containing the waveform
3066 //
3067 
3068  gRandom->SetSeed(seed);
3069 
3070  // Generate white gaussian noise 1 sec
3072  x.rate(MDC_SAMPLE_RATE);
3073  for (int i=0;i<(int)x.size();i++) x[i]=gRandom->Gaus(0,1);
3074 
3075  double dt = 1./x.rate();
3076  double df = x.rate()/x.size();
3077 
3078  // Apply a band limited cut in frequency
3079  x.FFTW(1);
3080  if(mode==1) {
3081  // set zero bins outside the range [0,bandwidth/2]
3082  // Heterodyne up by frequency+bandwidth/2 (move zero frequency to center of desidered band)
3083  int bFrequency = frequency/df;
3084  int bBandwidth = (bandwidth/2.)/df;
3085  wavearray<double> y=x; y=0;
3086  int bin = 2*(bFrequency+bBandwidth);
3087  y[bin]=x[0];
3088  y[bin+1]=x[1];
3089  for (int i=1;i<bBandwidth;i++) {
3090  y[bin+2*i]=x[2*i];
3091  y[bin+2*i+1]=x[2*i+1];
3092 
3093  y[bin-2*i]=x[2*i];
3094  y[bin-2*i+1]=-x[2*i+1];
3095  }
3096  x=y;;
3097  x.FFTW(-1);
3098  } else {
3099  // set zero bins outside the range [frequency,frequency+bandwidth]
3100  int bLow = frequency/df;
3101  int bHigh = (frequency+bandwidth)/df;
3102  for (int i=0;i<bLow;i++) {x[2*i]=0;x[2*i+1]=0;}
3103  for (int i=bHigh;i<(int)x.size()/2;i++) {x[2*i]=0;x[2*i+1]=0;}
3104  x.FFTW(-1);
3105  }
3106 
3107  // Apply a gaussian shape in time
3108  double function_range = 1.; // duration 1 sec
3109  TF1* ga_function = new TF1("Gaussian",GA_FORMULA_WNB,-function_range/2,function_range/2);
3110  ga_function->SetParameter(0,1);
3111  ga_function->SetParameter(1,duration);
3112  ga_function->SetParameter(2,function_range/2);
3113  for (int i=0;i<(int)x.size();i++) x[i]*=ga_function->Eval(dt*(i+1));
3114 
3115  // normalization
3116  double hrss=0;
3117  for (int i=0;i<(int)x.size();i++) hrss+=x[i]*x[i];
3118  hrss=sqrt(hrss*dt);
3119  for (int i=0;i<(int)x.size();i++) x[i]*=(1./sqrt(2.))*1./hrss;
3120 
3121  delete ga_function;
3122 
3123  return x;
3124 }
3125 
3126 #define GA_FORMULA "[0]*TMath::Exp(-TMath::Power((x-[2])/[1],2))"
3127 
3128 //______________________________________________________________________________
3131 //
3132 // Get Gaussian signal
3133 //
3134 //
3135 // Input: duration - (sec)
3136 //
3137 // Return wavearray data containing the waveform
3138 
3139  // Apply a gaussian shape in time
3140  double function_range = 1.; // duration 1 sec
3141  TF1* ga_function = new TF1("Gaussian",GA_FORMULA,-function_range/2,function_range/2);
3142  ga_function->SetParameter(0,1);
3143  ga_function->SetParameter(1,duration);
3144  ga_function->SetParameter(2,function_range/2);
3145 
3146  double dt = 1./MDC_SAMPLE_RATE;
3147 
3148  // plus component
3150  x.rate(MDC_SAMPLE_RATE);
3151  for (int i=0;i<(int)x.size();i++) x[i]=ga_function->Eval(dt*(i+1));
3152 
3153  // normalization
3154  double hrss=0;
3155  for (int i=0;i<(int)x.size();i++) hrss+=x[i]*x[i];
3156  hrss=sqrt(hrss*dt);
3157  for (int i=0;i<(int)x.size();i++) x[i]*=1./hrss;
3158 
3159  delete ga_function;
3160 
3161  return x;
3162 }
3163 
3164 #define RD_FORMULA "(((x-1./4./[2]+TMath::Abs(x-1./4./[2]))/2./(x-1./4./[2]))*[0]*TMath::Cos(TMath::TwoPi()*[2]*x)+[1]*TMath::Sin(TMath::TwoPi()*[2]*x))*TMath::Exp(-x/[3])" // Heaviside in cos like Andrea Vicere'
3165 
3166 //______________________________________________________________________________
3168 CWB::mdc::GetRD(double frequency, double tau, double iota, bool polarization) {
3169 //
3170 // Get RingDown signal
3171 //
3172 //
3173 // Input: frequency - (Hz)
3174 // tau - (sec)
3175 // iota - (degrees)
3176 // polarization - (degrees)
3177 //
3178 // Return wavearray data containing the waveform
3179 //
3180 
3181  iota*=TMath::Pi()/180.;
3182 
3183  double c2 = TMath::Cos(iota);
3184  double c1 = (1+c2*c2)/2.;
3185 
3186  if (c1/c2<1e-10) c1=0;
3187 
3188  char rd_formula[256] = RD_FORMULA;
3189  double function_range = 1.; // duration 1 sec
3190  TF1* rd_function = new TF1("RingDown",rd_formula,0.,function_range);
3191  rd_function->SetParameter(2,frequency);
3192  rd_function->SetParameter(3,tau);
3193 
3194  double time_offset=0.05; // it is necessary to allows negative time shift
3195  double dt = 1./MDC_SAMPLE_RATE;
3196 
3197  // plus component
3199  x.rate(MDC_SAMPLE_RATE);
3200  rd_function->SetParameter(0,c1);
3201  rd_function->SetParameter(1,0);
3202  for (int i=0;i<(int)x.size();i++) {
3203  double time = dt*(i+1)-time_offset;
3204  if (time>=0) x[i]=rd_function->Eval(time); else x[i]=0;
3205  }
3206 
3207  // cross component
3208  wavearray<double> y(int(inj_length*MDC_SAMPLE_RATE));
3209  y.rate(MDC_SAMPLE_RATE);
3210  rd_function->SetParameter(0,0);
3211  rd_function->SetParameter(1,c2);
3212  for (int i=0;i<(int)y.size();i++) {
3213  double time = dt*(i+1)-time_offset;
3214  if (time>=0) y[i]=rd_function->Eval(time); else y[i]=0;
3215  }
3216 
3217  double hrss=0;
3218  for (int i=0;i<(int)x.size();i++) hrss+=x[i]*x[i]+y[i]*y[i];
3219  hrss=sqrt(hrss*dt);
3220  for (int i=0;i<(int)x.size();i++) x[i]*=1./hrss;
3221  for (int i=0;i<(int)y.size();i++) y[i]*=1./hrss;
3222 
3223  delete rd_function;
3224 
3225  return polarization==0 ? x : y;
3226 }
3227 
3228 //______________________________________________________________________________
3229 void
3230 CWB::mdc::AddGauss(wavearray<double> &td, double v, double u) {
3231 //
3232 // Add Gaussian Noise
3233 //
3234 //
3235 // Input: td - wavearray with input data signal
3236 // v - sigma of gaussian noise
3237 // u - median of gaussian noise
3238 //
3239 // Output: td - Return input signal + gaussian noise
3240 //
3241 
3242  int n=td.size();
3243  for (int i=0; i < n; i++){
3244  td.data[i] += v*gRandom->Gaus(0.,1.)+u;
3245  }
3246 }
3247 
3248 //______________________________________________________________________________
3249 void
3251 //
3252 // Add exponential noise
3253 //
3254 //
3255 // Input: td - wavearray with input data signal
3256 // v - 1/tau of exponential
3257 // M - number of random values added for each sample
3258 //
3259 // Output: td - Return input signal + exponential noise
3260 //
3261 
3262  int i,j;
3263  double x,y;
3264  int m=abs(M);
3265  int n=td.size();
3266  for (i=0; i<n; i++){
3267  y = 0.;
3268  for (j=0; j<m; j++){
3269  x = gRandom->Exp(v);
3270  if(M>0) y += x;
3271  else if(x>y) y=x;
3272  }
3273  td.data[i] += y;
3274  }
3275 }
3276 
3277 //______________________________________________________________________________
3278 void
3279 CWB::mdc::AddSGBurst(wavearray<double> &td, double a, double f, double s, double d) {
3280 //
3281 // Add SinGaussian burst
3282 //
3283 //
3284 // Input: td - wavearray with input data signal
3285 // a - amplitude
3286 // f - frequency (Hz)
3287 // s - gaussian RMS
3288 // d - duration (sec)
3289 //
3290 // Output: td - Return input signal + SinGaussian burst
3291 //
3292 
3293  int n=td.size();
3294  double r = td.rate();
3295  int m;
3296  double g, t;
3297  double sum = 0.;
3298  double delay = d;
3299 
3300  m = int(6*s*r);
3301  if(m > n/2-1) m = n/2-2;
3302 
3303  for (int i=0; i < m; i++){
3304  t = i/r;
3305  g = 2*TMath::Exp(-t*t/2/s/s)*TMath::Sin(2*PI*f*t);
3306  sum += g*g;
3307  }
3308  a *= TMath::Sqrt(r/sum);
3309 
3310  td.data[n/2+int(delay*r)] += 0;
3311  for (int i=1; i < m; i++){
3312  t = i/r;
3313  g = a*TMath::Exp(-t*t/2/s/s)*TMath::Sin(2*PI*f*t);
3314  td.data[n/2+i+int(delay*r)] += g;
3315  td.data[n/2-i+int(delay*r)] -= g;
3316  }
3317 }
3318 
3319 //______________________________________________________________________________
3320 void
3321 CWB::mdc::AddCGBurst(wavearray<double> &td, double a, double f, double s, double d) {
3322 //
3323 // Add CosGaussian burst
3324 //
3325 //
3326 // Input: td - wavearray with input data signal
3327 // a - amplitude
3328 // f - frequency (Hz)
3329 // s - gaussian RMS
3330 // d - duration (sec)
3331 //
3332 // Output: td - Return input signal + CosGaussian burst
3333 //
3334 
3335  int n=td.size();
3336  double r = td.rate();
3337  int m;
3338  double g, t;
3339  double sum = 0.;
3340  double delay = d;
3341 
3342  m = int(6*s*r);
3343  if(m > n/2-1) m = n/2-2;
3344 
3345  for (int i=0; i < m; i++){
3346  t = i/r;
3347  g = 2*TMath::Exp(-t*t/2/s/s)*TMath::Cos(2*PI*f*t);
3348  sum += g*g;
3349  }
3350  a *= TMath::Sqrt(r/sum);
3351 
3352  td.data[n/2+int(delay*r)] += a;
3353  for (int i=1; i < m; i++){
3354  t = i/r;
3355  g = a*TMath::Exp(-t*t/2/s/s)*TMath::Cos(2*PI*f*t);
3356  td.data[n/2+i+int(delay*r)] += g;
3357  td.data[n/2-i+int(delay*r)] += g;
3358  }
3359 }
3360 
3361 //______________________________________________________________________________
3362 void
3364 //
3365 // Add windowed Gaussian noise
3366 //
3367 //
3368 // Input: td - wavearray with input data signal
3369 // a - amplitude
3370 // s - gaussian RMS
3371 //
3372 // Output: td - Return input signal + windowed Gaussian noise
3373 //
3374 
3375  int n=td.size();
3376  double r = td.rate();
3377  int m;
3378  double g, t;
3379  double sum = 0.;
3380 
3381  m = int(3*s*r);
3382  if(m > n/2-1) m = n/2-2;
3383  wavearray<double> gn(2*m);
3384 
3385 
3386  for (int i=0; i < m; i++){
3387  t = i/r;
3388  g = TMath::Exp(-t*t/2/s/s);
3389  gn.data[m+i] = g*gRandom->Gaus(0.,1.);
3390  gn.data[m-i-1] = g*gRandom->Gaus(0.,1.);
3391  sum += gn.data[m+i]*gn.data[m+i] + gn.data[m-i-1]*gn.data[m-i-1];
3392  }
3393  a *= TMath::Sqrt(r/sum);
3394 
3395  for (int i=0; i < m; i++){
3396  t = i/r;
3397  td.data[n/2+i] += a*gn.data[m+i];
3398  td.data[n/2-i] += a*gn.data[m-i-1];
3399  }
3400 }
3401 
3402 // --------------------------------------------------------
3403 // Miyamoto-Nagai Galactic Disk Model
3404 // www.astro.utu.fi/~cflynn/galdyn/lecture4.html
3405 // a=[0]
3406 // b=[1] scale length
3407 // R=x, z=y
3408 // --------------------------------------------------------
3409 
3410 #define MNGD_NUMERATOR "([0]*((x-[3])*(x-[3])+y*y)+([0]+3*sqrt(z*z+[1]*[1]))*pow([0]+sqrt(z*z+[1]*[1]),2))"
3411 #define MNGD_DENOMINATOR "(pow(((x-[3])*(x-[3])+y*y)+pow([0]+sqrt(z*z+[1]*[1]),2),5./2.)*pow(z*z+[1]*[1],3./2.))"
3412 
3413 #define MNGD_B 0.3 // Kpc
3414 #define MNGD_Md1 6.6e10 // Msol
3415 #define MNGD_A1 5.81 // Kpc
3416 #define MNGD_Md2 -2.9e10 // Msol
3417 #define MNGD_A2 17.43 // Kpc
3418 #define MNGD_Md3 3.3e9 // Msol
3419 #define MNGD_A3 34.86 // Kpc
3420 
3421 #define MNGD_XMAX 40
3422 #define MNGD_YMAX 4
3423 
3424 #define MNGD_SOLAR_SISTEM_DISTANCE_FROM_GC 7.62 // 7.62 [+/-0.32] Kpc it.wikipedia.org/wiki/Via_Lattea
3425 
3426 
3427 //______________________________________________________________________________
3428 void
3430 //
3431 // Set Sky Distribution
3432 //
3433 // see SetSkyDistribution(MDC_DISTRIBUTION sky_distribution, TString fName, vector<mdcpar> par, int seed)
3434 //
3435 //
3436 
3437  vector<mdcpar> par;
3438  SetSkyDistribution(sky_distribution, fName, par, seed, add);
3439  return;
3440 }
3441 
3442 //______________________________________________________________________________
3443 void
3445 //
3446 // Set Sky Distribution
3447 //
3448 // see SetSkyDistribution(MDC_DISTRIBUTION sky_distribution, TString fName, vector<mdcpar> par, int seed)
3449 //
3450 
3451  SetSkyDistribution(sky_distribution, "", par, seed, add);
3452  return;
3453 }
3454 
3455 //______________________________________________________________________________
3456 void
3458 //
3459 // Set Sky Distribution
3460 //
3461 //
3462 // Input: sky_distribution - sky distribution type
3463 // fName - input file name
3464 // par - input sky distribution parameters
3465 // seed - seed for random selection
3466 // add - add (def=false) if true the distribution is added to the current one
3467 //
3468 // sky_distribution & par & fName can be one of the following choices :
3469 //
3470 // MDC_RANDOM = random sky distribution (fName not used)
3471 // fName can be used to define a custom rho distribution
3472 // example : fName="pow(x,2)"
3473 // do not use par[n].name="rho_dist";
3474 // vector<mdcpar> par(1);
3475 // par[0].name="entries"; par[0].value=XXX; // number of random events
3476 // par.resize(3);
3477 // par[1].name="rho_min"; par[1].value=MIN; // min distance in kPc
3478 // par[2].name="rho_max"; par[2].value=MAX; // max distance in kPc
3479 // // if(rho_min>0 && rho_max>=rho_min)
3480 // // the amplitude is rescaled to 10/rho (10 Kpc is the stantard candle distance)
3481 // // if rho_min,rho_max are not defined the amplitude is not rescaled
3482 // //
3483 // par[n].name="rho_dist"; // define the rho distribution
3484 // par[n].value=x; // dist is rho^x
3485 // // if "rho_dist" is not defined then the distance of events
3486 // // is randomly selected from a (rho*rho) distribution
3487 // // so the sky distribution is uniform in volume
3488 //
3489 // par[m].name="iota"; par[m].value=iota; // ellipticity [0:180] deg
3490 // // if<0 || >180 -> iota=random
3491 // // default : iota=0
3492 // par[p].name="psi"; par[p].value=psi; // polarization (deg)
3493 // // if not defined -> random
3494 //
3495 // MDC_EARTH_FIX = earth fixed greographical coordinates (latitude, longitude)
3496 // MDC_CELESTIAL_FIX = celestial fixed coordinates (DEC, RA)
3497 // vector<mdcpar> par(2);
3498 // par[0].name="theta"; par[0].value=XXX; // degrees
3499 // par[1].name="phi"; par[1].value=YYY; // degrees
3500 // par.resize(3);
3501 // par[2].name="psi"; par[2].value=ZZZ; // degrees
3502 // par.resize(4);
3503 // par[3].name="rho"; par[3].value=UUU; // kPc
3504 // par.resize(5);
3505 // par[4].name="gps"; par[4].value=VVV; // sec
3506 // par.resize(6);
3507 // par[5].name="entries"; par[5].value=TTT; // number of random events
3508 // par.resize(7);
3509 // par[6].name="iota"; par[6].value=iota; // ellipticity [0:180] deg
3510 // // if<0 || >180 -> random
3511 //
3512 // MDC_MNGD = Miyamoto-Nagai Galactic Disk Model (fName,par not used)
3513 // www.astro.utu.fi/~cflynn/galdyn/lecture4.html
3514 // vector<mdcpar> par(1);
3515 // par[0].name="entries"; par[0].value=XXX; // number of random events
3516 // par.resize(2);
3517 // par[1].name="iota"; par[1].value=iota; // ellipticity [0:180] deg
3518 // // if<0 || >180 -> random
3519 //
3520 // MDC_GWGC = Gravitation Wave Galaxy Catalog (par not used)
3521 // fName = path name of galaxy catalog
3522 // vector<mdcpar> par(1);
3523 // par[0].name="distance_thr"; par[0].value=XXX; // distance max (Kpc)
3524 // par.resize(2);
3525 // par[1].name="iota"; par[1].value=iota; // ellipticity [0:180] deg
3526 // // if<0 || >180 -> random
3527 //
3528 // MDC_XMLFILE = mdc xml file
3529 // fName = path name of mdc xml file (LAL xml format)
3530 // par[0].name="start"; par[0].value=XXX; // start GPS time to search in XML file
3531 // par[1].name="stop"; par[1].value=YYY; // stop GPS time to search in XML file
3532 // par[2].name="hrss_factor"; par[2].value=ZZZ; // used to rescale hrss (default=1)
3533 // par[3].name="decimals"; par[3].value=WWW; // used to format the MDC name (default=1)
3534 // par[4].name="engine";par[4].value=V; // mdc engine : 0->AAL, 1->CWB (default=1)
3535 // par[5].name="auto";par[5].value=T; // 0/1->disaable/enable (default=0)
3536 // NOTE : if auto=0 the MDC names must be provided by user using the following setup:
3537 // par[6].name="type"; par[6].svalue="MDC_NAME1"; // MDC name1 (with CWB Format)
3538 // par[X].name="type"; par[X].svalue="MDC_NAMEX"; // MDC nameX (with CWB Format)
3539 // par[N].name="type"; par[N].svalue="MDC_NAMEN"; // MDC nameN (with CWB Format)
3540 //
3541 // MDC_LOGFILE = mdc log file
3542 // fName = path name of mdc log file
3543 //
3544 // MDC_CUSTOM = user define distribution
3545 // fName = path name of user file
3546 // file format : gps name theta phi psi rho iota hrss ID id
3547 // theta = [0:180] deg : phi = [0:360] deg : psi = [0:180] deg : iota = [0:180] deg
3548 // ID/id are the major/minor id waveform numbers
3549 // if ID=-1 then 'name' is used, if id=1 then id is selected randomly
3550 //
3551 // Note1: the angle iota is the inclination of the system which originates the burst with respect to the line of sight
3552 // iota = 0 : the line of sight is perpendicular to the orbit plane
3553 // iota = 90 : the line of sight has 0 deg inclination angle respect to the orbit plane
3554 // the h+ ellipticity factor is : (1+cos[iota]*cos[iota])/2
3555 // the hx ellipticity factor is : cos[iota]
3556 //
3557 // Note2: rho defines the distance of the source in Kpc
3558 // if rho=0 then the hrss is the one defined with SetInjHrss (default)
3559 // if rho>0 then the hrss is rescaled by a factor 10/rho;
3560 // the hrss defined with SetInjHrss is the hrss at 10Kpc
3561 //
3562 
3563  gRandom->SetSeed(seed);
3564 
3565  this->sky_distribution=sky_distribution;
3566  this->sky_file=fName;
3567  this->sky_parms=par;
3568 
3569  double rad2deg = 180./TMath::Pi();
3570 
3571  if(!add) {
3572  nameList.clear();
3573  thList.clear();
3574  phList.clear();
3575  psiList.clear();
3576  rhoList.clear();
3577  iotaList.clear();
3578  hrssList.clear();
3579  gpsList.clear();
3580  IDList.clear();
3581  idList.clear();
3582  }
3583 
3584  if(sky_distribution==MDC_RANDOM) {
3585 
3586  bool error=false;
3587  int entries = GetPar("entries",par,error);
3588  double rho_min = GetPar("rho_min",par,error);
3589  if(error) rho_min=0.;
3590  double rho_max = GetPar("rho_max",par,error);
3591  if(error) rho_max=0.;
3592 
3593  if(entries<=0) {
3594  cout << "CWB::mdc::SetSkyDistribution - "
3595  << "Error : entries must be positive" << endl;
3596  exit(1);
3597  }
3598  if(rho_max>0 && rho_min<=0) {
3599  cout << "CWB::mdc::SetSkyDistribution - " << "Error : rho_min must be > 0" << endl;
3600  exit(1);
3601  }
3602  if(rho_min>rho_max) {
3603  cout << "CWB::mdc::SetSkyDistribution - " << "Error : rho_min must be <= rho_max" << endl;
3604  exit(1);
3605  }
3606 
3607  cout << "CWB::mdc::SetSkyDistribution - All Sky random distribution" << endl;
3608 
3609  TF1 *rd = NULL;
3610  // define the rho distribution
3611  if(rho_min!=rho_max) {
3612  double rho_dist = GetPar("rho_dist",par,error);
3613  char rho_dist_func[256];
3614  if((!error)&&(fName=="")) sprintf(rho_dist_func,"pow(x,%f)",rho_dist); // custom pow(rho,rho_dist)
3615  else if(( error)&&(fName=="")) sprintf(rho_dist_func,"pow(x,2)"); // default distribution
3616  else if(( error)&&(fName!="")) strcpy(rho_dist_func,fName.Data()); // custom formula
3617  else if((!error)&&(fName!="")) { // ambiguoius definition
3618  cout << "CWB::mdc::SetSkyDistribution - "
3619  << "Error : ambiguous rho distribution - is defined twice "
3620  << " 1) as rho_dist params, 2) as formula" << endl;
3621  exit(1);
3622  }
3623  rd = new TF1("rd",rho_dist_func,rho_min,rho_max); // sky distribution rho^rho_dist
3624  TF1* rdcheck = (TF1*)gROOT->GetListOfFunctions()->FindObject("rd"); // check if formula is correct
3625  if(rdcheck==NULL) {
3626  cout << "CWB::mdc::SetSkyDistribution - "
3627  << "Error : wrong formula format : " << rho_dist_func << endl;
3628  exit(1);
3629  }
3630  }
3631 
3632  for(int n=0;n<entries;n++) {
3633  thList.push_back(rad2deg*acos(gRandom->Uniform(-1,1))-90.);
3634  phList.push_back(gRandom->Uniform(-180,180));
3635  if(rd!=NULL) rhoList.push_back(rd->GetRandom());
3636  else rhoList.push_back(rho_min);
3637 
3638  error=false;double value=GetPar("psi",par,error);
3639  double psi = error ? gRandom->Uniform(0,180) : value;
3640  psiList.push_back(psi);
3641 
3642  error=false;double iota = GetPar("iota",par,error);
3643  if(error) iotaList.push_back(0);
3644  else if(iota>=0&&iota<=180) iotaList.push_back(iota);
3645  else iotaList.push_back(rad2deg*acos(gRandom->Uniform(-1,1)));
3646 
3647  hrssList.push_back(0);
3648  IDList.push_back(-1);
3649  idList.push_back(-1);
3650  }
3651 
3652  if(rd!=NULL) delete rd;
3653 
3654  } else
3655  if(sky_distribution==MDC_MNGD) {
3656 
3657  bool error=false;
3658  double entries = GetPar("entries",par,error);
3659 
3660  if(error) {
3661  cout << "CWB::mdc::SetSkyDistribution - "
3662  << "Error : num par must be 1 [entries]" << endl;
3663  exit(1);
3664  }
3665 
3666  cout << "CWB::mdc::SetSkyDistribution - the Miyamoto-Nagai Galactic Disk Model" << endl;
3667 
3668  char formula[256];
3669  sprintf(formula,"[1]*[1]*[2]*%s/%s",MNGD_NUMERATOR,MNGD_DENOMINATOR);
3670 
3671  TF3 *gd1 = new TF3("gd1",formula,-MNGD_XMAX,MNGD_XMAX,-MNGD_XMAX,MNGD_XMAX,-MNGD_YMAX,MNGD_YMAX);
3672  gd1->SetParameter(0,MNGD_A1); // a
3673  gd1->SetParameter(1,MNGD_B); // b
3674  gd1->SetParameter(2,MNGD_Md1); // b
3675  gd1->SetParameter(3,MNGD_SOLAR_SISTEM_DISTANCE_FROM_GC);
3676 
3677  TF3 *gd2 = new TF3("gd2",formula,-MNGD_XMAX,MNGD_XMAX,-MNGD_XMAX,MNGD_XMAX,-MNGD_YMAX,MNGD_YMAX);
3678  gd2->SetParameter(0,MNGD_A2); // a
3679  gd2->SetParameter(1,MNGD_B); // b
3680  gd2->SetParameter(2,MNGD_Md2); // b
3681  gd2->SetParameter(3,MNGD_SOLAR_SISTEM_DISTANCE_FROM_GC);
3682 
3683  TF3 *gd3 = new TF3("gd3",formula,-MNGD_XMAX,MNGD_XMAX,-MNGD_XMAX,MNGD_XMAX,-MNGD_YMAX,MNGD_YMAX);
3684  gd3->SetParameter(0,MNGD_A3); // a
3685  gd3->SetParameter(1,MNGD_B); // b
3686  gd3->SetParameter(2,MNGD_Md3); // b
3687  gd3->SetParameter(3,MNGD_SOLAR_SISTEM_DISTANCE_FROM_GC);
3688 
3689  TF3* gd = new TF3("gd","gd1+gd2+gd3",-MNGD_XMAX,MNGD_XMAX,-MNGD_XMAX,MNGD_XMAX,-MNGD_YMAX,MNGD_YMAX);
3690 
3691  gd->SetNpx(100);
3692  gd->SetNpy(100);
3693  gd->SetNpz(100);
3694 
3695  // Generate randomly sources from the Gatactic Disk
3696 
3697  XYZVector xyz;
3699  xyz.SetXYZ(xgc,ygc,zgc);
3700 
3701  double ilongitude = xyz.Phi()*rad2deg;
3702  double ilatitude = -(xyz.Theta()-TMath::Pi()/2.)*rad2deg;
3703  double olongitude,olatitude;
3704  GalacticToEquatorial(ilongitude, ilatitude, olongitude, olatitude);
3705  double gc_phi = olongitude;
3706  double gc_theta = olatitude;
3707  double gc_rho = sqrt(xyz.mag2());
3708 
3709  cout << "gc_phi : " << gc_phi << " gc_theta : " << gc_theta << " " << gc_rho << endl;
3710 
3711  double x,y,z;
3712  for(int n=0;n<entries;n++) {
3713 
3714  gd->GetRandom3(x,y,z);
3715  xyz.SetXYZ(x,y,z);
3716 
3717  double ilongitude = xyz.Phi()*rad2deg;
3718  double ilatitude = -(xyz.Theta()-TMath::Pi()/2.)*rad2deg;
3719  double olongitude,olatitude;
3720  GalacticToEquatorial(ilongitude, ilatitude, olongitude, olatitude);
3721  phList.push_back(olongitude);
3722  thList.push_back(olatitude);
3723  psiList.push_back(gRandom->Uniform(0,180));
3724  rhoList.push_back(sqrt(xyz.mag2()));
3725 
3726  error=false;double iota = GetPar("iota",par,error);
3727  if(error) iotaList.push_back(0);
3728  else if(iota>=0&&iota<=180) iotaList.push_back(iota);
3729  else iotaList.push_back(rad2deg*acos(gRandom->Uniform(-1,1)));
3730 
3731  hrssList.push_back(0);
3732  IDList.push_back(-1);
3733  idList.push_back(-1);
3734  }
3735 
3736  delete gd1;
3737  delete gd2;
3738  delete gd3;
3739  delete gd;
3740 
3741  } else
3742  if(sky_distribution==MDC_GWGC) {
3743 
3744  bool error=false;
3745  double distance_thr = GetPar("distance_thr",par,error);
3746 
3747  if(error) {
3748  cout << "CWB::mdc::SetSkyDistribution - "
3749  << "Error : num par must be 1 [distance_thr]" << endl;
3750  exit(1);
3751  }
3752 
3753  cout << "CWB::mdc::SetSkyDistribution - Gravitational Wave Galaxy Catalog" << endl;
3754  cout << "CWB::mdc::SetSkyDistribution - Distance Threshold " << distance_thr << " Kpc" << endl;
3755 
3756  ifstream in;
3757  in.open(fName,ios::in);
3758  if (!in.good()) {cout << "CWB::mdc::SetSkyDistribution - Error Opening File : " << fName << endl;exit(1);}
3759 
3760  // get number of entries
3761  int entries=0;
3762  char str[1024];
3763  while(true) {
3764  in.getline(str,1024);
3765  if (!in.good()) break;
3766  if(str[0] != '#') entries++;
3767  }
3768  cout << "entries " << entries << endl;
3769  in.clear(ios::goodbit);
3770  in.seekg(0, ios::beg);
3771 
3772  char iline[1024];
3773  in.getline(iline,1024); // skip first line (header)
3774  while (1) {
3775 
3776  in.getline(iline,1024);
3777  if (!in.good()) break;
3778  TObjArray* tok = TString(iline).Tokenize(TString('|'));
3779 
3780  TObjString* tra = (TObjString*)tok->At(2);
3781  TObjString* tdec = (TObjString*)tok->At(3);
3782  TObjString* tdist = (TObjString*)tok->At(14);
3783 
3784  delete tok;
3785 
3786  double ra = tra->GetString().Atof();
3787  double dec = tdec->GetString().Atof();
3788  double dist = tdist->GetString().Atof(); // Mpc
3789 
3790  dist *= 1000; // Mpc -> Kpc
3791  if (dist<distance_thr) {
3792  thList.push_back(dec);
3793  phList.push_back(ra*360./24.);
3794  psiList.push_back(gRandom->Uniform(0,180));
3795  rhoList.push_back(dist);
3796 
3797  error=false;double iota = GetPar("iota",par,error);
3798  if(error) iotaList.push_back(0);
3799  else if(iota>=0&&iota<=180) iotaList.push_back(iota);
3800  else iotaList.push_back(rad2deg*acos(gRandom->Uniform(-1,1)));
3801 
3802  hrssList.push_back(0);
3803  IDList.push_back(-1);
3804  idList.push_back(-1);
3805  }
3806  }
3807 
3808  } else
3809  if(sky_distribution==MDC_CUSTOM) {
3810 
3811  cout << "CWB::mdc::SetSkyDistribution - User Custom Distribution" << endl;
3812 
3813  ifstream in;
3814  in.open(fName,ios::in);
3815  if (!in.good()) {cout << "CWB::mdc::SetSkyDistribution - Error Opening File : " << fName << endl;exit(1);}
3816 
3817  // get number of entries
3818  int entries=0;
3819  char str[1024];
3820  while(true) {
3821  in.getline(str,1024);
3822  if (!in.good()) break;
3823  if(str[0] != '#') entries++;
3824  }
3825  cout << "entries " << entries << endl;
3826  in.clear(ios::goodbit);
3827  in.seekg(0, ios::beg);
3828 
3829  char name[128];
3830  double gps,psi,rho,iota,hrss;
3831  double theta,phi; // geographic coordinates
3832  int ID,id;
3833  int fpos=0;
3834  while (1) {
3835  fpos=in.tellg();
3836  in.getline(str,1024);
3837  if(str[0] == '#') continue;
3838  if (!in.good()) break;
3839 
3840  std::stringstream linestream(str);
3841  if(!(linestream >> gps >> name >> theta >> phi >> psi >> rho >> iota >> hrss >> ID >> id)) {
3842  cout << "CWB::mdc::SetSkyDistribution - Wrong Format for File : " << fName << endl;
3843  cout << "input line : " << endl;
3844  cout << str << endl;
3845  cout << "must be : " << endl;
3846  cout << "gps " << "name " << "theta " << "phi " << "psi "
3847  << "rho " << "iota " << "hrss " << "ID " << "id " << "..." << endl;
3848  exit(1);
3849  }
3850  //cout << gps << " " << name << " " << theta << " " << phi << " " << psi
3851  // << " " << rho << " " << iota << " " << hrss << " " << ID << " " << id << endl;
3852 
3853  gpsList.push_back(gps);
3854  nameList.push_back(name);
3855  thList.push_back(theta);
3856  phList.push_back(phi);
3857  psiList.push_back(psi);
3858  rhoList.push_back(rho);
3859  iotaList.push_back(iota);
3860  hrssList.push_back(hrss);
3861  IDList.push_back(ID);
3862  idList.push_back(id);
3863  }
3864 
3865  in.close();
3866 
3867  } else
3868  if(sky_distribution==MDC_XMLFILE) {
3869 
3870 #ifdef _USE_LAL
3871  cout << "CWB::mdc::SetSkyDistribution - User Distribution from XML" << endl;
3872 
3873 #if LAL_VERSION_MAJOR > 6 || (LAL_VERSION_MAJOR == 6 && \
3874  (LAL_VERSION_MINOR > 14 || (LAL_VERSION_MINOR == 14 && \
3875  LAL_VERSION_MICRO >= 0 ))) // LAL_VERSION >= 6.14.0
3876 #else
3877  cout << "CWB::mdc::SetSkyDistribution - LAL XML File can not be used with LAL ver < 6.14.0" << endl;
3878  exit(1);
3879 #endif
3880 
3881  Long_t id,fsize,flags,mt;
3882  int estat = gSystem->GetPathInfo(fName.Data(),&id,&fsize,&flags,&mt);
3883  if (estat!=0) {
3884  cout << "CWB::mdc::SetSkyDistribution - XML File : " << fName.Data() << " Not Exist" << endl;
3885  exit(1);
3886  }
3887 
3888  bool error;
3889 
3890  // get decimals
3891  error=false;
3892  int decimals = GetPar("decimals",par,error);
3893  if(error) decimals=1;
3894 
3895  // get hrss_factor : is a user factor used to rescale hrss
3896  error=false;
3897  double hrss_factor = GetPar("hrss_factor",par,error);
3898  if(error) hrss_factor=1;
3899 
3900  // get mdc engine : aal=0, cwb=1 (default)
3901  error=false;
3902  int engine = GetPar("engine",par,error);
3903  if(error) engine=1;
3904 
3905  // get auto mode for MDC type : if auto=0 the MDC names must be provided by user
3906  error=false;
3907  int AUTO = GetPar("auto",par,error);
3908  if(error) AUTO=0;
3909 
3910  // get time range for injections
3911  error=false;
3912  double start = GetPar("start",par,error);
3913  if(error) start=0;
3914  error=false;
3915  double stop = GetPar("stop",par,error);
3916  if(error) stop=std::numeric_limits<double>::max();;
3917 
3918  xmlType.clear();
3919  if(!AUTO) { // get user defined xml types
3920  for(int n=0;n<par.size();n++) {
3921  error=false;
3922  vector<mdcpar> xpar(1); xpar[0]=par[n];
3923  TString type = GetParString("type",xpar,error);
3924  if(!error) { // add to xmlType if type is not present in the xmlType list
3925  bool present=false;
3926  for(int m=0;m<xmlType.size();m++) {
3927  if(type==xmlType[m]) {present=true;break;}
3928  }
3929  if(!present) xmlType.push_back(type.Data());
3930  }
3931  }
3932  }
3933 
3934  // read sim_burst table from XML file (see LIGOLwXMLBurstRead.c)
3935  LIGOTimeGPS gpsStartTime = {(int)start, 0};
3936  LIGOTimeGPS gpsStopTime = {(int)stop, 0};
3937  SimBurst* sim_burst = XLALSimBurstTableFromLIGOLw(fName.Data(),&gpsStartTime,&gpsStopTime);
3938  if(sim_burst==NULL) {
3939  cout << "CWB::mdc::SetSkyDistribution - XML File : " << fName.Data() << endl;
3940  cout << " No Events present in the range : " << (int)start << ":" << (int)stop <<endl;
3941  }
3942  skymap sm; // used to convert ra -> phi
3943  int sim_burst_index=0;
3944  for(; sim_burst; sim_burst = sim_burst->next) {
3945 
3946  sim_burst_index++;
3947 
3948  // the gps time of the injection corresponds to the sample at t=0
3949  // in the resultant time series. See XLALGenerateSimBurst in GenerateBurst.c
3950  double gps = sim_burst->time_geocent_gps.gpsSeconds;
3951  gps += 1.e-9*sim_burst->time_geocent_gps.gpsNanoSeconds;
3952 
3953  if(gps<start || gps>stop) continue; // skip if injection is not in the time range
3954 
3955  char name[128]= "";
3956 
3957  // read waveform parameters (see XLALWriteLIGOLwXMLSimBurstTable in LIGOLwXML.c)
3958  double phi = sm.RA2phi(rad2deg*sim_burst->ra,gps);
3959  double theta = rad2deg*(TMath::PiOver2()-sim_burst->dec);
3960  double psi = rad2deg*sim_burst->psi;
3961  double frequency = sim_burst->frequency;
3962  double Q = sim_burst->q;
3963  double duration = sim_burst->duration;
3964  double bandwidth = sim_burst->bandwidth;
3965  double rho = -1.; // rho<0 -> no hrss rescaling in GetBurst
3966  double phase = rad2deg*sim_burst->pol_ellipse_angle;
3967  double eccentricity = sim_burst->pol_ellipse_e;
3968  double hrss = sim_burst->hrss * hrss_factor;
3969  double amplitude = sim_burst->amplitude;
3970  double egw_over_rsquared = sim_burst->egw_over_rsquared;
3971  double waveform_number = sim_burst->waveform_number;
3972 
3973  // NOTE : iota is set to eccentricity but is not used because LAL implicity
3974  // apply with the parameter sim_burst->pol_ellipse_e
3975  // NOTE : CWB uses ellipticity, instead LAL uses eccentricity :
3976  // see XLALSimBurstSineGaussian in LALSimBurst.c
3977  // NOTE : the parameter phase is used by LAL to generate SG,CG waveforms
3978  // when random polarization is used the phase parameter is not effective
3979  // because the polarization angle is equivalent to the phase angle
3980 
3981  // eccentricity is saved in iota parameter, it is used in CWB::mdc::GetBurst
3982  double iota = eccentricity;
3983  //double cosi = e2cosi(eccentricity);
3984  //double iota = acos(cosi)*180./TMath::Pi();
3985 
3986  mdcid waveid;
3987  vector<mdcpar> wpar;
3988 
3989  // Convert LAL SimBurst defined in LALSimBurst.c into cWB MDC waveforms
3990  if(TString(sim_burst->waveform)=="Gaussian") {
3991 
3992  // add gaussian waveform
3993  wpar.resize(2);
3994  wpar[0].name="duration"; wpar[0].value=duration;
3995  wpar[1].name="decimals"; wpar[1].value=decimals;
3996  waveid = engine ? AddWaveform(MDC_GA, wpar) :
3997  AddWaveform(MDC_GA_LAL, sim_burst, wpar);
3998  sprintf(name,waveid.name.Data());
3999 
4000  } else
4001  if(TString(sim_burst->waveform)=="SineGaussian") {
4002 
4003  // add sinegaussian waveform
4004  wpar.resize(3);
4005  wpar[0].name="frequency"; wpar[0].value=frequency;
4006  wpar[1].name="Q"; wpar[1].value=Q;
4007  wpar[2].name="decimals"; wpar[2].value=decimals;
4008  waveid = engine ? AddWaveform(MDC_SGE, wpar) :
4009  AddWaveform(MDC_SGE_LAL, sim_burst, wpar);
4010  sprintf(name,waveid.name.Data());
4011 
4012  } else
4013  if(TString(sim_burst->waveform)=="BTLWNB") {
4014 
4015  // add whitenoiseburst waveform
4016  wpar.resize(7);
4017  wpar[0].name="frequency"; wpar[0].value=frequency;
4018  wpar[1].name="bandwidth"; wpar[1].value=bandwidth;
4019  wpar[2].name="duration"; wpar[2].value=duration;
4020  wpar[3].name="pseed"; wpar[3].value=seed+2*sim_burst_index;
4021  wpar[4].name="xseed"; wpar[4].value=seed+2*sim_burst_index+1;
4022  wpar[5].name="mode"; wpar[5].value=0; // asymmetric
4023  wpar[6].name="decimals"; wpar[6].value=decimals;
4024  waveid = engine ? AddWaveform(MDC_WNB, wpar) :
4025  AddWaveform(MDC_WNB_LAL, sim_burst, wpar);
4026  sprintf(name,waveid.name.Data());
4027 
4028  } else
4029  if(TString(sim_burst->waveform)=="StringCusp") {
4030 
4031  // add string cusp waveform
4032  wpar.resize(3);
4033  wpar[0].name="frequency"; wpar[0].value=frequency;
4034  wpar[1].name="amplitude"; wpar[1].value=amplitude;
4035  wpar[2].name="decimals"; wpar[2].value=decimals;
4036  waveid = AddWaveform(MDC_SC_LAL, sim_burst, wpar);
4037  sprintf(name,waveid.name.Data());
4038 
4039  }
4040 
4041  if(AUTO) {
4042  // fill xmlType
4043  for(int i=0;i<(int)wfList.size();i++) {
4044  bool save=true;
4045  for(int j=0; j<(int)xmlType.size(); j++){
4046  if(wfList[i].name.CompareTo(xmlType[j])==0) {save = false; break;}
4047  }
4048  if(save) {
4049  xmlType.push_back(wfList[i].name.Data());
4050  }
4051  }
4052  } else {
4053  // check if waveid.name is in the xmlType list
4054  bool present=false;
4055  for(int n=0;n<xmlType.size();n++) {
4056  if(waveid.name==xmlType[n]) {present=true;break;}
4057  }
4058  if(!present) {
4059  cout << "CWB::mdc::SetSkyDistribution - "
4060  << "Error : mdc type " << waveid.name << " is not in the xmlType list" << endl;
4061  cout<<endl<<"xmlType list : "<<endl<<endl;
4062  for(int n=0;n<xmlType.size();n++) {
4063  cout << "xmlType[" << n << "] : " << xmlType[n] << endl;
4064  }
4065  cout<<endl;
4066  exit(1);
4067  }
4068  }
4069 
4070  //cout.precision(3);
4071  //cout << (int)gps << " " << name << " th: " << theta << " ph: " << phi << " psi: " << psi
4072  // << " f: " << frequency << " Q: " << Q << " d: " << duration << " b: " << bandwidth
4073  // << " p:" << phase << " e: " << eccentricity << endl;
4074 
4075  // fill event parameter list
4076  gpsList.push_back(gps);
4077  nameList.push_back(name);
4078  thList.push_back(theta);
4079  phList.push_back(phi);
4080  psiList.push_back(psi);
4081  rhoList.push_back(rho);
4082  iotaList.push_back(iota);
4083  hrssList.push_back(hrss);
4084  IDList.push_back(waveid.ID);
4085  idList.push_back(waveid.id);
4086  }
4087 #else
4088  cout << "CWB::mdc::SetSkyDistribution - "
4089  << "Error : User Distribution from XML is enabled only with LAL" << endl;
4090  exit(1);
4091 #endif
4092 
4093  } else
4094  if((sky_distribution==MDC_EARTH_FIX)||
4095  (sky_distribution==MDC_CELESTIAL_FIX)) {
4096 
4097  bool error=false;
4098  bool gerror=false;
4099  double theta = GetPar("theta",par,error);
4100  if(gerror) gerror=error;
4101  double phi = GetPar("phi",par,error);
4102  if(gerror) gerror=error;
4103 
4104  if(gerror) {
4105  cout << "CWB::mdc::SetSkyDistribution - "
4106  << "Error : num par must be at least 2 [theta,phi,(psi,rho,gps)]" << endl;
4107  exit(1);
4108  }
4109 
4110  double value,psi,rho,iota,hrss;
4111  value=psi=rho=iota=0.;
4112  error=false;value=GetPar("entries",par,error);
4113  int entries = error ? 10000 : int(value);
4114  for(int n=0;n<entries;n++) {
4115  error=false;value=GetPar("psi",par,error);
4116  psi = error ? gRandom->Uniform(0,180) : value;
4117  error=false;value=GetPar("rho",par,error);
4118  rho = error ? 0. : value;
4119  error=false;value=GetPar("gps",par,error);
4120  if(!error) gpsList.push_back(value);
4121 
4122  error=false;iota = GetPar("iota",par,error);
4123  if(error) iotaList.push_back(0);
4124  else if(iota>=0&&iota<=180) iotaList.push_back(iota);
4125  else iotaList.push_back(rad2deg*acos(gRandom->Uniform(-1,1)));
4126 
4127  thList.push_back(theta);
4128  phList.push_back(phi);
4129  psiList.push_back(psi);
4130  rhoList.push_back(rho);
4131  hrssList.push_back(0);
4132  IDList.push_back(-1);
4133  idList.push_back(-1);
4134  }
4135  } else
4136  if(sky_distribution==MDC_LOGFILE) {
4137  if(net==NULL) {
4138  cout << "CWB::mdc::SetSkyDistribution - Error : Dummy method : network is not initialized " << endl;
4139  exit(1);
4140  }
4141  int nInj=net->readMDClog(const_cast<char*>(fName.Data()),0.);
4142  printf("CWB::mdc::SetSkyDistribution - injections loaded : %d\n",nInj);
4143  for(int k=0;k<nInj;k++) net->mdc__ID.push_back(k);
4144  size_t N = net->mdc__IDSize();
4145  size_t M = net->mdcTypeSize();
4146  cout << N << " " << M << endl;
4147  // fill mdcName vector with name of MDC (used in GetSourceList)
4148  mdcName.clear();
4149  for(int k=0;k<M;k++) mdcName.push_back(net->mdcType[k]);
4150  int nIFO=net->ifoListSize();
4151  inj = new injection(nIFO);
4152  inj_tree = inj->setTree();
4153  inj->output(inj_tree,net,1,false);
4154  delete inj;
4155  inj = new injection(inj_tree,nIFO);
4156  cout << "inj entries : " << inj->GetEntries() << endl;
4157  }
4158 
4159  return;
4160 }
4161 
4162 //______________________________________________________________________________
4163 void
4164 CWB::mdc::DrawSkyDistribution(TString name, TString projection, TString coordinate, double resolution, bool background) {
4165 //
4166 // Draw Sky Distribution
4167 //
4168 //
4169 // Input: name - unique name for canvas plot
4170 // projection - hammer, sinusoidal, parabolic
4171 // coordinate - geographic, celestial
4172 // resolution - default 2, define the resolution of pixels
4173 // background - false/true : if true draw a background color (blue)
4174 //
4175 
4176  if(psp!=NULL) delete psp;
4177  psp = new gskymap(0.4,0,180,0,360);
4178  psp->SetOptions(projection,coordinate,resolution/2);
4179 
4180  if(background) {
4181  psp->SetGridxColor(kWhite);
4182  psp->SetGridyColor(kWhite);
4183  } else {
4184  psp->SetGridxColor(kBlack);
4185  psp->SetGridyColor(kBlack);
4186  }
4187 // psp->SetGalacticDisk(true);
4188 // psp->SetGalacticDiskColor(kYellow);
4189 
4190  int entries=0;
4191  int size=360*2*resolution*180*2*resolution;
4193 
4194  double zmax=0.;
4196 
4197  if(inj_tree==NULL) {
4198  cout << "CWB::mdc::DrawSkyDistribution - Error : injection object is NULL" << endl;
4199  exit(1);
4200  }
4201 
4202  inj_tree->Draw("theta[0]:phi[0]:distance[0]:time[0]","","goff");
4203  entries = inj_tree->GetSelectedRows();
4204  size += entries;
4205  x.resize(size); y.resize(size); z.resize(size);
4206  double* theta = inj_tree->GetV1();
4207  double* phi = inj_tree->GetV2();
4208  double* distance = inj_tree->GetV3();
4209  double* gps = inj_tree->GetV4();
4210  coordinate.ToUpper();
4211  if(coordinate.CompareTo("CELESTIAL")==0) {
4212  for(int n=0;n<entries;n++) x[n] = sm.phi2RA(phi[n],gps[n]); // celestial 2 earth coordinates
4213  } else {
4214  for(int n=0;n<entries;n++) x[n] = phi[n];
4215  }
4216  for(int n=0;n<entries;n++) {
4217  y[n] = theta[n];
4218  z[n] = distance[n];
4219  if(zmax<z[n]) zmax=z[n];
4220  }
4221 
4222  } else {
4223  entries = (int)rhoList.size();
4224  size += entries;
4225  x.resize(size); y.resize(size); z.resize(size);
4226  for(int n=0;n<entries;n++) {
4227  x[n]=phList[n];
4228  y[n]=thList[n];
4229  z[n]=rhoList[n];
4230  if(zmax<z[n]) zmax=z[n];
4231  }
4232  }
4233 
4234  if(entries==0) {
4235  cout << "CWB::mdc::DrawSkyDistribution - Warning : no entries in sky distribution " << endl;
4236  exit(1);
4237  }
4238 
4239  size=entries;
4240  // add blue background
4241  if(background) {
4242  for (int i=0;i<360*2*resolution;i++) {
4243  for (int j=0;j<180*2*resolution;j++) {
4244  double ph = i/(double)(2*resolution);
4245  double th = j/(double)(2*resolution);
4246  x[size]=ph;
4247  y[size]=th;
4248  z[size]=zmax;
4249  size++;
4250  }
4251  }
4252  }
4253 
4254  // sort source respect to distance
4255  if(entries>1) {
4256  Int_t *index = new Int_t[size];
4257  TMath::Sort(size,z.data,index,true);
4258  wavearray<double> T(size);
4259  for (int i=0;i<size;i++) T[i]=x[index[i]];
4260  for (int i=0;i<size;i++) x[i]=T[i];
4261  for (int i=0;i<size;i++) T[i]=y[index[i]];
4262  for (int i=0;i<size;i++) y[i]=T[i];
4263  for (int i=0;i<size;i++) T[i]=z[index[i]];
4264  for (int i=0;i<size;i++) z[i]=T[i];
4265  T.resize(0);
4266  delete [] index;
4267  }
4268 
4269  psp->FillData(size, x.data, y.data, z.data);
4270 
4271  psp->SetZaxisTitle("Kpc");
4272  psp->Draw(-2);
4273 
4274  x.resize(0);
4275  y.resize(0);
4276  z.resize(0);
4277 
4278  return;
4279 }
4280 
4281 //______________________________________________________________________________
4282 TString
4283 CWB::mdc::WriteFrameFile(TString frDir, TString frLabel, size_t gps, size_t length, bool log, vector<TString> chName) {
4284 //
4285 // Write mdc to frame file
4286 //
4287 //
4288 // Input: frDir - output directory
4289 // frLabel - label used for output file name
4290 // file name path = frDir/network-frLabel-(gps/100000)/network-frLabel-gps.gwf
4291 // gps - time of frame (sec - integer)
4292 // length - time length of frame (sec - integer)
4293 // log - if 'true' then write log file
4294 // chName - channel name list, list size must be 0 or nIFO
4295 // if list size=0 then chName is IFO_NAME:GW-H
4296 // if list size=nIFO then is chName[n]="" then chName is IFO_NAME:GW-H
4297 //
4298 // Return log string
4299 //
4300 
4301  if(net==NULL) {
4302  cout << "CWB::mdc::WriteFrameFile - Error : Dummy method : network is not initialized " << endl;
4303  exit(1);
4304  }
4305 
4306  int nIFO=net->ifoListSize();
4307  char ifoLabel[64]="";
4308  for(int i=0;i<nIFO;i++) sprintf(ifoLabel,"%s%s",ifoLabel,net->ifoName[i]);
4309 
4310  // check input chName
4311  if(chName.size()!=0 && chName.size()!=nIFO) {
4312  cout << "CWB::mdc::WriteFrameFile - Error : chName list size must be equals to nIFO " << nIFO << endl;
4313  exit(1);
4314  }
4315 
4316  // make sub directory
4317  char sdir[64];
4318  sprintf(sdir,"%s-%s-%04d",ifoLabel,frLabel.Data(),int(gps/100000));
4319  char cmd[128];sprintf(cmd,"mkdir -p %s/%s",frDir.Data(),sdir);
4320  cout << cmd << endl;
4321  gSystem->Exec(cmd);
4322 
4323  char frFile[512];
4324  sprintf(frFile,"%s/%s/%s-%s-%lu-%lu.gwf",frDir.Data(),sdir,ifoLabel,frLabel.Data(),gps,length);
4325  cout << frFile << endl;
4326  FrFile *ofp = FrFileONew(frFile,1); // gzip compression
4327 
4328  /*----------------------- Create a new frame ---------*/
4329 
4330  FrameH* simFrame = FrameNew(const_cast<char*>(ifoLabel));
4331  simFrame->frame = 0;
4332  simFrame->run = -1;
4333  simFrame->dt = length;
4334  simFrame->GTimeS = gps;
4335  simFrame->GTimeN = 0;
4336 
4338  x.rate(MDC_SAMPLE_RATE);
4339  x.start(gps);
4340  char chNAME[64];
4341  for(int i=0;i<nIFO;i++) {
4342 
4343  TString ifo=net->ifoName[i];
4344  if(chName.size()) {
4345  if(chName[i]!="") sprintf(chNAME,"%s",chName[i].Data());
4346  else sprintf(chNAME,"%s:GW-H",net->ifoName[i]);
4347  } else {
4348  sprintf(chNAME,"%s:GW-H",net->ifoName[i]);
4349  }
4350 
4351  Get(x,ifo);
4352 
4353  cout << "Size (sec) " << x.size()/x.rate() << endl;
4354  FrProcData* proc = FrProcDataNew(simFrame,chNAME,x.rate(),x.size(),-64);
4355  if(proc == NULL) {cout << "CWB::mdc::WriteFrameFile - Cannot create FrProcData" << endl; exit(-1);}
4356  proc->timeOffset = 0;
4357  proc->tRange = simFrame->dt;
4358  proc->type = 1; // Time Serie
4359 
4360  for (int i=0;i<(int)proc->data->nData;i++) proc->data->dataD[i] = x[i];
4361  }
4362 
4363  int err=FrameWrite(simFrame,ofp);
4364  if (err) {cout << "CWB::mdc::WriteFrameFile - Error writing frame" << endl;exit(1);}
4365  FrameFree(simFrame);
4366 
4367  if (ofp!=NULL) FrFileOEnd(ofp);
4368 
4369 
4370  // log string
4371  TString logString = "";
4372  for(int i=0;i<(int)mdcList.size();i++) logString = logString+mdcList[i]+"\n";
4373 
4374  // write log file
4375  if(log) {
4376  TString logFile=frFile;
4377  logFile.ReplaceAll(".gwf","-Log.txt");
4378  DumpLog(logFile);
4379 /*
4380  ofstream out;
4381  out.open(logFile.Data(),ios::out);
4382  if (!out.good()) {cout << "CWB::mdc::WriteFrameFile - Error Opening File : " << logFile.Data() << endl;exit(1);}
4383  out.precision(14);
4384  for(int i=0;i<(int)mdcList.size();i++) out << mdcList[i] << endl;
4385  out.close();
4386 */
4387  }
4388 
4389  return logString;
4390 }
4391 
4392 //______________________________________________________________________________
4393 void
4395 //
4396 // Write waveform to file
4397 //
4398 //
4399 // Input: fname - output file name
4400 // ID - major id of waveform list
4401 // id - minor id of waveform list (Ex : the list WNB with different random waveforms)
4402 // polarization - hp/hx
4403 //
4404 
4405  polarization.ToUpper();
4406  waveform wf = GetWaveform(ID,id);
4407  if(wf.status) {
4408  if(polarization.Contains("HP")) Dump(fname, wf.hp);
4409  if(polarization.Contains("HX")) Dump(fname, wf.hx);
4410  }
4411  return;
4412 }
4413 
4414 //______________________________________________________________________________
4415 void
4417 //
4418 // Write waveform to file
4419 //
4420 //
4421 // Input: fname - output file name
4422 // name - name of waveform
4423 // id - minor id of waveform list (Ex : the list WNB with different random waveforms)
4424 // polarization - hp/hx
4425 //
4426 
4427  polarization.ToUpper();
4428  waveform wf = GetWaveform(name,id);
4429  if(wf.status) {
4430  if(polarization.Contains("HP")) Dump(fname, wf.hp);
4431  if(polarization.Contains("HX")) Dump(fname, wf.hx);
4432  }
4433  return;
4434 }
4435 
4436 //______________________________________________________________________________
4437 void
4439 //
4440 // Write waveform to file
4441 //
4442 //
4443 // Input: fname - output file name
4444 // x - wavearray which contains the waveform data
4445 //
4446 
4447  ofstream out;
4448  out.open(fname.Data(),ios::out);
4449  if (!out.good()) {cout << "CWB::mdc::WriteFrameFile - Error Opening File : " << fname.Data() << endl;exit(1);}
4450  out.precision(14);
4451  for(int i=0;i<(int)x.size();i++) out << x[i] << endl;
4452  out.close();
4453 
4454  return;
4455 }
4456 
4457 //______________________________________________________________________________
4458 void
4460 //
4461 // Write all waveform to file
4462 //
4463 //
4464 // Input: dname - output directory name
4465 // all file are written under dname
4466 //
4467 
4468  // create dir
4469  char cmd[256];
4470  sprintf(cmd,"mkdir -p %s",dname.Data());
4471  gSystem->Exec(cmd);
4472 
4473  char sid[8];
4474  for(int i=0;i<(int)wfList.size();i++) {
4475  //cout << "ID : " << i << "\t" << wfList[i].name.Data() << endl;
4476  Dump(dname+"/"+wfList[i].name+"~01.txt", i, 0, "hp");
4477  Dump(dname+"/"+wfList[i].name+"~02.txt", i, 0, "hx");
4478  printf("%s\n",TString(dname+"/"+wfList[i].name+"~01.txt").Data());
4479  printf("%s\n",TString(dname+"/"+wfList[i].name+"~02.txt").Data());
4480  for(int j=0;j<(int)wfList[i].list.size();j++) {
4481  //cout << " id : " << j+1 << "\t" << wfList[i].list[j].name.Data() << endl;
4482  sprintf(sid,"~%02d",2*(j+1)+1);
4483  Dump(dname+"/"+wfList[i].name+sid+".txt", i, j+1, "hp");
4484  printf("%s\n",TString(dname+"/"+wfList[i].name+sid+".txt").Data());
4485  sprintf(sid,"~%02d",2*(j+1)+1);
4486  Dump(dname+"/"+wfList[i].name+sid+".txt", i, j+1, "hx");
4487  printf("%s\n",TString(dname+"/"+wfList[i].name+sid+".txt").Data());
4488  }
4489  }
4490  return;
4491 }
4492 
4493 //______________________________________________________________________________
4494 double
4496 //
4497 // Get Antenna Pattern
4498 //
4499 //
4500 // Input: ifo - name of detector
4501 // phi - longitude (degrees)
4502 // theta - latitude (degrees)
4503 // psi - polarization (degrees)
4504 // polarization - hp/hx -
4505 //
4506 
4507  int nIFO = net ? net->ifoListSize() : 0;
4508 
4509  int ifoId=-1;
4510  detector* pD=NULL;
4511  for(int n=0; n<nIFO; n++) if(ifo.CompareTo(net->ifoName[n])==0) ifoId=n;
4512  if(ifoId>=0) pD = net->getifo(ifoId);
4513  else pD = new detector(const_cast<char*>(ifo.Data()));
4514 
4515  wavecomplex F = pD->antenna(theta,phi,psi);
4516  if(ifoId<0) delete pD;
4517  polarization.ToUpper();
4518  if(polarization.Contains("HP")) return F.real(); else return F.imag();
4519 }
4520 
4521 //______________________________________________________________________________
4522 double
4523 CWB::mdc::GetDelay(TString ifo1, TString ifo2, double phi, double theta) {
4524 //
4525 // Get Delay Traveling Time between two detectors
4526 //
4527 //
4528 // Input: ifo1 - name of the first detector
4529 // ifo2 - name of the second detector
4530 // if ifo2="" -> return ifo1 delay respect to geocenter
4531 // phi - longitude (degrees)
4532 // theta - latitude (degrees)
4533 //
4534 
4535  if(ifo1.CompareTo(ifo2)==0) return 0.0;
4536 
4537  int nIFO = net ? net->ifoListSize() : 0;
4538 
4539  int ifoId1=-1;
4540  detector* pD1=NULL;
4541  for(int n=0; n<nIFO; n++) if(ifo1.CompareTo(net->ifoName[n])==0) ifoId1=n;
4542  if(ifoId1>=0) pD1 = net->getifo(ifoId1);
4543  else pD1 = new detector(const_cast<char*>(ifo1.Data()));
4544 
4545  if(ifo2=="") {
4546  if(ifoId1<0) delete pD1;
4547  double delay = pD1->getTau(theta,phi);
4548  return delay; // return Delay Traveling Time between ifo1 and geocenter
4549  }
4550 
4551  int ifoId2=-1;
4552  detector* pD2=NULL;
4553  for(int n=0; n<nIFO; n++) if(ifo2.CompareTo(net->ifoName[n])==0) ifoId2=n;
4554  if(ifoId2>=0) pD2 = net->getifo(ifoId2);
4555  else pD2 = new detector(const_cast<char*>(ifo2.Data()));
4556 
4557  double delay = pD1->getTau(theta,phi)-pD2->getTau(theta,phi);
4558 
4559  if(ifoId1<0) delete pD1;
4560  if(ifoId2<0) delete pD2;
4561 
4562  return delay; // return Delay Traveling Time between ifo1 and ifo2
4563 }
4564 
4565 //______________________________________________________________________________
4566 void
4568 //
4569 // Dump log header to file
4570 //
4571 //
4572 // Input: fName - name of output file
4573 // label - label of file
4574 // size - number of mdc - if size<=0 use inj tree
4575 //
4576 
4577  if(size<=0 && inj==NULL) {
4578  cout << "CWB::mdc::DumpLogHeader - Error : dump needs injection object " << endl;
4579  exit(1);
4580  }
4581 
4582  // WRITE field headings to log file
4583 
4584  ofstream out;
4585  out.open(fName.Data(),ios::out);
4586  if (!out.good()) {cout << "CWB::mdc::DumpLogHeader - Error Opening File : " << fName.Data() << endl;exit(1);}
4587 
4588  int nIFO=net->ifoListSize();
4589 
4590  out << "# Log File for Burst " << label.Data() << endl;
4591  out << "# Produced by CWB::mdc " << wat::Time("now").GetDateString().Data() << endl;
4592  out << "# The following detectors were simulated" << endl;
4593  for(int n=0;n<nIFO;n++) out << "# - " << net->ifoName[n] << endl;
4594  if(size>0) {
4595  out << "# There were " << size << " injections" << endl;
4596  } else {
4597  out << "# There were " << net->mdcList.size() << " injections" << endl;
4598 // for(int i=0;i<(int)wfList.size();i++) {
4599 // out << "# Burst MDC Sim type " << wfList[i].name.Data() << endl;
4600 // }
4601  for(int i=0;i<(int)net->mdcType.size();i++) {
4602  char cut[16];sprintf(cut,"type==%d",i+1);
4603  inj_tree->Draw("type",cut,"goff");
4604  int ninj = inj_tree->GetSelectedRows();
4605  out << "# Burst MDC Sim type " << net->mdcType[i].data() << "\t occurred " << ninj << " times" << endl;
4606  }
4607  }
4608 
4609  out << "# GravEn_SimID SimHrss SimEgwR2 GravEn_Ampl ";
4610  out << "Internal_x Internal_phi ";
4611  out << "External_x External_phi External_psi ";
4612  out << "FrameGPS EarthCtrGPS SimName SimHpHp SimHcHc SimHpHc ";
4613  for(int n=0;n<nIFO;n++) {
4614  out << net->ifoName[n] << " " <<
4615  net->ifoName[n] << "ctrGPS " <<
4616  net->ifoName[n] << "fPlus " <<
4617  net->ifoName[n] << "fCross ";
4618  }
4619  out << endl;
4620 
4621  out.close();
4622 
4623  return;
4624 }
4625 
4626 #ifdef _USE_LAL
4627 //______________________________________________________________________________
4628 void
4629 CWB::mdc::CreateBurstXML(TString fName, vector<mdcpar> xml_parms) {
4630 //
4631 // Create XML file : Create XML LAL file + Add Header
4632 // see LAL LIGOLwXML.c
4633 //
4634 // Input: fName - name of the xml output file
4635 // xml_parms - contains custom auxiliary parameters to be added to the parameter table
4636 //
4637 
4638  if(inspName!="") {
4639  cout << "CWB::mdc::CreateBurstXML : Error : This function is allowed only for Burst !!!" << endl;
4640  exit(1);
4641  }
4642 
4643  if(xml_filename!="") {
4644  cout << "CWB::mdc::CreateBurstXML : Error : file XML already opened !!!" << endl;
4645  exit(1);
4646  }
4647 
4648  bool error=false;
4649  // extract start_time - start GPS time of interval in which to synthesize injections
4650  double start_time = GetPar("start_time",xml_parms,error); if(error) start_time = 0;
4651  // extract end_time - end GPS time of interval in which to synthesize injections
4652  double end_time = GetPar("end_time",xml_parms,error); if(error) end_time = 0;
4653 
4654  xml_filename = fName;
4655  xml_process_table_head = NULL;
4656  xml_process_params_table_head = NULL;
4657  xml_search_summary_table_head = NULL;
4658  xml_time_slide_table_head = NULL;
4659  xml_sim_burst_table_head = NULL;
4660  xml_sim_burst = &xml_sim_burst_table_head;
4661 
4662  TString ifos="";
4663  if(net!=NULL) for(int n=0;n<(int)net->ifoListSize();n++) ifos+=net->getifo(n)->Name+TString(",");
4664  if(ifos!="") ifos.Resize(ifos.Sizeof()-2);
4665 
4666  // Fill Process table
4667  xml_process_table_head = xml_process = XLALCreateProcessTableRow();
4668  sprintf(xml_process->program, "cWB"); // program name entry
4669  XLALGPSTimeNow(&xml_process->start_time); // start time
4670  sprintf(xml_process->version, watversion('r')); // git version
4671  sprintf(xml_process->cvs_repository, "https://git.ligo.org/cWB/library/");
4672  char cmd_line[2048]="";
4673  for(int i=0;i<gApplication->Argc();i++) sprintf(cmd_line,"%s %s",cmd_line,gApplication->Argv(i));
4674  sprintf(xml_process->comment, cmd_line); // save command line used to start the application
4675  sprintf(xml_process->domain, "cWB"); // online flag and domain
4676  // unix process id, username, host, and process_id
4677  UserGroup_t* uinfo = gSystem->GetUserInfo();
4678  xml_process->unix_procid = gSystem->GetPid();
4679  sprintf(xml_process->node, gSystem->HostName());
4680  sprintf(xml_process->username, uinfo->fUser);
4681  sprintf(xml_process->ifos,ifos.Data());
4682  xml_process->process_id = 0;
4683 
4684  // Fill Process parameter table
4685  ProcessParamsTable **paramaddpoint = &xml_process_params_table_head;
4686  if(net!=NULL) for(int n=0;n<(int)net->ifoListSize();n++) {
4687  ADD_PROCESS_PARAM(paramaddpoint, xml_process, "string", "instrument", net->getifo(n)->Name);
4688  }
4689  ADD_PROCESS_PARAM(paramaddpoint, xml_process, "double", "inj-hrss",
4690  TString::Format("%f",GetInjHrss()).Data());
4691  ADD_PROCESS_PARAM(paramaddpoint, xml_process, "double", "time-step",
4692  TString::Format("%f",1./GetInjRate()).Data());
4693  ADD_PROCESS_PARAM(paramaddpoint, xml_process, "double", "jitter",
4694  TString::Format("%f",GetInjJitter()).Data());
4695  ADD_PROCESS_PARAM(paramaddpoint, xml_process, "enum", "sky-distribution",
4697  ADD_PROCESS_PARAM(paramaddpoint, xml_process, "string", "sky-file", sky_file.Data());
4698  for(int i=0;i<sky_parms.size();i++) {
4699  ADD_PROCESS_PARAM(paramaddpoint, xml_process, "double",
4700  sky_parms[i].name.Data(), TString::Format("%f",sky_parms[i].value).Data());
4701  }
4702  for(int i=0;i<xml_parms.size();i++) {
4703  if(xml_parms[i].svalue!="") {
4704  ADD_PROCESS_PARAM(paramaddpoint, xml_process, "string",
4705  xml_parms[i].name.Data(), xml_parms[i].svalue.Data());
4706  } else {
4707  ADD_PROCESS_PARAM(paramaddpoint, xml_process, "double",
4708  xml_parms[i].name.Data(), TString::Format("%f",xml_parms[i].value).Data());
4709  }
4710  }
4711 
4712  // Fill Search summary table
4713  xml_search_summary_table_head = xml_search_summary = XLALCreateSearchSummaryTableRow(xml_process);
4714  sprintf(xml_search_summary->comment, "");
4715  sprintf(xml_search_summary->ifos,ifos.Data());
4716  xml_search_summary->nnodes = 1;
4717  wat::Time in_start_time(start_time);
4718  xml_search_summary->in_start_time.gpsSeconds = in_start_time.GetSec();
4719  xml_search_summary->in_start_time.gpsNanoSeconds = in_start_time.GetNSec();
4720  xml_search_summary->out_start_time.gpsSeconds = in_start_time.GetSec();
4721  xml_search_summary->out_start_time.gpsNanoSeconds = in_start_time.GetNSec();
4722  wat::Time in_end_time(end_time);
4723  xml_search_summary->in_end_time.gpsSeconds = in_end_time.GetSec();
4724  xml_search_summary->in_end_time.gpsNanoSeconds = in_end_time.GetNSec();
4725  xml_search_summary->out_end_time.gpsSeconds = in_end_time.GetSec();
4726  xml_search_summary->out_end_time.gpsNanoSeconds = in_end_time.GetNSec();
4727 
4728 }
4729 #endif
4730 
4731 #ifdef _USE_LAL
4732 //______________________________________________________________________________
4733 void
4734 CWB::mdc::FillBurstXML(bool verbose) {
4735 //
4736 // Fill XML LAL to file with event parameters
4737 //
4738 // NOTE : this function can be used only afer CreateBurstXML
4739 //
4740 
4741  if(xml_filename=="") {
4742  cout << "CWB::mdc::FillBurstXML : Error : file XML not declared !!! use CreateBurstXML" << endl;
4743  exit(1);
4744  }
4745 
4746  double NaN = std::numeric_limits<double>::quiet_NaN();
4747  const double deg2rad = TMath::Pi()/180.;
4748 
4749  if(verbose) {
4750  cout << "gps" << "\t\t" << "wf-name" << "\t\t\t" << "theta" << "\t" << "phi" << "\t" << "psi"
4751  << "\t" << "rho" << "\t" << "iota" << "\t" << "hrss" << "\t" << "ID" << "\t" << "id" << endl;
4752  }
4753 
4754  bool error=false;
4755  for(int i=0;i<(int)srcList.size();i++) {
4756  waveform wf = GetWaveform(srcList[i].ID, srcList[i].id);
4757  double hrss = srcList[i].hrss>0 ? srcList[i].hrss : inj_hrss;
4758  if(verbose) {
4759  cout << std::setprecision(13) << srcList[i].gps << "\t" << std::setprecision(6)
4760  << wf.name.Data() << "\t" << srcList[i].theta << "\t"
4761  << srcList[i].phi << "\t" << srcList[i].psi << "\t" << srcList[i].rho << "\t"
4762  << srcList[i].iota << "\t" << hrss << "\t" << srcList[i].ID << "\t" << srcList[i].id << endl;
4763  }
4764 
4765  SimBurst *sim_burst = XLALCreateSimBurst();
4766  if(!sim_burst) {*xml_sim_burst=NULL; return;}
4767 
4768  // fill sim_burst structure
4769  strcpy(sim_burst->waveform, wf.name.Data());
4770 
4771  wat::Time time(srcList[i].gps);
4772  sim_burst->time_geocent_gps.gpsSeconds = time.GetSec();
4773  sim_burst->time_geocent_gps.gpsNanoSeconds = time.GetNSec();
4774 
4775  sim_burst->ra = deg2rad*sm.phi2RA(srcList[i].phi,srcList[i].gps);
4776  sim_burst->dec = TMath::PiOver2()-deg2rad*srcList[i].theta;
4777  sim_burst->psi = deg2rad*srcList[i].psi;
4778  error=false;
4779  sim_burst->frequency = GetPar("frequency",wf.par,error);if(error) sim_burst->frequency=NaN;
4780  error=false;
4781  sim_burst->q = GetPar("Q",wf.par,error); if(error) sim_burst->q=NaN;
4782  error=false;
4783  sim_burst->duration = GetPar("duration",wf.par,error); if(error) sim_burst->duration=NaN;
4784  error=false;
4785  sim_burst->bandwidth = GetPar("bandwidth",wf.par,error);if(error) sim_burst->bandwidth=NaN;
4786  sim_burst->pol_ellipse_angle = 0;
4787  sim_burst->pol_ellipse_e = cos(deg2rad*srcList[i].iota);
4788  sim_burst->hrss = hrss;
4789  sim_burst->amplitude = 0;
4790  sim_burst->egw_over_rsquared = 0;
4791  sim_burst->waveform_number = srcList[i].ID;
4792 
4793  *xml_sim_burst = sim_burst;
4794  xml_sim_burst = &(*xml_sim_burst)->next;
4795  }
4796 
4797 }
4798 #endif
4799 
4800 #ifdef _USE_LAL
4801 //______________________________________________________________________________
4802 void
4803 CWB::mdc::CloseBurstXML() {
4804 //
4805 // Close XML LAL file
4806 //
4807 // NOTE : this function can be used only afer CreateBurstXML
4808 //
4809 
4810  if(xml_filename=="") {
4811  cout << "CWB::mdc::CloseBurstXML : Error : file XML not declared !!! use CreateBurstXML" << endl;
4812  exit(1);
4813  }
4814 
4815  XLALGPSTimeNow(&xml_process->end_time);
4816 
4817  // write xml file (see LAL binj.c)
4818  LIGOLwXMLStream *xml;
4819 
4820  xml = XLALOpenLIGOLwXMLFile(xml_filename.Data());
4821 
4822  /* process table */
4823  if(XLALWriteLIGOLwXMLProcessTable(xml, xml_process_table_head)) {
4824  cout << "CWB::mdc::CloseBurstXML : Error in XLALWriteLIGOLwXMLProcessTable" << endl;
4825  exit(1);
4826  }
4827  /* process params table */
4828  if(XLALWriteLIGOLwXMLProcessParamsTable(xml, xml_process_params_table_head)) {
4829  cout << "CWB::mdc::CloseBurstXML : Error in XLALWriteLIGOLwXMLProcessParamsTable" << endl;
4830  exit(1);
4831  }
4832  /* search summary table */
4833  if(XLALWriteLIGOLwXMLSearchSummaryTable(xml, xml_search_summary_table_head)) {
4834  cout << "CWB::mdc::CloseBurstXML : Error in XLALWriteLIGOLwXMLSearchSummaryTable" << endl;
4835  exit(1);
4836  }
4837  /* time slide table */
4838  if(XLALWriteLIGOLwXMLTimeSlideTable(xml, xml_time_slide_table_head)) {
4839  cout << "CWB::mdc::CloseBurstXML : Error in XLALWriteLIGOLwXMLTimeSlideTable" << endl;
4840  exit(1);
4841  }
4842  /* sim burst table */
4843  if(XLALWriteLIGOLwXMLSimBurstTable(xml, xml_sim_burst_table_head)) {
4844  cout << "CWB::mdc::CloseBurstXML : Error in XLALWriteLIGOLwXMLSimBurstTable" << endl;
4845  exit(1);
4846  }
4847 
4848  XLALCloseLIGOLwXMLFile(xml);
4849 
4850  xml_filename = "";
4851  XLALDestroyProcessTable(xml_process_table_head);
4852  XLALDestroyProcessParamsTable(xml_process_params_table_head);
4853  XLALDestroyTimeSlideTable(xml_time_slide_table_head);
4854  XLALDestroySearchSummaryTable(xml_search_summary_table_head);
4855  XLALDestroySimBurstTable(xml_sim_burst_table_head);
4856 }
4857 #endif
4858 
4859 #ifdef _USE_LAL
4860 //______________________________________________________________________________
4861 TString
4862 CWB::mdc::GetBurstNameLAL(TString options) {
4863 //
4864 // convert LAL Burst options to the name used in mdc class
4865 //
4866 // options : --name Gaussian --duration value
4867 // options : --name SineGaussian --frequency value --q value
4868 // options : --name BTLWNB --frequency value --bandwidth value --duration value
4869 // options : --name StringCusp --frequency value
4870 //
4871 // --decimals value number of decimals used to format the waveform name
4872 // if not defined ; used default format
4873 //
4874 
4875  TString wfname = "";
4876 
4877  CWB::Toolbox TB;
4878  TString name = TB.getParameter(options,"--name");
4879  bool error=false;
4880  if(name=="") error=true;
4881  if((name=="Gaussian")&&(name!="SineGaussian")&&(name=="BTLWNB")) error=true;
4882  if(error) {
4883  cout << "CWB::mdc::GetBurstNameLAL : Error - Not valid --name option" << endl;
4884  cout << "available --name options are : Gaussian/SineGaussian/BTLWNB" << endl;
4885  return "";
4886  }
4887 
4888  // get number of decimals to be used to format the waveform name
4889  int decimals = -1;
4890  TString sdecimals = TB.getParameter(options,"--decimals");
4891  if(sdecimals.IsDigit()) decimals = sdecimals.Atoi();
4892 
4893  if(name=="Gaussian") {
4894 
4895  int d1 = decimals==-1 ? 1 : decimals;
4896 
4897  float duration;
4898  TString sduration = TB.getParameter(options,"--duration");
4899  if(sduration.IsFloat()) {
4900  duration = sduration.Atof();
4901  } else {
4902  cout << "CWB::mdc::GetBurstNameLAL : Error : --duration not defined or not a number!!! " << endl;
4903  return "";
4904  }
4905 
4906  wfname = TString::Format("LAL_GA%.*f",d1,1000.*duration);
4907  wfname.ReplaceAll(".","d");
4908  return wfname;
4909 
4910  } else if(name=="SineGaussian") {
4911 
4912  int d1 = decimals==-1 ? 0 : decimals;
4913  int d2 = decimals==-1 ? 1 : decimals;
4914 
4915  float frequency;
4916  TString sfrequency = TB.getParameter(options,"--frequency");
4917  if(sfrequency.IsFloat()) {
4918  frequency = sfrequency.Atof();
4919  } else {
4920  cout << "CWB::mdc::GetBurstNameLAL : Error : --frequency not defined or not a number!!! " << endl;
4921  return "";
4922  }
4923 
4924  float q;
4925  TString sq = TB.getParameter(options,"--q");
4926  if(sq.IsFloat()) {
4927  q = sq.Atof();
4928  } else {
4929  cout << "CWB::mdc::GetBurstNameLAL : Error : --q not defined or not a number!!! " << endl;
4930  return "";
4931  }
4932 
4933  wfname = TString::Format("LAL_SGE%.*fQ%.*f",d1,frequency,d2,q);
4934  wfname.ReplaceAll(".","d");
4935  if(decimals==-1) wfname.ReplaceAll("d0","");
4936  return wfname;
4937 
4938  } else if(name=="BTLWNB") {
4939 
4940  int d1 = decimals==-1 ? 0 : decimals;
4941  int d2 = decimals==-1 ? 0 : decimals;
4942  int d3 = decimals==-1 ? 3 : decimals;
4943 
4944  float frequency;
4945  TString sfrequency = TB.getParameter(options,"--frequency");
4946  if(sfrequency.IsFloat()) {
4947  frequency = sfrequency.Atof();
4948  } else {
4949  cout << "CWB::mdc::GetBurstNameLAL : Error : --frequency not defined or not a number!!! " << endl;
4950  return "";
4951  }
4952 
4953  float bandwidth;
4954  TString sbandwidth = TB.getParameter(options,"--bandwidth");
4955  if(sbandwidth.IsFloat()) {
4956  bandwidth = sbandwidth.Atof();
4957  } else {
4958  cout << "CWB::mdc::GetBurstNameLAL : Error : --bandwidth not defined or not a number!!! " << endl;
4959  return "";
4960  }
4961 
4962  float duration;
4963  TString sduration = TB.getParameter(options,"--duration");
4964  if(sduration.IsFloat()) {
4965  duration = sduration.Atof();
4966  } else {
4967  cout << "CWB::mdc::GetBurstNameLAL : Error : --duration not defined or not a number!!! " << endl;
4968  return "";
4969  }
4970 
4971  wfname = TString::Format("LAL_WNB%.*f_%.*f_%.*f",d1,frequency,d2,bandwidth,d3,duration);
4972  wfname.ReplaceAll(".","d");
4973  return wfname;
4974 
4975  } else if(name=="StringCusp") {
4976 
4977  int d1 = decimals==-1 ? 1 : decimals;
4978 
4979  float frequency;
4980  TString sfrequency = TB.getParameter(options,"--frequency");
4981  if(sfrequency.IsFloat()) {
4982  frequency = sfrequency.Atof();
4983  } else {
4984  cout << "CWB::mdc::GetBurstNameLAL : Error : --frequency not defined or not a number!!! " << endl;
4985  return "";
4986  }
4987 
4988  wfname = TString::Format("LAL_SC%.*f",d1,1000.*frequency);
4989  wfname.ReplaceAll(".","d");
4990  return wfname;
4991 
4992  }
4993 
4994  return wfname;
4995 }
4996 #endif
4997 
4998 //______________________________________________________________________________
4999 double
5001 //
5002 // convert the LAL eccentricity used to generate SineGaussian waveform into the
5003 // equivalent iota value
5004 //
5005 // e : eccentricity [0:1]
5006 //
5007 // return the cos(iota) value
5008 //
5009 // CWB uses the following formula :
5010 // h_+ = 0.5*(1+cos(iota)^2) * A(t) cos(Phi(t))
5011 // h_x = cos(iota) * A(t) sin(Phi(t))
5012 // while LAL uses :
5013 // h_+ = A * A(t) cos(Phi(t))
5014 // h_x = B * A(t) sin(Phi(t))
5015 // where :
5016 // A = 1/sqrt(2-E*E) ; B = A*sqrt(1-E*E)
5017 // and E is the eccentricity
5018 // it follows that A*A+B*B=1
5019 //
5020 
5021  if(e<0 || e>1) {
5022  cout << "CWB::mdc::e2cosi - Error : eccentricity must be defined in the range [0:1] " << endl;
5024  }
5025 
5026  double E = e<0.9999999999 ? e : 0.9999999999; // avoid x1,x2=nan
5027  double A = 1./sqrt(2-E*E);
5028  double B = A*sqrt(1-E*E);
5029  double x1 = (A+sqrt(A*A-B*B))/(B*B);
5030  double x2 = (A-sqrt(A*A-B*B))/(B*B);
5031  double x = fabs(x1*B)>1 ? x2 : x1;
5032 
5033  double cosi = -x*B;
5034 
5035  return cosi;
5036 }
5037 
5038 //______________________________________________________________________________
5039 double
5040 CWB::mdc::cosi2e(double cosi) {
5041 //
5042 // convert cos(iota) into the equivalent LAL eccentricity used
5043 // to generate SineGaussian waveform
5044 //
5045 // cosi : cos(iota) [-1:1]
5046 //
5047 // return the eccentricity value
5048 //
5049 
5050  if(fabs(cosi)>1) {
5051  cout << "CWB::mdc::cosi2e - Error : cosi must be defined in the range [-1:1] " << endl;
5053  }
5054 
5055  double A = (1+cosi*cosi)/2;
5056  double B = -cosi;
5057 
5058  double C = sqrt(A*A+B*B);
5059  A/=C; B/=C;
5060 
5061  double E = sqrt(1-(B*B)/(A*A));
5062 
5063  return E;
5064 }
5065 
5066 //______________________________________________________________________________
5067 void
5069 //
5070 // Dump log to file
5071 //
5072 //
5073 // Input: fName - name of output file
5074 // label - label of file
5075 // append - false/true -> create new file/append to the file
5076 //
5077 
5078  if(fName.Contains(".root")) {
5079 
5080  if(inj==NULL) {
5081  cout << "CWB::mdc::DumpLog - Error : dump to root needs injection object " << endl;
5082  exit(1);
5083  }
5084 
5085  TFile froot(fName,"RECREATE");
5086  if(label.Sizeof()>1) this->Write(label); else this->Write("WaveMDC");
5087  inj_tree->Write();
5088  cout << "CWB::mdc::DumpLog - inj entries written : " << inj_tree->GetEntries() << endl;
5089  froot.Write();
5090  froot.Close();
5091 
5092  } else
5093  if(fName.Contains(".txt")) {
5094 
5095  // log string
5096  TString logString = "";
5097  for(int i=0;i<(int)mdcList.size();i++) logString = logString+mdcList[i]+"\n";
5098 
5099  // write log file
5100  ofstream out;
5101  if(append) out.open(fName.Data(),ios::app);
5102  else out.open(fName.Data(),ios::out);
5103  if (!out.good()) {cout << "CWB::mdc::DumpLog - Error Opening File : " << fName.Data() << endl;exit(1);}
5104  out.precision(14);
5105  for(int i=0;i<(int)mdcList.size();i++) out << mdcList[i] << endl;
5106  out.close();
5107 
5108  } else
5109  if(fName.Contains(".lst")) {
5110 
5111  // write source list file
5112  ofstream out;
5113  if(append) out.open(fName.Data(),ios::app);
5114  else out.open(fName.Data(),ios::out);
5115  if (!out.good()) {cout << "CWB::mdc::DumpLog - Error Opening File : " << fName.Data() << endl;exit(1);}
5116  out.precision(14);
5117  out << "#gps\t\t" << "name\t\t" << "theta\t" << "phi\t" << "psi\t"
5118  << "rho\t" << "iota\t" << "hrss\t" << "ID\t" << "id\t" << endl;
5119  for(int i=0;i<(int)srcList.size();i++) {
5120  waveform wf = GetWaveform(srcList[i].ID, srcList[i].id);
5121  double hrss = srcList[i].hrss>0 ? srcList[i].hrss : inj_hrss;
5122  out << srcList[i].gps << "\t" << wf.name.Data() << "\t" << srcList[i].theta << "\t"
5123  << srcList[i].phi << "\t" << srcList[i].psi << "\t" << srcList[i].rho << "\t"
5124  << srcList[i].iota << "\t" << hrss << "\t" << srcList[i].ID << "\t" << srcList[i].id << endl;
5125  }
5126  out.close();
5127 
5128  } else {
5129  cout << "CWB::mdc::DumpLog - Error : file extention must be .root" << endl;
5130  exit(1);
5131  }
5132 
5133  return;
5134 }
5135 
5136 #ifdef _USE_LAL
5137 //______________________________________________________________________________
5138 TString
5139 CWB::mdc::GetInspiral(wavearray<double>& x, TString ifo) {
5140 //
5141 // Get inspiral mdc data of the detector = ifo
5142 //
5143 //
5144 // Input: x - the input start/stop gps time are obtained from the wavearray values
5145 // start = x.start(); stop = x.start()+x.size()/x.rate()
5146 // ifo - name of the detector defined in the network
5147 //
5148 // Output: x - x.data contains the mdc data
5149 //
5150 // Return: log - ascii string with mdc parameters
5151 //
5152 
5153  if(net==NULL) {
5154  cout << "CWB::mdc::GetInspiral - Error : Dummy method : network is not initialized " << endl;
5155  exit(1);
5156  }
5157  if(x.rate()!=MDC_SAMPLE_RATE) {
5158  cout << "CWB::mdc::GetInspiral - Error : x.rate() != " << MDC_SAMPLE_RATE << endl;
5159  exit(1);
5160  }
5161 
5162  x=0.;
5163 
5164  // start/end times
5165  int gpsStartSec = x.start();
5166  int gpsEndSec = gpsStartSec + x.size()/x.rate();
5167 
5168  // injections
5169  INT4 numInjections = 0;
5170  SimInspiralTable *injections = NULL;
5171  TString injectionFile = GenInspiralXML(0., 0., false);
5172 
5173  // set default debug level
5174  lal_errhandler = LAL_ERR_EXIT;
5175 
5176  XLALSetSilentErrorHandler();
5177 
5178  // read the injections
5179  numInjections = SimInspiralTableFromLIGOLw(&injections, injectionFile.Data(), gpsStartSec, gpsEndSec);
5180 
5181  if ( numInjections == 0 ) {
5182  fprintf( stderr, "CWB::mdc::GetInspiral - Warning : No injections in specified time\n");
5183  return "";
5184  } else {
5185  fprintf( stdout, "CWB::mdc::GetInspiral : Read %d injection(s) from the file '%s'\n",
5186  numInjections, injectionFile.Data() );
5187  }
5188 
5189  // reset lists
5190  mdcList.clear();
5191  mdcType.clear();
5192  mdcTime.clear();
5193 
5194  fprintf(stdout, "CWB::mdc::GetInspiral : Generating injection for: %s",ifo.Data());
5195 
5196  FindChirpInjectSignals(x, injections, ifo);
5197 
5198  fprintf(stdout, "\n");
5199 
5200  // loop over injections
5201  SimInspiralTable *thisInj = NULL;
5202  for (thisInj = injections; thisInj; thisInj = thisInj->next)
5203  {
5204  // add waveform log string to mdc log string
5205  TString log = GetInspiralLog(inspName,x.start(),thisInj);
5206  //cout << "LOG : " << log.Data() << endl;
5207 
5208  // add infos to lists
5209  mdcList.push_back(log.Data());
5210  double gps = thisInj->geocent_end_time.gpsSeconds+1.e-9*thisInj->geocent_end_time.gpsNanoSeconds;
5211  mdcTime.push_back(gps);
5212  }
5213  mdcType.push_back(inspName.Data());
5214 
5215  if(inspXML=="") gSystem->Exec(TString("rm ")+injectionFile); // remove injectionFile file
5216 
5217  while ( injections ) {
5218  SimInspiralTable *thisInj = NULL;
5219  thisInj = injections;
5220  injections = injections->next;
5221  LALFree( thisInj );
5222  }
5223 
5224  LALCheckMemoryLeaks();
5225  return "";
5226 }
5227 #endif
5228 
5229 #ifdef _USE_LAL
5230 //______________________________________________________________________________
5231 TString
5232 CWB::mdc::GetInspiralLog(TString inspName, double FrameGPS, SimInspiralTable *thisInj) {
5233 //
5234 // Get Log string for inspiral mdc
5235 //
5236 // Input: inspName - name of inspiral
5237 // FrameGPS - Frame gps time
5238 // thisInj - List of waveform parameters
5239 //
5240 
5241  if(net==NULL) {
5242  cout << "CWB::mdc::GetInspiralLog - Error : Dummy method : network is not initialized " << endl;
5243  exit(1);
5244  }
5245 
5246  // network ifos
5247  INT4 nIFO=net->ifoListSize();
5248 
5249  // declare variables
5250  float f_isco;
5251  REAL8 gmst;
5252  REAL8 longitude;
5253  char output[2048]="";
5254 
5255  // GravEn_SimID
5256  if (strncmp(thisInj->waveform, "NumRel", LIGOMETA_WAVEFORM_MAX) == 0)
5257  sprintf(output, "%s ", thisInj->numrel_data);
5258  else
5259  sprintf(output, "file ");
5260  // GravEn_Ampl
5261  sprintf(output, "%s 1 ",output);
5262  // StartSamp1
5263  sprintf(output, "%s 0 ",output);
5264  // StartSamp2
5265  sprintf(output, "%s 0 ",output);
5266  // Internal_x
5267  sprintf(output, "%s %g ",output, cos(thisInj->inclination));
5268  // Internal_phi
5269  sprintf(output, "%s %g ",output, thisInj->coa_phase);
5270  // External_x
5271  sprintf(output, "%s %g ",output, cos(thisInj->latitude - LAL_PI_2));
5272  // External_phi
5273  gmst = fmod(XLALGreenwichMeanSiderealTime(&thisInj->geocent_end_time), LAL_TWOPI);
5274  longitude = fmod(thisInj->longitude - gmst, LAL_TWOPI);
5275  if (longitude < 0)
5276  longitude += LAL_TWOPI;
5277  sprintf(output, "%s %g ",output, longitude);
5278  // External_psi
5279  sprintf(output, "%s %g ",output, thisInj->polarization);
5280  // FrameGPS
5281  sprintf(output, "%s %d ",output, int(FrameGPS));
5282  // SimStartGPS
5283  sprintf(output, "%s %d.%09d ",output, thisInj->geocent_end_time.gpsSeconds, thisInj->geocent_end_time.gpsNanoSeconds);
5284  // SimName
5285  sprintf(output, "%s %s ",output, inspName.Data());
5286  // SimHpHp
5287  sprintf(output, "%s 0 ",output);
5288  // SimHcHc
5289  sprintf(output, "%s 0 ",output);
5290  // SimHpHc
5291  sprintf(output, "%s 0 ",output);
5292 
5293  // IFO GPS F_+ F_x eff_dist
5294  for(int n=0;n<nIFO;n++) {
5295  TString ifo;
5296  double latitude,longitude,polarization;
5297  double theta,phi,psi;
5298  double rad2deg = 180./TMath::Pi();
5299 
5300  ifo = net->ifoName[n];
5301  latitude=thisInj->latitude;
5302  longitude=thisInj->longitude;
5303  polarization=thisInj->polarization;
5304  theta = LAL_PI_2-latitude; // LAL -> CWB
5305  theta*=rad2deg;
5306  longitude = fmod(longitude - gmst, LAL_TWOPI);
5307  if (longitude < 0) longitude += LAL_TWOPI;
5308  phi = longitude > 0 ? longitude : 2*TMath::Pi()+longitude;
5309  phi*= rad2deg;
5310  psi = polarization*rad2deg;
5311 
5312  double fp = GetAntennaPattern(ifo, phi, theta, psi, "hp");
5313  double fc = GetAntennaPattern(ifo, phi, theta, psi, "hx");
5314 
5315  // compute the gw delay between ifo and earth center
5316  double d2r = TMath::Pi()/180.;
5317 
5318  detector* D = net->getifo(n);
5319  detectorParams dP = D->getDetectorParams(); // get ifo parameters
5320  double D_theta = dP.latitude;
5321  double D_phi = dP.longitude;
5322  double D_R = sqrt(D->Rv[0]*D->Rv[0]+D->Rv[1]*D->Rv[1]+D->Rv[2]*D->Rv[2]); // earth radius
5323  GeographicToCwb(D_phi,D_theta,D_phi,D_theta);
5324  TVector3 dV(1,0,0); // set vector to ifo direction
5325  dV.SetTheta(D_theta*d2r);
5326  dV.SetPhi(D_phi*d2r);
5327 
5328  TVector3 sV(1,0,0); // set vector to source direction
5329  sV.SetTheta(theta*d2r);
5330  sV.SetPhi(phi*d2r);
5331 
5332  double cos_dVdS = dV.Dot(sV); // get cos between ifo and source direction
5333  double D_geocent_delay=-cos_dVdS*D_R/speedlight; // gw time delay ifo-geo_center
5334  int tShift_sec = int(fabs(D_geocent_delay));
5335  int tShift_nsec = int(1e9*(fabs(D_geocent_delay)-tShift_sec));
5336 
5337  // add gw time delay ifo geo_center to geocent_end_time
5338  int end_time_gpsSeconds = thisInj->geocent_end_time.gpsSeconds;
5339  int end_time_gpsNanoSeconds = thisInj->geocent_end_time.gpsNanoSeconds;
5340  if(D_geocent_delay>=0) {
5341  end_time_gpsSeconds += tShift_sec;
5342  end_time_gpsNanoSeconds += tShift_nsec;
5343  if ( end_time_gpsNanoSeconds >= 1000000000 ) {
5344  end_time_gpsSeconds += INT_4S( end_time_gpsNanoSeconds / 1000000000 );
5345  end_time_gpsNanoSeconds = end_time_gpsNanoSeconds % 1000000000;
5346  }
5347  } else {
5348  end_time_gpsSeconds -= tShift_sec;
5349  if ( end_time_gpsNanoSeconds >= tShift_nsec ) {
5350  end_time_gpsNanoSeconds -= tShift_nsec;
5351  } else {
5352  --end_time_gpsSeconds;
5353  end_time_gpsNanoSeconds += 1000000000 - tShift_nsec;
5354  }
5355  }
5356 
5357  // compute effective distance
5358  double cosiota = cos(thisInj->inclination);
5359  double eff_dist = thisInj->distance / sqrt(pow(fp*(1.+pow(cosiota,2)),2)/4.+pow(fc*cosiota,2));
5360 
5361  sprintf(output, "%s %s %d.%09d %e %e %g ",output, ifo.Data(), end_time_gpsSeconds,
5362  end_time_gpsNanoSeconds, fp, fc, eff_dist);
5363  }
5364 
5365  // calculate frequency of innermost stable circulat orbit
5366  // taken from: gr-qc/0612100
5367  f_isco = 205 * (20 / (thisInj->mass1 + thisInj->mass2));
5368 
5369  // numerical relativity specific parameters
5370  sprintf(output, "%s insp ",output);
5371  sprintf(output, "%s distance %g ",output, thisInj->distance);
5372  sprintf(output, "%s mass1 %g ",output, thisInj->mass1);
5373  sprintf(output, "%s mass2 %g ",output, thisInj->mass2);
5374  sprintf(output, "%s mchirp %g ",output, thisInj->mchirp);
5375  sprintf(output, "%s spin1 %g %g %g ",output, thisInj->spin1x, thisInj->spin1y, thisInj->spin1z);
5376  sprintf(output, "%s spin2 %g %g %g ",output, thisInj->spin2x, thisInj->spin2y, thisInj->spin2z);
5377  sprintf(output, "%s freq %g %g",output, thisInj->f_lower, f_isco);
5378  sprintf(output, "%s redshift %g",output, thisInj->alpha3);
5379  sprintf(output, "%s alpha1 %g",output, thisInj->alpha1); // used by cWB PE to store PE logl
5380  sprintf(output, "%s alpha2 %g\n",output, thisInj->alpha2); // used by cWB PE to store PE prior
5381 
5382  return output;
5383 }
5384 #endif
5385 
5386 #ifdef _USE_LAL
5387 //______________________________________________________________________________
5388 void
5390 //
5391 // Set inspiral mdc parameters
5392 //
5393 // Input: inspName - name of inspiral
5394 // inspOptions - list of options (see lalapps_inspinj options)
5395 // to dump all the available options do: 'lalapps_inspinj --help'
5396 // for any details refer to the LAL documentation.
5397 // There are some special options added only for the mdc class
5398 // --xml "file.xml" : read mdc injection's parameters from xml file
5399 // --output "file.xml" : write mdc injection's parameters to xml file
5400 // --dir "tmp dir" : directory used to store the temporary xml file,
5401 // default=/tmp
5402 //
5403 // Note : The LAL function used to generate the waveforms is defined in LALInspiralWave.c
5404 // for LAL version < 6.13.2 it is : XLALSimInspiralChooseWaveformFromSimInspiral
5405 // for LAL version >= 6.13.2 it is : XLALInspiralTDWaveformFromSimInspiral
5406 //
5407 // If --waveform is used together with the --xml option the waveform name
5408 // in the xml file is overwritten with the waveform user name
5409 
5410 // const int nOpt = 12;
5411 // const int nOpt = 10;
5412  const int nOpt = 7;
5413  TString option[nOpt] = {"--help","--verbose","--user-tag","--write-compress",
5414  "--ipn-gps-time","--t-distr",
5415  "--write-sim-ring"};
5416 // "--gps-start-time","--gps-end-time","--ipn-gps-time","--t-distr",
5417 // "--time-step","--time-interval","--write-sim-ring"};
5418 
5419  if(inspName.Sizeof()<=1) {
5420  cout << "CWB::mdc::SetInspiral - Error : inspName not declared" << endl;
5421  exit(1);
5422  }
5423 
5424  for(int i=0;i<nOpt;i++) {
5425  if(inspOptions.Contains(option[i])) {
5426  cout << "CWB::mdc::SetInspiral - Error : option " << option[i].Data()
5427  << " not allowed in CWB" << endl;
5428  exit(1);
5429  }
5430  }
5431 
5432  // approximant is substitute with waveform
5433  // approximant is maintained only for back compatibility
5434  inspOptions.ReplaceAll("--approximant","--waveform");
5435 
5436  TObjArray* token = inspOptions.Tokenize(TString(" "));
5437 
5438  // check options waveform and xml
5439  int bxml=0;
5440  int bwaveform=0;
5441  for(int i=0;i<token->GetEntries();i++) {
5442  TObjString* otoken = (TObjString*)token->At(i);
5443  TString stoken = otoken->GetString();
5444  if(stoken=="--xml") bxml++;
5445  if(stoken=="--waveform") bwaveform++;
5446  }
5447  if(!bxml) { // xlm is build by mdc cwb
5448  if(bwaveform!=1) {
5449  cout << "CWB::mdc::SetInspiral - Error : ";
5450  if(bwaveform>1) cout << "imultiple declaration of waveform option" << endl;
5451  if(!bwaveform) cout << "missing waveform option" << endl;
5452  exit(1);
5453  }
5454  }
5455 
5456  TString inspDump="";
5457  TString inspOutput="";
5458 
5459  // exctract xml, dir, time-step & check waveform
5460  cout << "CWB::mdc::SetInspiral - Read options ..." << endl;
5461  for(int i=0;i<token->GetEntries();i++) {
5462  TObjString* otoken = (TObjString*)token->At(i);
5463  TString stoken = otoken->GetString();
5464  if(stoken=="--xml") {
5465  otoken = (TObjString*)token->At(i+1);
5466  stoken = otoken->GetString();
5467  cout << "--xml = " << stoken.Data() << endl;
5468  CWB::Toolbox TB;
5469  TB.checkFile(stoken.Data());
5470  this->inspXML=stoken;
5471  }
5472  if(stoken=="--dir") {
5473  // xml temporary dir
5474  otoken = (TObjString*)token->At(i+1);
5475  stoken = otoken->GetString();
5476  cout << "--dir = " << stoken.Data() << endl;
5477  CWB::Toolbox TB;
5478  TB.checkFile(stoken.Data());
5479  this->inspDIR=stoken;
5480  // remove dir option from inspOptions
5481  inspOptions.ReplaceAll("--dir","");
5482  inspOptions.ReplaceAll(stoken,"");
5483  }
5484  if(stoken=="--output") {
5485  otoken = (TObjString*)token->At(i+1);
5486  stoken = otoken->GetString();
5487  cout << "--output = " << stoken.Data() << endl;
5488  inspOutput=stoken;
5489  // remove output option from inspOptions
5490  inspOptions.ReplaceAll("--output","");
5491  inspOptions.ReplaceAll(stoken,"");
5492  }
5493  if(stoken=="--dump") {
5494  otoken = (TObjString*)token->At(i+1);
5495  stoken = otoken->GetString();
5496  cout << "--dump = " << stoken.Data() << endl;
5497  inspDump=stoken;
5498  // remove dump option from inspOptions
5499  inspOptions.ReplaceAll("--dump","");
5500  inspOptions.ReplaceAll(stoken,"");
5501  }
5502  if(stoken=="--time-step") {
5503  otoken = (TObjString*)token->At(i+1);
5504  stoken = otoken->GetString();
5505  cout << "--time-step = " << stoken.Data() << endl;
5506  inj_rate = 1./stoken.Atof();
5507  }
5508  if(stoken=="--time-interval") {
5509  otoken = (TObjString*)token->At(i+1);
5510  stoken = otoken->GetString();
5511  cout << "--time-interval = " << stoken.Data() << endl;
5512  inj_jitter = stoken.Atof();
5513  }
5514  if(stoken=="--waveform") {
5515  otoken = (TObjString*)token->At(i+1);
5516  stoken = otoken->GetString();
5517  cout << "--waveform = " << stoken.Data() << endl;
5518  this->waveName=stoken;
5519  if(XLALGetApproximantFromString(stoken.Data()) == XLAL_FAILURE) {
5520  cout << "CWB::mdc::SetInspiral - waveform : \'" << stoken.Data()
5521  << "\' not allowed !!!" << endl;
5522  exit(1);
5523  }
5524  }
5525  }
5526 
5527  delete token;
5528 
5529  if(this->inspDIR=="") {
5530  cout << endl;
5531  cout << "CWB::mdc::SetInspiral - Error : temporary dir not defined !!! Use --dir option" << endl;
5532  cout << endl;
5533  cout << " if this option is called from a config plugin add the following line to the inspOptions : " << endl;
5534  cout << " inspOptions+= \"--dir \"+TString(cfg->tmp_dir)+\" " << endl;
5535  cout << " before to call : 'MDC.SetInspiral(inspOptions);'" << endl << endl;
5536  cout << " and these lines to the plugin : " << endl;
5537  cout << " // export config object to the config plugin" << endl;
5538  cout << " sprintf(cmd,\"CWB::config* cfg = (CWB::config*)%p;\",cfg);" << endl;
5539  cout << " gROOT->ProcessLine(cmd);" << endl;
5540  cout << " before to execute the config plugin : 'cfg->configPlugin.Exec(NULL,&error);'" << endl;
5541  cout << endl;
5542  exit(1);
5543  }
5544 
5545  this->inspName=inspName;
5546  this->inspOptions=inspOptions;
5547 
5548  // write xml file & exit
5549  if(inspDump!="") {
5550  TString injectionFile = GenInspiralXML(0, 0, false);
5551  cout << "Save inspiral injection file to " << inspDump.Data() << endl;
5552  if(inspXML=="") gSystem->Exec("mv "+injectionFile+" "+inspDump);
5553  else gSystem->Exec("cp "+injectionFile+" "+inspDump);
5554  exit(0);
5555  }
5556 
5557  // write xml file
5558  if(inspOutput!="") {
5559  // Check if file exist
5560  Long_t id,size=0,flags,mt;
5561  int estat = gSystem->GetPathInfo(inspOutput.Data(),&id,&size,&flags,&mt);
5562  if (estat!=0) { // skip if file already exist
5563  TString injectionFile = GenInspiralXML(0, 0, false);
5564  cout << "Save inspiral injection file to " << inspOutput.Data() << endl;
5565  gSystem->Exec("cp "+injectionFile+" "+inspOutput);
5566  }
5567  }
5568 
5569  // dummy exec to check if parameters are correct
5570  if(inspXML=="") GenInspiralXML(900000000, 900000000, true);
5571 
5572  return;
5573 }
5574 #endif
5575 
5576 #ifdef _USE_LAL
5577 //______________________________________________________________________________
5578 TString
5579 CWB::mdc::GetInspiralOption(TString inspOption) {
5580 //
5581 // Get inspiral mdc parameters
5582 //
5583 // Input: inspOption - name of inspiral xml option
5584 //
5585 
5586  if(inspOptions=="") return ""; // inspOptions not defined
5587 
5588  if(inspXML!="") { // xml is provided by user
5589 
5590  // read XML
5591  ifstream in;
5592  in.open(inspXML.Data(),ios::in);
5593  if (!in.good()) {cout << "CWB::mdc::GetInspiralOption - Error Opening xml File : "
5594  << inspXML.Data() << endl;gSystem->Exit(1);}
5595 
5596  char str[2048];
5597  while(true) {
5598  in.getline(str,2048);
5599  if (!in.good()) break;
5600  if(TString(str).Contains("inspinj")&&TString(str).Contains(inspOption)) {
5601  TObjArray* token = TString(str).Tokenize(TString(","));
5602  if(token->GetEntries()!=5) {cout << "CWB::mdc::GetInspiralOption - bad line format : "
5603  << str << endl;gSystem->Exit(1);}
5604  TObjString* otoken = (TObjString*)token->At(4);
5605  TString stoken = otoken->GetString();
5606  stoken.ReplaceAll("\"","");
5607  delete token;
5608  return stoken; // return token
5609  }
5610  }
5611 
5612  in.close();
5613  } else { // inspOptions provided by the user
5614 
5615  TObjArray* token = inspOptions.Tokenize(TString(" "));
5616  for(int i=0;i<token->GetEntries();i++) {
5617  TObjString* otoken = (TObjString*)token->At(i);
5618  TString stoken = otoken->GetString();
5619  if(stoken.Contains(inspOption)) {
5620  otoken = (TObjString*)token->At(i+1);
5621  stoken = otoken->GetString();
5622  stoken.ReplaceAll("\"","");
5623  return stoken;
5624  }
5625  }
5626  delete token;
5627  }
5628 
5629  return "";
5630 }
5631 #endif
5632 
5633 #ifdef _USE_LAL
5634 //______________________________________________________________________________
5635 TString
5636 CWB::mdc::GenInspiralXML(int gps_start_time, int gps_end_time, bool rmFile) {
5637 //
5638 // Get XML inspiral mdc parameters
5639 //
5640 // Input: gps_start_time - start time
5641 // gps_end_time - stop time
5642 // rmFile - remove temporary file
5643 //
5644 // Return XML string
5645 //
5646 
5647  if(inspXML!="") return inspXML; // xml is provided by user
5648 
5649  TString lalinspinj_exec;
5650  if(gSystem->Getenv("LALINSPINJ_EXEC")==NULL) {
5651  cout << "CWB::mdc::GenInspiralXML - Error : environment LALINSPINJ_EXEC is not defined!!!" << endl;exit(1);
5652  } else {
5653  lalinspinj_exec=TString(gSystem->Getenv("LALINSPINJ_EXEC"));
5654  }
5655 
5656  // test if command is well done (dummy exec)
5657  TString ofName = GetTemporaryFileName("inspiral","xml",inspDIR,true);
5658 
5659  TString cmdOptions = inspOptions;
5660  cmdOptions += " --output "+ofName;
5661  if(gps_start_time!=0) {
5662  cmdOptions += " --gps-start-time ";
5663  cmdOptions += gps_start_time;
5664  }
5665  if(gps_end_time!=0) {
5666  cmdOptions += " --gps-end-time ";
5667  cmdOptions += gps_end_time;
5668  }
5669 
5670  char cmd[1024];
5671  sprintf(cmd,"%s %s",lalinspinj_exec.Data(),cmdOptions.Data());
5672  cout << cmd << endl;
5673  int error = gSystem->Exec(cmd);
5674  if(rmFile) gSystem->Exec(TString("rm ")+ofName); // remove temporary file
5675 
5676  if(error) {
5677  cout << endl;
5678  char help[1024];
5679  sprintf(help,"%s --help",lalinspinj_exec.Data());
5680  gSystem->Exec(help);
5681  cout << endl;
5682  cout << "CWB::mdc::GenInspiralXML - Error in exececuting :" << endl << endl;
5683  cout << cmd << endl << endl;
5684  exit(1);
5685  }
5686 
5687  return ofName;
5688 }
5689 #endif
5690 
5691 //______________________________________________________________________________
5692 TString
5694 //
5695 // Get a temporary file name
5696 //
5697 // Input: tag - tag string
5698 // ext - file extension tag
5699 // mkdir - if true create temporary dir
5700 //
5701 
5702 
5703  gRandom->SetSeed(0);
5704  int rnID = int(gRandom->Rndm(13)*1.e9);
5705 
5706  if(dir=="/tmp") { // use /tmp dir
5707  // create temporary dir
5708  UserGroup_t* uinfo = gSystem->GetUserInfo();
5709  TString uname = uinfo->fUser;
5710  dir="/tmp/"+uname;
5711  int error=0;
5712  if(mkdir) error=gSystem->Exec(TString("mkdir -p ")+dir);
5713  if(error) {
5714  cout << endl;
5715  cout << "CWB::mdc::GetTemporaryFileName - Error in exececuting :" << endl << endl;
5716  cout << TString(TString("mkdir -p ")+dir) << endl << endl;
5717  exit(1);
5718  }
5719  }
5720 
5721  char fName[256];
5722  sprintf(fName,"%s/%s_%d.%s",dir.Data(),tag.Data(),rnID,ext.Data());
5723 
5724  return TString(fName);
5725 }
5726 
5727 #ifdef _USE_LAL
5728 //______________________________________________________________________________
5729 void
5730 CWB::mdc::FindChirpInjectSignals(wavearray<double>& w, SimInspiralTable *injections, TString ifo) {
5731 //
5732 // Get inspiral for user define detectors
5733 //
5734 //
5735 // Input: injections - structure which contains the parameters of waveforms
5736 //
5737 // Output: w - wavearray which contains the waveform data
5738 //
5739 
5740  double rad2deg = 180./TMath::Pi();
5741  double deg2rad = TMath::Pi()/180.;
5742  double fp,fx;
5743  double latitude,longitude,polarization;
5744  double theta,phi,psi;
5745  double gmst;
5746 
5748  w=0; z=w;
5749 
5750  REAL8TimeSeries *hp=NULL;
5751  REAL8TimeSeries *hx=NULL;
5752 
5753  //TString ifoRef=net->ifoName[0];
5754 
5755  // get detector location
5756  int nIFO = net ? net->ifoListSize() : 0;
5757  int ifoId=-1;
5758  detector* pD=NULL;
5759  for(int n=0; n<nIFO; n++) if(ifo.CompareTo(net->ifoName[n])==0) ifoId=n;
5760  if(ifoId>=0) pD = net->getifo(ifoId);
5761  else pD = new detector(const_cast<char*>(ifo.Data()));
5762  detectorParams dP = pD->getDetectorParams();
5763  REAL8 location[3] = {pD->Rv[0],pD->Rv[1],pD->Rv[2]};
5764  if(ifoId<0) delete pD;
5765 
5766  // loop over injections
5767  SimInspiralTable *thisInj = NULL;
5768  for (thisInj = injections; thisInj; thisInj = thisInj->next)
5769  {
5770  REAL8 deltaT = 1./w.rate();
5771  if(waveName!="") strcpy(thisInj->waveform,waveName.Data());
5772 
5773  // get approximant ( see LALSimInspiral.c )
5774  Approximant approximant = (Approximant)XLALSimInspiralGetApproximantFromString(thisInj->waveform);
5775 /*
5776  cout << endl << endl;
5777  cout << "---------------------------------------------------------------------------------" << endl;
5778  cout << "CWB::mdc::FindChirpInjectSignals" << endl;
5779  cout << "---------------------------------------------------------------------------------" << endl;
5780  cout << "thisSim->numrel_data : " << thisInj->numrel_data << endl;
5781  cout << "thisSim->waveform : " << thisInj->waveform << endl;
5782  cout << "thisSim->amp_order : " << thisInj->amp_order << endl;
5783  cout << "APPROXIMANT : " << approximant << " (NR_hdf5=" << NR_hdf5 << ")" << endl;
5784  cout << endl;
5785 */
5786  if(approximant==NR_hdf5) {
5787 
5788 #if LAL_VERSION_MAJOR > 6 || (LAL_VERSION_MAJOR == 6 && \
5789  (LAL_VERSION_MINOR > 18 || (LAL_VERSION_MINOR == 18 && \
5790  (LAL_VERSION_MICRO > 0 || (LAL_VERSION_MICRO == 0 && LAL_VERSION_DEVEL >= 1))))) // LAL_VERSION >= 6.18.0.1
5791 
5792  // see LALInferenceReadData.c
5793  LALDict *LALpars=XLALCreateDict();
5794  XLALSimInspiralWaveformParamsInsertNumRelData(LALpars, thisInj->numrel_data);
5795 
5796  // add check if numrel_mode_min/max is empty then skip creating ModeArray
5797  LALValue* ModeArray = XLALSimInspiralCreateModeArray();
5798 
5799  int ell_min = thisInj->numrel_mode_min; // this should really only ever be numrel_mode_min=2
5800  int ell_max = thisInj->numrel_mode_max;
5801 
5802  if ((ell_min == 0) && (ell_max == 0)){ell_min=2;ell_max=LAL_SIM_L_MAX_MODE_ARRAY;}
5803  //loop over
5804  for (int ell=ell_min; ell<=ell_max; ell++){
5805  XLALSimInspiralModeArrayActivateAllModesAtL(ModeArray, ell);
5806  }
5807 
5808  XLALSimInspiralWaveformParamsInsertModeArray(LALpars, ModeArray);
5809 
5810  // see LALSimInspiral.c
5811  REAL8 f_min = XLALSimInspiralfLow2fStart(thisInj->f_lower, thisInj->amp_order, approximant);
5812 /*
5813  cout << endl;
5814  printf("CWB::mdc::FindChirpInjectSignals - Injecting with approximant = %d\n", approximant);
5815  printf("CWB::mdc::FindChirpInjectSignals - Injecting with numrel_data = %s\n", thisInj->numrel_data);
5816  printf("CWB::mdc::FindChirpInjectSignals - Injecting with waveform = %s\n", thisInj->waveform);
5817  printf("CWB::mdc::FindChirpInjectSignals - Injecting with f_min = %f\n", f_min);
5818  printf("CWB::mdc::FindChirpInjectSignals - Injecting with f_lower = %f\n", thisInj->f_lower);
5819  printf("CWB::mdc::FindChirpInjectSignals - Injecting with amp_order = %d\n", thisInj->amp_order);
5820  printf("CWB::mdc::FindChirpInjectSignals - Injecting with mass1 = %f\n", thisInj->mass1);
5821  printf("CWB::mdc::FindChirpInjectSignals - Injecting with mass2 = %f\n", thisInj->mass2);
5822  printf("CWB::mdc::FindChirpInjectSignals - Injecting with spin1x = %f\n", thisInj->spin1x);
5823  printf("CWB::mdc::FindChirpInjectSignals - Injecting with spin2x = %f\n", thisInj->spin2x);
5824  printf("CWB::mdc::FindChirpInjectSignals - Injecting with spin1y = %f\n", thisInj->spin1y);
5825  printf("CWB::mdc::FindChirpInjectSignals - Injecting with spin2y = %f\n", thisInj->spin2y);
5826  printf("CWB::mdc::FindChirpInjectSignals - Injecting with spin1z = %f\n", thisInj->spin1z);
5827  printf("CWB::mdc::FindChirpInjectSignals - Injecting with spin2z = %f\n", thisInj->spin2z);
5828  printf("CWB::mdc::FindChirpInjectSignals - Injecting with distance = %f\n", thisInj->distance);
5829  printf("CWB::mdc::FindChirpInjectSignals - Injecting with inclination = %f\n", thisInj->inclination);
5830  printf("CWB::mdc::FindChirpInjectSignals - Injecting with coa_phase = %f\n", thisInj->coa_phase);
5831  printf("CWB::mdc::FindChirpInjectSignals - Injecting with mode min = %d\n", thisInj->numrel_mode_min);
5832  printf("CWB::mdc::FindChirpInjectSignals - Injecting with mode max = %d\n", thisInj->numrel_mode_max);
5833  cout << endl;
5834 */
5835  if( thisInj->amp_order!=0 ) {
5836  cout << endl << "CWB::mdc::FindChirpInjectSignals - "
5837  << "Error : amp_order must be 0 for NR waveform : "
5838  << "check inspiral parameters" << endl;
5839  exit(1);
5840  }
5841 
5842  // see LALSimInspiral.c
5843  int ret = XLALSimInspiralTD(&hp, &hx, thisInj->mass1*LAL_MSUN_SI, thisInj->mass2*LAL_MSUN_SI,
5844  thisInj->spin1x, thisInj->spin1y, thisInj->spin1z,
5845  thisInj->spin2x, thisInj->spin2y, thisInj->spin2z,
5846  thisInj->distance*LAL_PC_SI*1.0e6, thisInj->inclination,
5847  thisInj->coa_phase, 0., 0., 0.,
5848  deltaT, f_min, 0.,
5849  LALpars, approximant);
5850 
5851  XLALDestroyDict(LALpars);
5852 
5853  if( ret==XLAL_FAILURE ) {
5854  cout << endl << "CWB::mdc::GetInspiral - "
5855  << "Error in XLALInspiralTDWaveformFromSimInspiral(1) : "
5856  << "check inspiral parameters" << endl;
5857  exit(1);
5858  }
5859 #else
5860  cout << endl << "CWB::mdc::GetInspiral - "
5861  << "Error - NR_hdf5 not supported for LAL_VERSION < 6.18.0.1" << endl;
5862  exit(1);
5863 #endif
5864 
5865  } else {
5866 
5867 #if LAL_VERSION_MAJOR > 6 || (LAL_VERSION_MAJOR == 6 && \
5868  (LAL_VERSION_MINOR > 16 || (LAL_VERSION_MINOR == 16 && \
5869  LAL_VERSION_MICRO >= 1 ))) // LAL_VERSION >= 6.16.1
5870 
5871  // check if source is produced by CWB::mdc::Posterior2XML
5872  TString source = TString(thisInj->source);
5873  if(source(0,5)=="#CWB:") {
5874  // extract version number
5875  TString version=source(source.Index(":",4)+1,source.Index(":",5)-source.Index(":",4)-1);
5876  // check version
5877  if(version.Atoi()<1) {
5878  cout << endl << "CWB::mdc::FindChirpInjectSignals - "
5879  << "Error: outdated version of XML produced by CWB::mdc::Posterior2XML, must be >= 1" << endl << endl;
5880  exit(1);
5881  }
5882  }
5883 
5884 #if LAL_VERSION_MAJOR == 6 && LAL_VERSION_MINOR == 16 && LAL_VERSION_MICRO == 1 // used only for tagged version lalinference_o2 used for O2 posteriors
5885 
5886  // NOTE: lambda1, lambda2 are provided with xml generated with CWB::mdc::Posterior2XML
5887  // since there are not dedicated locations in the SimInspiralTable we use alpha,beta
5888  double lambda1 = source(0,5)=="#CWB:" ? thisInj->alpha : 0;
5889  double lambda2 = source(0,5)=="#CWB:" ? thisInj->beta : 0;
5890 
5891  // see LALSimInspiral.c
5892  REAL8 f_min = XLALSimInspiralfLow2fStart(thisInj->f_lower, thisInj->amp_order, approximant);
5893 
5894  // get pn order from waveform
5895  int pn_order = XLALSimInspiralGetPNOrderFromString(thisInj->waveform);
5896 
5897  // see LALSimInspiral.c
5898  int ret = XLALSimInspiralTD(&hp, &hx, thisInj->coa_phase, deltaT,
5899  thisInj->mass1*LAL_MSUN_SI, thisInj->mass2*LAL_MSUN_SI,
5900  thisInj->spin1x, thisInj->spin1y, thisInj->spin1z,
5901  thisInj->spin2x, thisInj->spin2y, thisInj->spin2z,
5902  f_min, thisInj->f_final,
5903  thisInj->distance*LAL_PC_SI*1.0e6, 0., thisInj->inclination,
5904  lambda1, lambda2, NULL, NULL,
5905  thisInj->amp_order, pn_order, approximant);
5906 
5907 #else
5908  // this function is reimplemented in the cWB code, see mdc::XLALInspiralTDWaveformFromSimInspiral
5909  int ret = this->XLALInspiralTDWaveformFromSimInspiral(&hp, &hx, thisInj, deltaT);
5910 #endif
5911 
5912  if( ret==XLAL_FAILURE ) {
5913  cout << endl << "CWB::mdc::GetInspiral - "
5914  << "Error in XLALInspiralTDWaveformFromSimInspiral(2) : "
5915  << "check inspiral parameters" << endl;
5916  exit(1);
5917  }
5918 #else
5919  cout << endl << "CWB::mdc::GetInspiral - "
5920  << "Error - LAL_VERSION < 6.16.1 not supported " << endl;
5921  exit(1);
5922 #endif
5923 
5924  }
5925 
5926  /* add the time of the injection at the geocentre to the
5927  * start times of the h+ and hx time series. after this,
5928  * their epochs mark the start of those time series at the
5929  * geocentre. (see http://www.lsc-group.phys.uwm.edu/cgit/gstlal/tree/gstlal/gst/lal/gstlal_simulation.c) */
5930 
5931  XLALGPSAddGPS(&hp->epoch, &thisInj->geocent_end_time);
5932  XLALGPSAddGPS(&hx->epoch, &thisInj->geocent_end_time);
5933 
5934  wat::Time gpsbuf(w.start());
5935  wat::Time gpsinj(hp->epoch.gpsSeconds,hp->epoch.gpsNanoSeconds);
5936  wat::Time gpsoff=gpsinj;gpsoff-=gpsbuf;
5937 
5938  int bininj = int(gpsoff.GetDouble()/deltaT);
5939  double binoff = fmod(gpsoff.GetDouble(),deltaT);
5940 
5941  bininj+=hp->data->length;
5942  if(bininj>w.size()) {
5943  cout << "CWB::mdc::FindChirpInjectSignals - Warning " << endl;
5944  cout << " signal length " << hp->data->length*deltaT
5945  << " (sec) is too high, signal is cutted to fit the buffer length" << endl;
5946  cout << " Decrease the injection rate and/or reduce the waveform length" << endl;
5947  bininj=w.size()-1;
5948  }
5949 
5950  gmst = fmod(XLALGreenwichMeanSiderealTime(&thisInj->geocent_end_time), LAL_TWOPI);
5951 
5952  latitude=thisInj->latitude;
5953  longitude=thisInj->longitude;
5954  polarization=thisInj->polarization;
5955  theta = LAL_PI_2-latitude; // LAL -> CWB
5956  theta*=rad2deg;
5957  longitude = fmod(longitude - gmst, LAL_TWOPI);
5958  if (longitude < 0) longitude += LAL_TWOPI;
5959  phi = longitude > 0 ? longitude : 2*TMath::Pi()+longitude;
5960  phi*= rad2deg;
5961  psi = polarization*rad2deg;
5962 
5963  fp = GetAntennaPattern(ifo, phi, theta, psi, "hp");
5964  fx = GetAntennaPattern(ifo, phi, theta, psi, "hx");
5965 
5966  // check if the injection length is greater of the buffer
5967  int length = hp->data->length<w.size() ? hp->data->length : w.size();
5968  z=0;
5969  for(int i=bininj;i>=0;i--) {
5970  int j=length-(bininj-i)-1;
5971  if(j<0) break;
5972  z[i] = fp*hp->data->data[j]+fx*hx->data->data[j]; // detector wave projection
5973  }
5974  if(inspCLB!="") {
5975  int simulation_id = thisInj->bandpass; // WARNING!!! used simTable->bandpass instead of simTable->simulation_id
5976  wat::Time wtime(thisInj->geocent_end_time.gpsSeconds, thisInj->geocent_end_time.gpsNanoSeconds);
5977  CalibrateInspiral(z, ifo, wtime.GetDouble(), simulation_id); // apply calibration if user has defined the calibration file inspCLB
5978  }
5979  // apply time shift respect to the ifoRef
5980  //double tShift = GetDelay(ifo,ifoRef,phi,theta);
5981  double tShift = XLALTimeDelayFromEarthCenter(location, thisInj->longitude, thisInj->latitude, &hp->epoch);
5982  // add to tShift the bin time offset
5983  tShift+=binoff;
5984  TimeShift(z, tShift);
5985  for(int i=0;i<(int)w.size();i++) w[i]+=z[i];
5986 
5987  XLALDestroyREAL8TimeSeries( hp );
5988  XLALDestroyREAL8TimeSeries( hx );
5989  hp = NULL; hx = NULL;
5990  }
5991  return;
5992 }
5993 #endif
5994 
5995 #ifdef _USE_LAL
5996 //______________________________________________________________________________
5998 CWB::mdc::GetInspiral(TString pol, int gps_start_time, int gps_end_time) {
5999 //
6000 // Get inspiral waveform
6001 //
6002 //
6003 // Input: pol - wave polarization : hp, hx
6004 // gps_start_time - start time
6005 // gps_end_time - stop time
6006 //
6007 // Output: w - wavearray which contains the waveform data
6008 //
6009 
6011  w.rate(MDC_SAMPLE_RATE);
6012 
6013  if(pol!="hp" && pol!="hx") {
6014  fprintf( stderr, "CWB::mdc::GetInspiral - Warning : wrong polarization (enter hp or hx)\n");
6015  return w;
6016  }
6017 
6018  // start/end times
6019  int gpsStartSec = gps_start_time;
6020  int gpsEndSec = gps_end_time;
6021 
6022  // injections
6023  INT4 numInjections = 0;
6024  SimInspiralTable *injections = NULL;
6025  TString injectionFile = GenInspiralXML(0., 0., false);
6026 
6027  // set default debug level
6028  lal_errhandler = LAL_ERR_EXIT;
6029 
6030  XLALSetSilentErrorHandler();
6031 
6032  // read the injections
6033  numInjections = SimInspiralTableFromLIGOLw(&injections, injectionFile.Data(), gpsStartSec, gpsEndSec);
6034 
6035  if ( numInjections == 0 ) {
6036  fprintf( stderr, "CWB::mdc::GetInspiral - Warning : No injections in specified time\n");
6037  return w;
6038  } else {
6039  fprintf( stdout, "CWB::mdc::GetInspiral : Read %d injection(s) from the file '%s'\n",
6040  numInjections, injectionFile.Data() );
6041  }
6042 
6043  REAL8TimeSeries *hp=NULL;
6044  REAL8TimeSeries *hx=NULL;
6045 
6046  // loop over injections
6047  SimInspiralTable *thisInj = NULL;
6048  for (thisInj = injections; thisInj; thisInj = thisInj->next)
6049  {
6050  REAL8 deltaT = 1./w.rate();
6051  if(waveName!="") strcpy(thisInj->waveform,waveName.Data());
6052 
6053  // get approximant ( see LALSimInspiral.c )
6054  Approximant approximant = (Approximant)XLALSimInspiralGetApproximantFromString(thisInj->waveform);
6055 /*
6056  cout << endl << endl;
6057  cout << "---------------------------------------------------------------------------------" << endl;
6058  cout << "CWB::mdc::GetInspiral" << endl;
6059  cout << "---------------------------------------------------------------------------------" << endl;
6060  cout << "thisSim->numrel_data : " << thisInj->numrel_data << endl;
6061  cout << "thisSim->waveform : " << thisInj->waveform << endl;
6062  cout << "thisSim->amp_order : " << thisInj->amp_order << endl;
6063  cout << "APPROXIMANT : " << approximant << " (NR_hdf5=" << NR_hdf5 << ")" << endl;
6064  cout << endl;
6065 */
6066  if(approximant==NR_hdf5) {
6067 
6068 #if LAL_VERSION_MAJOR > 6 || (LAL_VERSION_MAJOR == 6 && \
6069  (LAL_VERSION_MINOR > 18 || (LAL_VERSION_MINOR == 18 && \
6070  (LAL_VERSION_MICRO > 0 || (LAL_VERSION_MICRO == 0 && LAL_VERSION_DEVEL >= 1))))) // LAL_VERSION >= 6.18.0.1
6071 
6072  // see LALInferenceReadData.c
6073  LALDict *LALpars=XLALCreateDict();
6074  XLALSimInspiralWaveformParamsInsertNumRelData(LALpars, thisInj->numrel_data);
6075 
6076  // add check if numrel_mode_min/max is empty then skip creating ModeArray
6077  LALValue* ModeArray = XLALSimInspiralCreateModeArray();
6078 
6079  int ell_min = thisInj->numrel_mode_min; // this should really only ever be numrel_mode_min=2
6080  int ell_max = thisInj->numrel_mode_max;
6081 
6082  if ((ell_min == 0) && (ell_max == 0)){ell_min=2;ell_max=LAL_SIM_L_MAX_MODE_ARRAY;}
6083  //loop over
6084  for (int ell=ell_min; ell<=ell_max; ell++){
6085  XLALSimInspiralModeArrayActivateAllModesAtL(ModeArray, ell);
6086 
6087  }
6088 
6089  XLALSimInspiralWaveformParamsInsertModeArray(LALpars, ModeArray);
6090 
6091  // see LALSimInspiral.c
6092  REAL8 f_min = XLALSimInspiralfLow2fStart(thisInj->f_lower, thisInj->amp_order, approximant);
6093 /*
6094  cout << endl;
6095  printf("CWB::mdc::GetInspiral - Injecting with approximant = %d\n", approximant);
6096  printf("CWB::mdc::GetInspiral - Injecting with numrel_data = %s\n", thisInj->numrel_data);
6097  printf("CWB::mdc::GetInspiral - Injecting with waveform = %s\n", thisInj->waveform);
6098  printf("CWB::mdc::GetInspiral - Injecting with f_min = %f\n", f_min);
6099  printf("CWB::mdc::GetInspiral - Injecting with f_lower = %f\n", thisInj->f_lower);
6100  printf("CWB::mdc::GetInspiral - Injecting with amp_order = %d\n", thisInj->amp_order);
6101  printf("CWB::mdc::GetInspiral - Injecting with mass1 = %f\n", thisInj->mass1);
6102  printf("CWB::mdc::GetInspiral - Injecting with mass2 = %f\n", thisInj->mass2);
6103  printf("CWB::mdc::GetInspiral - Injecting with spin1x = %f\n", thisInj->spin1x);
6104  printf("CWB::mdc::GetInspiral - Injecting with spin2x = %f\n", thisInj->spin2x);
6105  printf("CWB::mdc::GetInspiral - Injecting with spin1y = %f\n", thisInj->spin1y);
6106  printf("CWB::mdc::GetInspiral - Injecting with spin2y = %f\n", thisInj->spin2y);
6107  printf("CWB::mdc::GetInspiral - Injecting with spin1z = %f\n", thisInj->spin1z);
6108  printf("CWB::mdc::GetInspiral - Injecting with spin2z = %f\n", thisInj->spin2z);
6109  printf("CWB::mdc::GetInspiral - Injecting with distance = %f\n", thisInj->distance);
6110  printf("CWB::mdc::GetInspiral - Injecting with inclination = %f\n", thisInj->inclination);
6111  printf("CWB::mdc::GetInspiral - Injecting with coa_phase = %f\n", thisInj->coa_phase);
6112  printf("CWB::mdc::GetInspiral - Injecting with mode min = %d\n", thisInj->numrel_mode_min);
6113  printf("CWB::mdc::GetInspiral - Injecting with mode max = %d\n", thisInj->numrel_mode_max);
6114  cout << endl;
6115 */
6116  if( thisInj->amp_order!=0 ) {
6117  cout << endl << "CWB::mdc::GetInspiral - "
6118  << "Error : amp_order must be 0 for NR waveform : "
6119  << "check inspiral parameters" << endl;
6120  exit(1);
6121  }
6122 
6123  // see LALSimInspiral.c
6124  int ret = XLALSimInspiralTD(&hp, &hx, thisInj->mass1*LAL_MSUN_SI, thisInj->mass2*LAL_MSUN_SI,
6125  thisInj->spin1x, thisInj->spin1y, thisInj->spin1z,
6126  thisInj->spin2x, thisInj->spin2y, thisInj->spin2z,
6127  thisInj->distance*LAL_PC_SI*1.0e6, thisInj->inclination,
6128  thisInj->coa_phase, 0., 0., 0.,
6129  deltaT, f_min, 0.,
6130  LALpars, approximant);
6131 
6132  XLALDestroyDict(LALpars);
6133 
6134  if( ret==XLAL_FAILURE ) {
6135  cout << endl << "CWB::mdc::GetInspiral - "
6136  << "Error in XLALInspiralTDWaveformFromSimInspiral(3) : "
6137  << "check inspiral parameters" << endl;
6138  exit(1);
6139  }
6140 #else
6141  cout << endl << "CWB::mdc::GetInspiral - "
6142  << "Error - NR_hdf5 not supported for LAL_VERSION < 6.18.0.1" << endl;
6143  exit(1);
6144 #endif
6145 
6146  } else {
6147 
6148 #if LAL_VERSION_MAJOR > 6 || (LAL_VERSION_MAJOR == 6 && \
6149  (LAL_VERSION_MINOR > 16 || (LAL_VERSION_MINOR == 16 && \
6150  LAL_VERSION_MICRO >= 1 ))) // LAL_VERSION >= 6.16.1
6151 
6152  // check if source is produced by CWB::mdc::Posterior2XML
6153  TString source = TString(thisInj->source);
6154  if(source(0,5)=="#CWB:") {
6155  // extract version number
6156  TString version=source(source.Index(":",4)+1,source.Index(":",5)-source.Index(":",4)-1);
6157  // check version
6158  if(version.Atoi()<1) {
6159  cout << endl << "CWB::mdc::FindChirpInjectSignals - "
6160  << "Error: outdated version of XML produced by CWB::mdc::Posterior2XML, must be >= 1" << endl << endl;
6161  exit(1);
6162  }
6163  }
6164 
6165 #if LAL_VERSION_MAJOR == 6 && LAL_VERSION_MINOR == 16 && LAL_VERSION_MICRO == 1 // used only for tagged version lalinference_o2 used for O2 posteriors
6166 
6167  // NOTE: lambda1, lambda2 are provided with xml generated with CWB::mdc::Posterior2XML
6168  // since there are not dedicated locations in the SimInspiralTable we use alpha,beta
6169  double lambda1 = source(0,5)=="#CWB:" ? thisInj->alpha : 0;
6170  double lambda2 = source(0,5)=="#CWB:" ? thisInj->beta : 0;
6171 
6172  // see LALSimInspiral.c
6173  REAL8 f_min = XLALSimInspiralfLow2fStart(thisInj->f_lower, thisInj->amp_order, approximant);
6174 
6175  // get pn order from waveform
6176  int pn_order = XLALSimInspiralGetPNOrderFromString(thisInj->waveform);
6177 
6178  // see LALSimInspiral.c
6179  int ret = XLALSimInspiralTD(&hp, &hx, thisInj->coa_phase, deltaT,
6180  thisInj->mass1*LAL_MSUN_SI, thisInj->mass2*LAL_MSUN_SI,
6181  thisInj->spin1x, thisInj->spin1y, thisInj->spin1z,
6182  thisInj->spin2x, thisInj->spin2y, thisInj->spin2z,
6183  f_min, thisInj->f_final,
6184  thisInj->distance*LAL_PC_SI*1.0e6, 0., thisInj->inclination,
6185  lambda1, lambda2, NULL, NULL,
6186  thisInj->amp_order, pn_order, approximant);
6187 
6188 #else
6189  // this function is reimplemented in the cWB code, see mdc::XLALInspiralTDWaveformFromSimInspiral
6190  int ret = this->XLALInspiralTDWaveformFromSimInspiral(&hp, &hx, thisInj, deltaT);
6191 #endif
6192 
6193  if( ret==XLAL_FAILURE ) {
6194  cout << endl << "CWB::mdc::GetInspiral - "
6195  << "Error in XLALInspiralTDWaveformFromSimInspiral : "
6196  << "check inspiral parameters" << endl;
6197  exit(1);
6198  }
6199 #else
6200  cout << endl << "CWB::mdc::GetInspiral - "
6201  << "Error - LAL_VERSION < 6.16.1 not supported " << endl;
6202  exit(1);
6203 #endif
6204 
6205  }
6206 
6207  /* add the time of the injection at the geocentre to the
6208  * start times of the h+ and hx time series. after this,
6209  * their epochs mark the start of those time series at the
6210  * geocentre. (see http://www.lsc-group.phys.uwm.edu/cgit/gstlal/tree/gstlal/gst/lal/gstlal_simulation.c) */
6211 
6212  XLALGPSAddGPS(&hp->epoch, &thisInj->geocent_end_time);
6213  XLALGPSAddGPS(&hx->epoch, &thisInj->geocent_end_time);
6214 
6215  // fill output wavearray
6216  if(pol=="hp") {
6217  w.resize(hp->data->length);
6218  wat::Time gps(hp->epoch.gpsSeconds,hp->epoch.gpsNanoSeconds);
6219  w.start(gps.GetDouble());
6220  for(int i=0;i<(int)w.size();i++) w[i] = hp->data->data[i];
6221  }
6222  if(pol=="hx") {
6223  w.resize(hx->data->length);
6224  wat::Time gps(hx->epoch.gpsSeconds,hx->epoch.gpsNanoSeconds);
6225  w.start(gps.GetDouble());
6226  for(int i=0;i<(int)w.size();i++) w[i] = hx->data->data[i];
6227  }
6228 
6229  XLALDestroyREAL8TimeSeries(hp);
6230  XLALDestroyREAL8TimeSeries(hx);
6231  hp = NULL; hx = NULL;
6232 
6233  break; // break after the first waveform
6234  }
6235 
6236  if(inspXML=="") gSystem->Exec(TString("rm ")+injectionFile); // remove injectionFile file
6237 
6238  while ( injections ) {
6239  SimInspiralTable *thisInj = NULL;
6240  thisInj = injections;
6241  injections = injections->next;
6242  LALFree( thisInj );
6243  }
6244 
6245  LALCheckMemoryLeaks();
6246 
6247  return w;
6248 }
6249 #endif
6250 
6251 #ifdef _USE_LAL
6252 // this function has been copied from LALInspiralWave.c (lalsuite-v6.54)
6253 // we have chaged the line:
6254 // REAL8 f_ref = 0.;
6255 // with line:
6256 // REAL8 f_ref = thisRow->f_final;
6257 // to permits the use of the original f_ref stored in the posterior samples
6258 // cWB stores f_ref into the thisRow->f_final
6259 //
6260 // new code has beed added to manage new approximants: SEOBNRv4P, SEOBNRv4PHM
6261 // this is necessary because the LAL funcion XLALSimInspiralTD (LALSimInspiral.c)
6262 // does a f_min correction which is not valid SEOBNRv4P, SEOBNRv4PHM
6263 int
6264 CWB::mdc::XLALInspiralTDWaveformFromSimInspiral(
6265  REAL8TimeSeries **hplus, /**< +-polarization waveform */
6266  REAL8TimeSeries **hcross, /**< x-polarization waveform */
6267  SimInspiralTable *thisRow, /**< row from the sim_inspiral table containing waveform parameters */
6268  REAL8 deltaT /**< time step (s) */
6269  )
6270 {
6271 #if !(LAL_VERSION_MAJOR == 6 && LAL_VERSION_MINOR == 16 && LAL_VERSION_MICRO == 1) // not used for tagged version lalinference_o2 used for O2 posteriors
6272  int ret;
6273  LALPNOrder order;
6274  Approximant approximant;
6275  REAL8 phi0 = thisRow->coa_phase;
6276  REAL8 m1 = thisRow->mass1 * LAL_MSUN_SI;
6277  REAL8 m2 = thisRow->mass2 * LAL_MSUN_SI;
6278  REAL8 S1x = thisRow->spin1x;
6279  REAL8 S1y = thisRow->spin1y;
6280  REAL8 S1z = thisRow->spin1z;
6281  REAL8 S2x = thisRow->spin2x;
6282  REAL8 S2y = thisRow->spin2y;
6283  REAL8 S2z = thisRow->spin2z;
6284  REAL8 f_min = thisRow->f_lower;
6285  REAL8 f_ref = thisRow->f_final; // new line
6286 // REAL8 f_ref = 0.; // old line
6287  REAL8 distance = thisRow->distance * LAL_PC_SI * 1e6;
6288  REAL8 inclination = thisRow->inclination;
6289  LALDict *params = XLALCreateDict();
6290  XLALSimInspiralWaveformParamsInsertPNAmplitudeOrder(params, thisRow->amp_order);
6291 
6292  /* get approximant */
6293  approximant = (Approximant)XLALSimInspiralGetApproximantFromString(thisRow->waveform);
6294  if ( (int) approximant == XLAL_FAILURE)
6295  XLAL_ERROR(XLAL_EFUNC);
6296 
6297  if (approximant == NR_hdf5) {
6298  char *filepath = thisRow->numrel_data;
6299  XLALSimInspiralWaveformParamsInsertNumRelData(params, filepath);
6300  }
6301  /* get phase PN order; this is an enum such that the value is twice the PN order */
6302  order = (LALPNOrder)XLALSimInspiralGetPNOrderFromString(thisRow->waveform);
6303  if ( (int) order == XLAL_FAILURE)
6304  XLAL_ERROR(XLAL_EFUNC);
6305  XLALSimInspiralWaveformParamsInsertPNPhaseOrder(params, order);
6306 
6307  /* note: the condition waveform already does tapering... ignore any request to do so get taper option */
6308  /* taper = XLALGetTaperFromString(thisRow->taper); */
6309 
6310  /* generate +,x waveforms */
6311 #ifdef NEW_CODE_FOR_SEOBNRv4P_AND_SEOBNRv4PHM
6312  if (approximant == SEOBNRv4P || approximant == SEOBNRv4PHM) {
6313  ret = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, distance, inclination, phi0, 0.0, 0.0, 0.0, deltaT, f_min, f_ref, params, approximant);
6314  XLALDestroyDict(params);
6315  if( ret == XLAL_FAILURE )
6316  XLAL_ERROR(XLAL_EFUNC);
6317 
6318  const double extra_time_fraction = 0.1; /* fraction of waveform duration to add as extra time for tapering */
6319  const double extra_cycles = 3.0; /* more extra time measured in cycles at the starting frequency */
6320 
6321  /* upper bound on the chirp time starting at f_min */
6322  double tchirp = XLALSimInspiralChirpTimeBound(f_min, m1, m2, S1z, S2z);
6323 
6324  /* extra time to include for all waveforms to take care of situations
6325  * where the frequency is close to merger (and is sweeping rapidly):
6326  * this is a few cycles at the low frequency */
6327  double textra = extra_cycles / f_min;
6328 
6329  /* condition the time domain waveform by tapering in the extra time
6330  * at the beginning and high-pass filtering above original f_min */
6331  XLALSimInspiralTDConditionStage1(*hplus, *hcross, extra_time_fraction * tchirp + textra, f_min);
6332 
6333  /* final tapering at the beginning and at the end to remove filter transients */
6334 
6335  /* waveform should terminate at a frequency >= Schwarzschild ISCO
6336  * so taper one cycle at this frequency at the end; should not make
6337  * any difference to IMR waveforms */
6338  double fisco = 1.0 / (pow(6.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
6339  XLALSimInspiralTDConditionStage2(*hplus, *hcross, f_min, fisco);
6340  } else {
6341  ret = XLALSimInspiralTD(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, distance, inclination, phi0, 0.0, 0.0, 0.0, deltaT, f_min, f_ref, params, approximant);
6342  XLALDestroyDict(params);
6343  if( ret == XLAL_FAILURE )
6344  XLAL_ERROR(XLAL_EFUNC);
6345  }
6346 #else
6347 /*
6348  // used to select the higher-order modes (or subleading modes) of the gravitational wave radiation
6349  // only for SEOBNRv4HM_ROM approximant
6350  int ell_min = thisRow->numrel_mode_min; // this should really only ever be numrel_mode_min=2
6351  int ell_max = thisRow->numrel_mode_max;
6352  if((ell_min>=1 && ell_max<=5)&&(ell_min<=ell_max)) {
6353  cout << endl << "CWB::mdc::XLALInspiralTDWaveformFromSimInspiral - select modes " << ell_min << " " << ell_max << endl;
6354  LALValue* ModeArray = XLALSimInspiralCreateModeArray();
6355  for(int ell=ell_min; ell<=ell_max; ell++) {
6356  if(ell==1) XLALSimInspiralModeArrayActivateMode(ModeArray, 2, -1);
6357  else XLALSimInspiralModeArrayActivateMode(ModeArray, ell, -ell);
6358  }
6359  XLALSimInspiralWaveformParamsInsertModeArray(params, ModeArray);
6360  } else if(ell_min!=0 && ell_max!=0) {
6361  cout << endl << "CWB::mdc::XLALInspiralTDWaveformFromSimInspiral - error: select modes " << ell_min << " " << ell_max << endl;
6362  cout << "For SEOBNRv4_ROM the available modes are: 2,1,3,4,5 -> modes = [(2,-2),(2,-1),(3,-3),(4,-4),(5,-5)]" << endl << endl;
6363  exit(1);
6364  }
6365 */
6366  ret = XLALSimInspiralTD(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, distance, inclination, phi0, 0.0, 0.0, 0.0, deltaT, f_min, f_ref, params, approximant);
6367  XLALDestroyDict(params);
6368  if( ret == XLAL_FAILURE )
6369  XLAL_ERROR(XLAL_EFUNC);
6370 #endif
6371 #endif // endif lalinference_o2
6372 
6373  return XLAL_SUCCESS;
6374 }
6375 #endif
6376 
6377 #ifdef _USE_LAL
6378 void
6379 CWB::mdc::Posterior2XML(TString sampleFile, TString xmlFile, TString options) {
6380 //
6381 // sampleFile : input posterior sample file produced by PE
6382 // xmlFile : output xml file
6383 // options
6384 // --gps_start_time : gps start time
6385 // if(gps_start_time<=0) the posterior time is used
6386 // if gps_start_time>0 is integer (Ex: 123456789 without decimal point, NOT 123456789.) then
6387 // the GPS decimal part is taken from posterior time otherwise
6388 // is the decimal part defined in gps_start_time (Ex: 123456789.123 -> 0.123)
6389 // --gps_stop_time : gps stop time
6390 // --time_step : injection time step
6391 // --seed : if (<0) the parameters are read sequentially from posterior sample
6392 // : if (>0) the parameters are read randomly (uniformely with seed) from posterior sample
6393 // --waveform : if declared it overwrite the approximant declared in the posteriors
6394 // --source : if declared it is added to the SimInspiralTable->source (max length=20)
6395 // --ninjections : number of xml entries (only for gps_stop_time<=0)
6396 // --clb_file : if defined then it is used to dump the calibration parameters (same format as for posteriors sample)
6397 // --sample : values [map,maxl]. If defined only the map/maxl sample is used to create the xml file
6398 // --taper : taper string to be included in the XML file. Valid values are:
6399 // "TAPER_NONE","TAPER_START","TAPER_END","TAPER_STARTEND" -> see lalsimulation/src/LALSimInspiral.c
6400 // --f_lower : if defined it overwrite the value defined in the sampleFile file
6401 // --f_ref : if defined it overwrite the value defined in the sampleFile file
6402 // --pn_order : if defined it overwrite the value defined in the sampleFile file
6403 // --amp_order : if defined it overwrite the value defined in the sampleFile file
6404 //
6405 
6406  CWB::Toolbox TB;
6407 
6408  double gps_start_time=0, gps_stop_time=0, time_step = 0;
6409  int time_nsec = -1.;
6410  int seed = -1;
6411  int ninjections = 0;
6412 
6413  TString sgps_start_time = TB.getParameter(options,"--gps_start_time");
6414  if(sgps_start_time.IsDigit()) {
6415  gps_start_time = sgps_start_time.Atoi();
6416  } else if(sgps_start_time.IsFloat()) {
6417  gps_start_time = sgps_start_time.Atoi();
6418  sgps_start_time.Remove(0,sgps_start_time.Last('.'));
6419  time_nsec = int(1.e9*sgps_start_time.Atof());
6420  } else if(sgps_start_time!="") {
6421  cout << endl << "CWB::mdc::Posterior2XML - "
6422  << "Error : gps_start_time must be an interger number" << endl;
6423  return;
6424  }
6425 
6426  TString sgps_stop_time = TB.getParameter(options,"--gps_stop_time");
6427  if(sgps_stop_time.IsDigit()) {
6428  gps_stop_time = sgps_stop_time.Atoi();
6429  } else if(sgps_stop_time!="") {
6430  cout << endl << "CWB::mdc::Posterior2XML - "
6431  << "Error : gps_stop_time must be an interger number" << endl;
6432  return;
6433  }
6434 
6435  TString stime_step = TB.getParameter(options,"--time_step");
6436  if(stime_step.IsDigit()) {
6437  time_step = stime_step.Atoi();
6438  } else if(stime_step!="") {
6439  cout << endl << "CWB::mdc::Posterior2XML - "
6440  << "Error : time_step must be an interger number" << endl;
6441  return;
6442  }
6443 
6444  TString sseed = TB.getParameter(options,"--seed");
6445  if(sseed.IsDigit()) seed = sseed.Atoi();
6446 
6447  TString sninjections = TB.getParameter(options,"--ninjections");
6448  if(sninjections.IsDigit()) ninjections = sninjections.Atof();
6449 
6450  TString swaveform = TB.getParameter(options,"--waveform");
6451 
6452  TString ssource = TB.getParameter(options,"--source");
6453  if(ssource=="") ssource="NULL";
6454  if(ssource.Sizeof()>20) {
6455  cout << endl << "CWB::mdc::Posterior2XML - "
6456  << "Error : max source length is 20" << endl;
6457  return;
6458  }
6459 
6460  TString clb_file = TB.getParameter(options,"--clb_file"); // output calibration file
6461  TString extension = clb_file(clb_file.Last('.'),clb_file.Sizeof()-clb_file.Last('.')-1);
6462  if(extension!=".clb") {
6463  cout << "CWB::mdc::Posterior2XML - Error : Calibration file extension must be .clb" << endl;
6464  return;
6465  }
6466 
6467  TString sample_opt = TB.getParameter(options,"--sample");
6468  if(sample_opt!="" && sample_opt!="map" && sample_opt!="maxl" && !sample_opt.IsDigit()) {
6469  cout << endl << "CWB::mdc::Posterior2XML - "
6470  << "Error : wrong --sample option type, must be map/maxl or an integer number >=0" << endl;
6471  return;
6472  }
6473 
6474  TString taper = TB.getParameter(options,"--taper");
6475  if(taper!="" && taper!="TAPER_NONE" && taper!="TAPER_START" && taper!="TAPER_END" && taper!="TAPER_STARTEND") {
6476  cout << endl << "CWB::mdc::Posterior2XML - "
6477  << "Error : wrong --taper option type, must be TAPER_NONE,TAPER_START,TAPER_END,TAPER_STARTEND" << endl;
6478  return;
6479  }
6480 
6481  TString sf_lower = TB.getParameter(options,"--f_lower");
6482  float f_lower=-1.;
6483  if(sf_lower.IsFloat()) {
6484  f_lower = sf_lower.Atof();
6485  } else if(sf_lower!="") {
6486  cout << endl << "CWB::mdc::Posterior2XML - "
6487  << "Error : f_lower must be a float number" << endl;
6488  return;
6489  }
6490 
6491  TString sf_ref = TB.getParameter(options,"--f_ref");
6492  float f_ref=-1.;
6493  if(sf_ref.IsFloat()) {
6494  f_ref = sf_ref.Atof();
6495  } else if(sf_ref!="") {
6496  cout << endl << "CWB::mdc::Posterior2XML - "
6497  << "Error : f_ref must be a float number" << endl;
6498  return;
6499  }
6500 
6501  TString spn_order = TB.getParameter(options,"--pn_order");
6502  int pn_order_opt=-1;
6503  if(spn_order.IsDigit()) {
6504  pn_order_opt = spn_order.Atoi();
6505  } else if(spn_order!="") {
6506  cout << endl << "CWB::mdc::Posterior2XML - "
6507  << "Error : pn_order must be an interger number" << endl;
6508  return;
6509  }
6510  if(pn_order_opt!=-1 && swaveform!="") {
6511  cout << endl << "CWB::mdc::Posterior2XML - "
6512  << "Error : only one of the following options can be defined: --pn_order, --waveform" << endl;
6513  return;
6514  }
6515 
6516  TString samp_order = TB.getParameter(options,"--amp_order");
6517  int amp_order_opt=-1;
6518  if(samp_order.IsDigit()) {
6519  amp_order_opt = samp_order.Atoi();
6520  } else if(samp_order!="") {
6521  cout << endl << "CWB::mdc::Posterior2XML - "
6522  << "Error : amp_order must be an interger number" << endl;
6523  return;
6524  }
6525 
6526  if(gps_start_time>0) {
6527  if(gps_stop_time<gps_start_time) {
6528  cout << endl << "CWB::mdc::Posterior2XML - "
6529  << "Error : if gps_start_time>0 then gps_stop_time must be >= gps_start_time" << endl;
6530  return;
6531  }
6532  if(time_step<=0) {
6533  cout << endl << "CWB::mdc::Posterior2XML - "
6534  << "Error : if gps_start_time>0 then time_step must be > 0" << endl;
6535  return;
6536  }
6537  if(ninjections>0) {
6538  cout << endl << "CWB::mdc::Posterior2XML - "
6539  << "Error : if gps_start_time>0 then ninjections can not be declared" << endl;
6540  return;
6541  }
6542  // compute ninjections
6543  ninjections = int((gps_stop_time-gps_start_time)/time_step);
6544  } else {
6545  if(ninjections<=0) {
6546  cout << endl << "CWB::mdc::Posterior2XML - "
6547  << "Error : if gps_start_time<=0 then --ninjections option must be > 0" << endl;
6548  return;
6549  }
6550  }
6551 
6552  ifstream in;
6553  in.open(sampleFile.Data(),ios::in);
6554  if(!in.good()) {
6555  cout << endl << "CWB::mdc::Posterior2XML - "
6556  << "Error Opening File : " << sampleFile.Data() << endl;
6557  return;
6558  }
6559 
6560  // get header line from posteriors files
6561  char hline[4*1024];
6562  in.getline(hline,4*1024);
6563 
6564  // converts new json header format into posterior_samples.dat format
6565  // the conversion is reported in:
6566  // https://git.ligo.org/lscsoft/pesummary/blob/master/pesummary/gw/file/standard_names.py
6567  // sline.ReplaceAll("json header item","posterior_samples.dat header item");
6568  TString sline = TString("\t")+hline+TString("\t");
6569  sline.ReplaceAll("#","\t"); // remove initial comment character presents in the O1/O2 versions
6570  sline.ReplaceAll(" ","\t");
6571  sline.ReplaceAll("\treference_frequency\t","\tf_ref\t");
6572  sline.ReplaceAll("\tlambda_1\t","\tlambda1\t");
6573  sline.ReplaceAll("\tlambda_2\t","\tlambda2\t");
6574  sline.ReplaceAll("\tluminosity_distance\t","\tdist\t");
6575  sline.ReplaceAll("\tmass_ratio\t","\tq\t");
6576  sline.ReplaceAll("\tchirp_mass\t","\tmc\t");
6577  sline.ReplaceAll("\trightascension\t","\tra\t");
6578  sline.ReplaceAll("\tdeclination\t","\tdec\t");
6579  sline.ReplaceAll("\tcos_theta_jn\t","\tcostheta_jn\t");
6580  sline.ReplaceAll("\ttilt_1\t","\ttilt1\t");
6581  sline.ReplaceAll("\ttilt_2\t","\ttilt2\t");
6582  sline.ReplaceAll("\tcos_tilt_1\t","\tcostilt1\t");
6583  sline.ReplaceAll("\tcos_tilt_2\t","\tcostilt2\t");
6584  sline.ReplaceAll("\tphi_12\t","\tphi12\t");
6585  sline.ReplaceAll("\ta_1\t","\ta1\t");
6586  sline.ReplaceAll("\ta_2\t","\ta2\t");
6587  sline.ReplaceAll("\tspin_1z\t","\ta1z\t");
6588  sline.ReplaceAll("\tspin_2z\t","\ta2z\t");
6589  sline.ReplaceAll("\ta_1\t","\ta1\t");
6590  sline.ReplaceAll("\ta_2\t","\ta2\t");
6591  sline.ReplaceAll("\tmarginalized_phase\t","\tphase_maxl\t");
6592  sline.ReplaceAll("\tgeocent_time\t","\ttime\t");
6593  sline.ReplaceAll("\tmarginalized_geocent_time\t","\ttime_maxl\t");
6594  sline.ReplaceAll("\tlog_likelihood\t","\tlogl\t");
6595  sline.ReplaceAll("\tlog_prior\t","\tlogprior\t");
6596  sline.ReplaceAll("\tH1_time\t","\th1_end_time\t");
6597  sline.ReplaceAll("\tL1_time\t","\tl1_end_time\t");
6598  sline.ReplaceAll("\tV1_time\t","\tv1_end_time\t");
6599  sline.ReplaceAll("\tG1_time\t","\tg1_end_time\t");
6600  sline=sline(1,sline.Sizeof()-3); // remove initial and final \t
6601  if(sline!=hline) {
6602  cout << endl << "CWB::mdc::Posterior2XML - header converted " << endl;
6603  cout << endl << "before convertion:" << endl << hline << endl;
6604  cout << endl << "after convertion:" << endl << sline << endl << endl;
6605  }
6606  strcpy(hline,sline.Data());
6607 
6608  std::map<TString, int> hsample; // header sample
6609  TObjArray* token = TString(hline).Tokenize('\t');
6610  TString first_sheader="";
6611  for(int j=0;j<token->GetEntries();j++) {
6612  TString sheader = ((TObjString*)token->At(j))->GetString();
6613  sheader.ReplaceAll(" " ,"");
6614  // the first entry is used to check is an item is present. hsample["whatever itime not in the list"] returns 0
6615  // we move the first item to the end of the list
6616  if(j==0) {
6617  hsample[""] = j;
6618  first_sheader=sheader;
6619  } else {
6620  hsample[sheader] = j;
6621  }
6622  }
6623  hsample[first_sheader] = token->GetEntries();
6624 /*
6625  std::map<TString, int>::iterator iter;
6626  for (iter=hsample.begin(); iter!=hsample.end(); iter++) {
6627  cout << iter->first << "\t" << hsample[iter->first] << endl;
6628  }
6629 */
6630 
6631  // read samples from posteriors file
6632  std::vector<vector<double> > sample;
6633  int nsample=0;
6634  double value;
6635  int hsize=token->GetEntries();
6636  std::vector<double> vsample(hsample.size());
6637  while (1) {
6638  for(int i=0;i<hsize;i++) in >> vsample[i];
6639  vsample[hsize]=vsample[0]; // we move the first item to the end of the list (see comment above)
6640  if(!in.good()) break;
6641  sample.push_back(vsample);
6642  nsample++;
6643  }
6644  in.close();
6645  cout << endl << "CWB::mdc::Posterior2XML - "
6646  << "Read\t" << nsample << "\tsamples from posterior samples file" << endl;
6647 
6648  // if sample_opt is map then get the map sample index
6649  int mapSampleID=-1;
6650  if(sample_opt=="map") {
6651  double post_max=-1e+20;
6652  for(int i=0;i<sample.size();i++) {
6653  double post = -1;
6654  if(hsample["logpost"]) {
6655  post = sample[i][hsample["logpost"]];
6656  } else if(hsample["logprior"] && hsample["logl"]) {
6657  post = sample[i][hsample["logprior"]] + sample[i][hsample["logl"]];
6658  } else if(hsample["post"]) {
6659  post = sample[i][hsample["post"]];
6660  } else {
6661  cout << endl << "CWB::mdc::Posterior2XML - "
6662  << "Error : none of values used by map option are present in the sample header" << endl;
6663  return;
6664  }
6665  if(post>post_max) {post_max=post;mapSampleID=i;}
6666  }
6667  cout << endl << "CWB::mdc::Posterior2XML - found map sample id = " << mapSampleID << endl << endl;
6668  }
6669 
6670  // if sample_opt is maxl then get the maxL sample index
6671  int maxlSampleID=-1;
6672  if(sample_opt=="maxl") {
6673  double maxl_max=-1e+20;
6674  for(int i=0;i<sample.size();i++) {
6675  double maxl = -1;
6676  if(hsample["logl"]) {
6677  maxl = sample[i][hsample["logl"]];
6678  } else {
6679  cout << endl << "CWB::mdc::Posterior2XML - "
6680  << "Error : logl is not present in the sample header" << endl;
6681  return;
6682  }
6683  if(maxl>maxl_max) {maxl_max=maxl;maxlSampleID=i;}
6684  }
6685  cout << endl << "CWB::mdc::Posterior2XML - found maxl sample id = " << maxlSampleID << endl << endl;
6686  }
6687 
6688  // if sample_opt is a number then get its sample index
6689  int SampleID=-1;
6690  if(sample_opt.IsDigit()) {
6691  SampleID=sample_opt.Atoi();
6692  if(SampleID<0 || SampleID>=sample.size()) {
6693  cout << endl << "CWB::mdc::Posterior2XML - "
6694  << "Error : sample index is not valid. Allowed valued for this posterior sample file are [0," << sample.size()-1 << "]" << endl;
6695  return;
6696  }
6697  }
6698 
6699  // write clb header to calibration file
6700  ofstream clb;
6701  if(clb_file!="") {
6702  if(!clb_file.Contains(".clb")) {
6703  cout << endl << "CWB::mdc::Posterior2XML - "
6704  << "Error : calibration file extention must be .clb" << endl;
6705  return;
6706  }
6707  clb.open(clb_file.Data(),ios::out);
6708  if(!clb.good()) {
6709  cout << endl << "CWB::mdc::Posterior2XML - "
6710  << "Error Opening Output Calibration File : " << clb_file.Data() << endl;
6711  return;
6712  }
6713  clb.precision(18);
6714  clb << "time\t";
6715  std::map<TString, int>::iterator iter;
6716  for (iter=hsample.begin(); iter!=hsample.end(); iter++) {
6717  if(TString(iter->first).Contains("spcal")) clb << iter->first << "\t";
6718  }
6719  clb << "simulation_id";
6720  clb << endl;
6721  }
6722 
6723  static LALStatus status;
6724  LIGOLwXMLStream xmlfp;
6725  MetadataTable injections;
6726  SimInspiralTable *simTable; // see lalsuite include/lal/LIGOMetadataTables.h
6727 
6728  gps_start_time = int(gps_start_time/time_step)*time_step; // force gps_start_time to be an multiple of time_step
6729 
6730  wat::Time gpsStartTime(gps_start_time);
6731  wat::Time gpsEndTime(gps_stop_time);
6732  wat::Time currentGpsTime(gps_start_time);
6733  wat::Time timeStep(time_step);
6734 
6735  // create the first injection
6736  simTable = injections.simInspiralTable = (SimInspiralTable *) calloc( 1, sizeof(SimInspiralTable) );
6737 
6738 // if(seed>=0) gRandom->SetSeed(abs(seed));
6739  TRandom3 random(abs(seed));
6740 
6741  // loop over parameter generation until end time is reached
6742  int ninj = 0;
6743  int simulation_id = 0; // used to syncronize the calibration entries with the xml entries
6744  int initialNanoSeconds=-1;
6745  while(1) {
6746 
6747  int id = (seed>=0) ? gRandom->Uniform(0,sample.size()-1) : ninj;
6748  if(sample_opt=="map") id=mapSampleID;
6749  if(sample_opt=="maxl") id=maxlSampleID;
6750  if(sample_opt.IsDigit()) id=SampleID;
6751 
6752  // get posterior sample parameters
6753  std::map<TString, double> psample = GetPsample(hsample, sample[id], f_lower, f_ref);
6754  if(psample.size()==0) {
6755  ninj++;
6756  if(seed>=0) continue;
6757  else {if(ninj<sample.size()) continue; else break;}
6758  }
6759 
6760  // store tag in table
6761  char source_tag[30]; sprintf(source_tag,"#CWB:1:%s",ssource.Data());
6762  memcpy( simTable->source, source_tag, sizeof(CHAR) * LIGOMETA_SOURCE_MAX );
6763 
6764  // get time
6765  double time = psample["time"];
6766 
6767  // store time in table
6768  wat::Time iwtime(time);
6769  if(gps_start_time>0) {
6770  simTable->geocent_end_time.gpsSeconds = currentGpsTime.GetSec();
6771  if(time_nsec>=0) {
6772  simTable->geocent_end_time.gpsNanoSeconds = time_nsec;
6773  } else {
6774  simTable->geocent_end_time.gpsNanoSeconds = iwtime.GetNSec();
6775  // correct seconds when event times are gittering around the an integer (Ex: 1248242631.001, 1248242630.998, ...)
6776  if(initialNanoSeconds==-1) initialNanoSeconds=iwtime.GetNSec();
6777  int deltaNSec = int(iwtime.GetNSec())-initialNanoSeconds;
6778  if(deltaNSec> 500000000) simTable->geocent_end_time.gpsSeconds-=1;
6779  if(deltaNSec<-500000000) simTable->geocent_end_time.gpsSeconds+=1;
6780  }
6781  } else {
6782  simTable->geocent_end_time.gpsSeconds = iwtime.GetSec();
6783  simTable->geocent_end_time.gpsNanoSeconds = iwtime.GetNSec();
6784  }
6785  wat::Time owtime(simTable->geocent_end_time.gpsSeconds, simTable->geocent_end_time.gpsNanoSeconds);
6786 
6787  // populate detector times (used by CBC pipelines)
6788  wat::Time h_time(psample["h1_end_time"]);
6789  simTable->h_end_time.gpsSeconds = h_time.GetSec();
6790  simTable->h_end_time.gpsNanoSeconds = h_time.GetNSec();
6791 
6792  wat::Time l_time(psample["l1_end_time"]);
6793  simTable->l_end_time.gpsSeconds = l_time.GetSec();
6794  simTable->l_end_time.gpsNanoSeconds = l_time.GetNSec();
6795 
6796  wat::Time v_time(psample["v1_end_time"]);
6797  simTable->v_end_time.gpsSeconds = v_time.GetSec();
6798  simTable->v_end_time.gpsNanoSeconds = v_time.GetNSec();
6799 
6800  wat::Time g_time(psample["g1_end_time"]);
6801  simTable->g_end_time.gpsSeconds = g_time.GetSec();
6802  simTable->g_end_time.gpsNanoSeconds = g_time.GetNSec();
6803 
6804  // populate location
6805  simTable->longitude = psample["ra"];
6806  simTable->latitude = psample["dec"];
6807  simTable->polarization = psample["psi"];
6808  simTable->distance = psample["dist"];
6809 
6810  if(gps_start_time>0) {
6811  skymap sm;
6812  double gps_source = time;
6813  double phi_source = sm.RA2phi(simTable->longitude*180./TMath::Pi(), gps_source);
6814  double ra_source = sm.phi2RA(phi_source, owtime.GetDouble());
6815  if(ra_source>180) ra_source-=360.;
6816  simTable->longitude = ra_source*TMath::Pi()/180.;
6817  }
6818 
6819  // populate spins
6820  simTable->spin1x = psample["s1x"];
6821  simTable->spin1y = psample["s1y"];
6822  simTable->spin1z = psample["s1z"];
6823  simTable->spin2x = psample["s2x"];
6824  simTable->spin2y = psample["s2y"];
6825  simTable->spin2z = psample["s2z"];
6826 
6827  // populate masses
6828  simTable->mass1 = psample["m1"];
6829  simTable->mass2 = psample["m2"];
6830  simTable->mchirp = psample["mchirp"];
6831 
6832  // populate waveform and other parameters
6833  int approx = psample["approx"];
6834  int pn_order = psample["pn_order"];
6835  if(pn_order_opt>=0) pn_order = pn_order_opt; // it is overwritten by the value defined by user
6836  char waveform[256] = "";
6837  if(pn_order<0) {
6838  sprintf(waveform,"%s",XLALSimInspiralGetStringFromApproximant((Approximant)approx));
6839  } else {
6840  sprintf(waveform,"%s%s",XLALSimInspiralGetStringFromApproximant((Approximant)approx),XLALSimInspiralGetStringFromPNOrder((LALPNOrder)pn_order));
6841  }
6842  if(swaveform!="") sprintf(waveform,"%s",swaveform.Data()); // it is overwritten by the value defined by user
6843  memcpy( simTable->waveform, waveform, sizeof(CHAR) * LIGOMETA_WAVEFORM_MAX );
6844  //cout << "waveform : " << waveform << endl;
6845 
6846  simTable->f_lower = psample["flow"];
6847  if(f_lower>=0) simTable->f_lower = f_lower; // it is overwritten by the value defined by user
6848  simTable->f_final = psample["f_ref"];
6849  if(f_ref>=0) simTable->f_final = f_ref; // it is overwritten by the value defined by user
6850  simTable->amp_order = int(psample["amp_order"]);
6851  if(amp_order_opt>=0) simTable->amp_order = amp_order_opt; // it is overwritten by the value defined by user
6852  simTable->inclination = psample["iota"];
6853  simTable->coa_phase = psample["phase"];
6854 
6855  // populate tidal parameters (since there are not dedicated locations in the simTable we use qmParameter1,qmParameter2)
6856  simTable->alpha = psample["lambda1"];
6857  simTable->beta = psample["lambda2"];
6858 
6859  // populate logl and prior parameters. Such parameters are saved in simTable alpha1/2 unused locations.
6860  // The values alpha1/2 are then stored in the output mdc log string and can be use as cross check
6861  // to verify the the distribution of reconstructed samples wrt the injected samples
6862  simTable->alpha1 = psample["logl"];
6863  simTable->alpha2 = psample["post"];
6864 
6865 // simTable->event_id = (EventIDColumn *)LALCalloc(1, sizeof(EventIDColumn) );
6866 // memcpy( simTable->event_id->textId, "CALIBRATION=1234.56789", sizeof(CHAR) * LIGOMETA_UNIQUE_MAX );
6867 // simTable->event_id->next = NULL;
6868 
6869  // simTable->taper is empty then it initialized to TAPER_START (used in FD)
6870  if(TString(simTable->taper)=="") memcpy( simTable->taper, "TAPER_START", sizeof(CHAR) * LIGOMETA_INSPIRALTAPER_MAX );
6871  // if taper is define by user then it overwrite the simTable->taper value
6872  if(taper!="") memcpy( simTable->taper, taper.Data(), sizeof(CHAR) * LIGOMETA_INSPIRALTAPER_MAX );
6873 
6874  ninj++;
6875 
6876  bool isBreak=false;
6877  if(gps_start_time>0) {
6878  currentGpsTime+=timeStep;
6879  if((currentGpsTime>gpsEndTime) || (seed<0 && ninj>=sample.size())) isBreak=true;
6880  } else {
6881  if(ninj>=ninjections) isBreak=true;
6882  }
6883 
6884  // dump calib parameters to calibration file
6885  if(clb_file!="") {
6886  clb << std::scientific;
6887  clb << owtime.GetDouble() << "\t";
6888  std::map<TString, int>::iterator iter;
6889  for (iter=hsample.begin(); iter!=hsample.end(); iter++) {
6890  if(TString(iter->first).Contains("spcal")) clb << psample[iter->first] << "\t";
6891  }
6892  simTable->bandpass = simulation_id; // WARNING!!! used simTable->bandpass instead of simTable->simulation_id
6893  // because simulation_id is not defined in lalsuit branch lalinference_o2
6894  // simTable->bandpass is not used in CWB::mdc::FindChirpInjectSignals
6895  clb << simulation_id++;
6896  clb << endl;
6897  }
6898 
6899 
6900  if(isBreak) break;
6901 
6902  // allocate and go to next SimInspiralTable
6903  simTable = simTable->next = (SimInspiralTable *) calloc( 1, sizeof(SimInspiralTable) );
6904  }
6905 
6906  // close clb file
6907  if(clb_file!="") clb.close();
6908 
6909  // write xml file
6910  memset( &xmlfp, 0, sizeof(LIGOLwXMLStream) );
6911  LAL_CALL( LALOpenLIGOLwXMLFile( &status, &xmlfp, xmlFile.Data() ), &status );
6912  if(injections.simInspiralTable) {
6913  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, sim_inspiral_table ), &status );
6914  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, injections, sim_inspiral_table ), &status );
6915  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
6916  }
6917  LAL_CALL( LALCloseLIGOLwXMLFile ( &status, &xmlfp ), &status );
6918  LALCheckMemoryLeaks();
6919  cout << endl << "CWB::mdc::Posterior2XML - "
6920  << "Write\t" << ninj << "\tsamples to output xml file" << endl;
6921 
6922 }
6923 #endif
6924 
6925 #ifdef _USE_LAL
6926 std::map<TString, double>
6927 CWB::mdc::GetPsample(std::map<TString, int> hsample, vector<double> sample, float if_lower, float if_ref) {
6928 
6929  // ./lalapps/src/inspiral/inspinj.c
6930 
6931  std::map<TString, double> psample;
6932  std::map<TString, double> psample_null;
6933 
6934  bool check=false;
6935 
6936  int pn_order = hsample["lal_pnorder"] ? int(sample[hsample["lal_pnorder"]]) : -1;
6937  int amp_order = hsample["lal_amporder"] ? int(sample[hsample["lal_amporder"]]) : -1;
6938  int approx = hsample["lal_approximant"] ? int(sample[hsample["lal_approximant"]]) : IMRPhenomPv2;
6939 
6940  psample["pn_order"] = pn_order;
6941  psample["amp_order"] = amp_order;
6942  psample["approx"] = approx;
6943 
6944  //cout << "TEST APPROXIMANT " << approx << " " << NumApproximants << " " << IMRPhenomPv2 << endl;
6945 
6946  double flow = hsample["flow"] ? sample[hsample["flow"]] : 30.;
6947  double f_ref = hsample["f_ref"] ? sample[hsample["f_ref"]] : 30.;
6948 #ifdef NEW_CODE_FOR_SEOBNRv4P_AND_SEOBNRv4PHM
6949  flow = 2*flow /(2+psample["amp_order"]);
6950  f_ref = 2*f_ref/(2+psample["amp_order"]);
6951  psample["amp_order"] = 0; // is set to 0 because flow and f_ref already renormalized ???
6952 #endif
6953  if(if_lower>=0) flow = if_lower; // it is overwritten by the value defined by user
6954  if(if_ref>=0) f_ref = if_ref; // it is overwritten by the value defined by user
6955 
6956  psample["flow"] = flow;
6957  psample["f_ref"] = f_ref;
6958 
6959  double lambda1 = hsample["lambda1"] ? sample[hsample["lambda1"]] : 0.;
6960  double lambda2 = hsample["lambda2"] ? sample[hsample["lambda2"]] : 0.;
6961 
6962  psample["lambda1"] = lambda1;
6963  psample["lambda2"] = lambda2;
6964 
6965  psample["logl"] = hsample["logl"] ? sample[hsample["logl"]] : 0.;
6966  if(hsample["logpost"]) {
6967  psample["post"] = sample[hsample["logpost"]];
6968  } else if(hsample["logprior"] && hsample["logl"]) {
6969  psample["post"] = sample[hsample["logprior"]] + sample[hsample["logl"]];
6970  } else if(hsample["post"]) {
6971  psample["post"] = sample[hsample["post"]];
6972  } else psample["post"] = 0.;
6973 
6974  double dist = 0;
6975  int dist_check=0;
6976  if(hsample["distance"]) {dist = sample[hsample["distance"]];dist_check++;}
6977  if(hsample["dist"]) {dist = sample[hsample["dist"]];dist_check++;}
6978  if(hsample["logdistance"]) {dist = TMath::Exp(sample[hsample["logdistance"]]);dist_check++;}
6979  if(dist_check>1) {
6980  cout << endl << "CWB::mdc::Posterior2XML - "
6981  << "multiple definitions of distance in sample header " << endl;
6982  return psample_null;
6983  }
6984  if(dist==0) {
6985  cout << endl << "CWB::mdc::Posterior2XML - "
6986  << "distance not defined in sample header " << endl;
6987  return psample_null;
6988  }
6989  psample["dist"] = dist;
6990 
6991  double q = sample[hsample["q"]];
6992  double factor = sample[hsample["mc"]] * pow(1 + q, 1.0/5.0);
6993 
6994  double m1 = factor * pow(q, -3.0/5.0);
6995  double m2 = factor * pow(q, 2.0/5.0);
6996 
6997  double q1 = hsample["q1"] ? sample[hsample["q1"]] : 0.;
6998  double q2 = hsample["q2"] ? sample[hsample["q2"]] : 0.;
6999 
7000  double ra = sample[hsample["ra"]];
7001  double dec = sample[hsample["dec"]];
7002 
7003  double psi = hsample["psi"] ? sample[hsample["psi"]] : sample[hsample["polarization"]];
7004 
7005  psample["ra"] = ra;
7006  psample["dec"] = dec;
7007  psample["psi"] = psi;
7008 
7009  psample["q1"] = q1;
7010  psample["q2"] = q2;
7011 
7012  psample["m1"] = m1;
7013  psample["m2"] = m2;
7014  psample["mchirp"] = pow(m1*m2,3./5.)/pow(m1+m2,1./5.);
7015 
7016  // These are identical if non-precessing, in which case this will be overwritten
7017  double iota = -1;
7018  if(hsample["costheta_jn"]) {
7019  iota = TMath::ACos(sample[hsample["costheta_jn"]]);
7020  } else if(hsample["theta_jn"]) {
7021  iota = sample[hsample["theta_jn"]];
7022  } else {
7023  cout << endl << "CWB::mdc::Posterior2XML - "
7024  << "Error: costheta_jn or theta_jn not defined in posterior samples header file" << endl;
7025  return psample_null;
7026  }
7027 
7028  double phase;
7029  static bool phase_warning=true;
7030  if(hsample["phi_orb"]) {
7031  phase = sample[hsample["phi_orb"]];
7032  } else {
7033  if(hsample["phase"]) {
7034  phase = sample[hsample["phase"]];
7035  } else {
7036  phase = sample[hsample["phase_maxl"]];
7037  if(phase_warning) {
7038  cout << "WARNING: Samples already marginalized over phase." << endl;
7039  cout << " Begrudgingly using max loglikelihood estimates." << endl;
7040  phase_warning=false;
7041  }
7042  }
7043  }
7044  psample["phase"] = phase;
7045 
7046  double s1x=0, s1y=0, s1z = 0.;
7047  double s2x=0, s2y=0, s2z = 0.;
7048 
7049  // Try to treat this as a precessing analysis
7050  double theta_jn, phi_jl, tilt1, tilt2, phi12, a1, a2;
7051  if((hsample["theta_jn"]||hsample["costheta_jn"]) && hsample["phi_jl"]) {
7052 
7053  theta_jn = hsample["theta_jn"] ? sample[hsample["theta_jn"]] : TMath::ACos(sample[hsample["costheta_jn"]]);
7054  phi_jl = sample[hsample["phi_jl"]];
7055 
7056  if(hsample["tilt1"] && hsample["tilt2"]) {
7057  tilt1 = sample[hsample["tilt1"]];
7058  tilt2 = sample[hsample["tilt2"]];
7059  } else {
7060  tilt1 = TMath::ACos(sample[hsample["costilt1"]]);
7061  tilt2 = TMath::ACos(sample[hsample["costilt2"]]);
7062  }
7063 
7064  phi12 = sample[hsample["phi12"]];
7065  a1 = sample[hsample["a1"]];
7066  a2 = sample[hsample["a2"]];
7067 
7068 
7069  // routines for transforming initial conditions of precessing waveforms
7070  // include/lal/LALSimInspiral.h
7071  double phiRef=phase;
7072 #if LAL_VERSION_MAJOR == 6 && LAL_VERSION_MINOR == 16 && LAL_VERSION_MICRO == 1 // used only for tagged version lalinference_o2 used for O2 posteriors
7073  int ret = XLALSimInspiralTransformPrecessingNewInitialConditions(&iota, &s1x, &s1y, &s1z, &s2x, &s2y, &s2z, theta_jn,
7074  phi_jl, tilt1, tilt2, phi12, a1, a2, m1*LAL_MSUN_SI, m2*LAL_MSUN_SI, f_ref); // version used by ben farr
7075 #else
7076  int ret = XLALSimInspiralTransformPrecessingNewInitialConditions(&iota, &s1x, &s1y, &s1z, &s2x, &s2y, &s2z, theta_jn,
7077  phi_jl, tilt1, tilt2, phi12, a1, a2, m1*LAL_MSUN_SI, m2*LAL_MSUN_SI, f_ref, phiRef); // new version
7078 #endif
7079  if( ret==XLAL_FAILURE ) {
7080  cout << endl << "CWB::mdc::Posterior2XML - "
7081  << "Error in XLALSimInspiralTransformPrecessingNewInitialConditions" << endl;
7082  return psample_null;
7083  }
7084  //cout << "SPINS : " << iota << " " << s1x << " " << s1y << " " << s1z << " " << s2x << " " << s2y << " " << s2z << endl;
7085 
7086  } else {
7087 
7088  if(hsample["a1z"] && hsample["a2z"]) {
7089  s1z = sample[hsample["a1z"]];
7090  s2z = sample[hsample["a2z"]];
7091  } else {
7092  if(hsample["a1"] && hsample["a2"]) {
7093  s1z = sample[hsample["a1"]];
7094  s2z = sample[hsample["a2"]];
7095  } else {
7096  cout << endl << "CWB::mdc::Posterior2XML - "
7097  << "Error: It must be non-spinning !!!" << endl;
7098  }
7099  }
7100  }
7101 
7102  psample["iota"] = iota;
7103 
7104  psample["s1x"] = s1x;
7105  psample["s1y"] = s1y;
7106  psample["s1z"] = s1z;
7107  psample["s2x"] = s2x;
7108  psample["s2y"] = s2y;
7109  psample["s2z"] = s2z;
7110 
7111  double time;
7112  static bool time_warning=true;
7113  if(hsample["time"]) {
7114  time = sample[hsample["time"]];
7115  } else {
7116  time = sample[hsample["time_maxl"]];
7117  if(time_warning) {
7118  cout << "WARNING: Samples already marginalized over time." << endl;
7119  cout << " Begrudgingly using max loglikelihood estimates." << endl;
7120  time_warning=false;
7121  }
7122  }
7123  psample["time"] = time;
7124 
7125  if(hsample["h1_end_time"]) psample["h1_end_time"]=sample[hsample["h1_end_time"]]; else psample["h1_end_time"]=0.;
7126  if(hsample["l1_end_time"]) psample["l1_end_time"]=sample[hsample["l1_end_time"]]; else psample["l1_end_time"]=0.;
7127  if(hsample["v1_end_time"]) psample["v1_end_time"]=sample[hsample["v1_end_time"]]; else psample["v1_end_time"]=0.;
7128  if(hsample["g1_end_time"]) psample["g1_end_time"]=sample[hsample["g1_end_time"]]; else psample["g1_end_time"]=0.;
7129 
7130  // extract calibration parameters
7131  std::map<TString, int>::iterator iter;
7132  for (iter=hsample.begin(); iter!=hsample.end(); iter++) {
7133  if(TString(iter->first).Contains("spcal")) psample[iter->first] = sample[hsample[iter->first]];
7134  }
7135 
7136  return psample;
7137 }
7138 #endif
7139 
7140 #ifdef _USE_LAL
7141 //______________________________________________________________________________
7142 void
7143 CWB::mdc::CalibrateInspiral(wavearray<double>& w, TString ifo, double time, int simulation_id) {
7144 //
7145 // Apply calibration to the detector waveforms
7146 //
7147 //
7148 // Input: ifo - ifo label
7149 // time/simulation_id - GPS time/simulation_id use to extract the calibration parameters
7150 //
7151 // Output: w - wavearray which contains the calibrated waveform data
7152 //
7153 
7154  if(inspCLB=="") return;
7155 
7156  TString extension = inspCLB(inspCLB.Last('.'),inspCLB.Sizeof()-inspCLB.Last('.')-1);
7157  if(extension!=".clb") {
7158  cout << "CWB::mdc::CalibrateInspiral - Error : Calibration file extension must be .clb" << endl;
7159  exit(1);
7160  }
7161 
7162  ifstream in;
7163  in.open(inspCLB.Data(),ios::in);
7164  if(!in.good()) {
7165  cout << endl << "CWB::mdc::CalibrateInspiral - "
7166  << "Error Opening Calibration File : " << inspCLB.Data() << endl;
7167  exit(1);
7168  }
7169 
7170  std::map<TString, int> hsample; // header sample
7171 
7172  // get header line
7173  char hline[4*1024];
7174  in.getline(hline,4*1024);
7175 
7176  TObjArray* token = TString(hline).Tokenize('\t');
7177  TString first_sheader="";
7178  for(int j=0;j<token->GetEntries();j++) {
7179  TString sheader = ((TObjString*)token->At(j))->GetString();
7180  sheader.ReplaceAll(" " ,"");
7181  // the first entry is used to check is an item is present. hsample["whatever itime not in the list"] returns 0
7182  // we move the first item to the end of the list
7183  if(j==0) {
7184  hsample[""] = j;
7185  first_sheader=sheader;
7186  } else {
7187  hsample[sheader] = j;
7188  }
7189  }
7190  hsample[first_sheader] = token->GetEntries();
7191 
7192  // extract parameters at GPS=time with simulation_id value
7193  bool spcal = false;
7194  int hsize=token->GetEntries();
7195  std::vector<double> sample(hsample.size());
7196  while (1) {
7197  for(int i=0;i<hsize;i++) in >> sample[i];
7198  sample[hsize]=sample[0]; // we move the first item to the end of the list (see comment above)
7199  if(!in.good()) break;
7200  if((fabs(time-sample[hsample["time"]])<0.001)&&(simulation_id==sample[hsample["simulation_id"]])) {spcal=true;break;}
7201  }
7202  in.close();
7203 
7204  if(spcal) {
7205  printf("\nCWB::mdc::CalibrateInspiral - Calibration Found @ GPS time %10.6f\n",sample[hsample["time"]]);
7206  } else {
7207  return;
7208  }
7209 
7210  wavearray<double> logfreq;
7211  wavearray<double> amp;
7213 
7214  TString ifo_label=ifo;
7215  ifo_label.ToLower();
7216  if(sample[hsample["spcal_active"]]) {
7217  int spcal_npts = sample[hsample["spcal_npts"]];
7218  //cout << "spcal_npts : " << spcal_npts << endl;
7219  logfreq.resize(spcal_npts);
7220  amp.resize(spcal_npts);
7221  phase.resize(spcal_npts);
7222  for(int j=0;j<spcal_npts;j++) {
7223  logfreq[j] = log(sample[hsample[TString::Format("%s_spcal_freq_%d",ifo_label.Data(),j)]]);
7224  amp[j] = sample[hsample[TString::Format("%s_spcal_amp_%d",ifo_label.Data(),j)]];
7225  phase[j] = sample[hsample[TString::Format("%s_spcal_phase_%d",ifo_label.Data(),j)]];
7226  }
7227  }
7228 
7229  //for(int j=0;j<logfreq.size();j++) {
7230  // cout << ifo << "\t" << j << "\t" << exp(logfreq[j]) << "\t" << amp[j] << "\t" << phase[j] << endl;
7231  //}
7232 
7233 
7234  TSpline3 spamp("spamp",logfreq.data,amp.data,logfreq.size());
7235  TSpline3 spphs("spphs",logfreq.data,phase.data,logfreq.size());
7236 
7237  // apply calibration to waveform
7238  w.FFTW(1);
7239  TComplex C;
7240  double df = w.rate()/w.size();
7241  for (int i=0;i<(int)w.size()/2;i++) {
7242  double logF = log(i*df);
7243  if(logF<logfreq[0] || logF>logfreq[logfreq.size()-1]) continue; // exclude points outside the input freq range
7244  double dA = spamp.Eval(logF);
7245  double dP = spphs.Eval(logF);
7246  //cout << "1 -> " << exp(logF) << "\t" << dA << "\t" << dP << endl;
7247  //TComplex cal_factor = (1.0+dA)*TComplex(2.0,dP)/TComplex(2.0,-dP); // exp approximation used in gw_reconstruct package (Ben Farr))
7248  TComplex cal_factor = (1.0+dA)*C.Exp(TComplex(0.,dP));
7249  //cout << "2 -> " << exp(logF) << "\t" << cal_factor.Re() << "\t" << cal_factor.Im() << endl;
7250  TComplex W(w[2*i],w[2*i+1]);
7251  W=W*cal_factor; // calibrate
7252  w[2*i]=W.Re();
7253  w[2*i+1]=W.Im();
7254  }
7255  w.FFTW(-1);
7256 }
7257 #endif
7258 
7259 //______________________________________________________________________________
7262 //
7263 // Compute the cross correlation wavearray from w1,w2
7264 //
7265 //
7266 // Input: w1 - wavearray
7267 // w2 - wavearray
7268 //
7269 // return cross correlation wavearray
7270 
7271  if(w1.start()!=w2.start()) {
7272  cout << "CwB::mdc::GetXCorr error: start w1 != start w2" << endl;
7274  return w; // return empty wavearray
7275  }
7276  if(w1.size()!=w2.size()) {
7277  cout << "CwB::mdc::GetXCorr error: size w1 != size w2" << endl;
7279  return w; // return empty wavearray
7280  }
7281 
7282  int size = w1.size();
7283 
7284  wavearray<double> W1=w1; W1.FFTW(1);
7285  wavearray<double> W2=w2; W2.FFTW(1);
7286 
7287  wavearray<double> X(size);
7288  for(int i=0;i<size;i+=2) {
7289  complex<double> A(W1[i], W1[i+1]);
7290  complex<double> B(W2[i],-W2[i+1]); // conjugate
7291  complex<double> C = A*B;
7292  X[i] = C.real();
7293  X[i+1] = C.imag();
7294  }
7295  X.FFTW(-1);
7296 
7297  return X;
7298 }
7299 
7300 //______________________________________________________________________________
7303 //
7304 // align w1 wrt w2
7305 //
7306 //
7307 // Input: w1 - wavearray
7308 // w2 - wavearray
7309 //
7310 // Return aligned w
7311 //
7312 // Input w1,w2:
7313 //
7314 // |------- w1 ------|
7315 // |---------- w2 ------------|
7316 //
7317 // Output w:
7318 //
7319 // |000000000000000000-- w1 --|
7320 
7321  wavearray<double> w = *w2;
7322  w=0;
7323 
7324  if(w1==NULL) return w;
7325  if(w1->size()==0) return w;
7326 
7327  double R=w1->rate();
7328 
7329  double b_w1 = w1->start();
7330  double e_w1 = w1->start()+w1->size()/R;
7331  double b_w2 = w2->start();
7332  double e_w2 = w2->start()+w2->size()/R;
7333 
7334  int o_w1 = b_w1>b_w2 ? 0 : int((b_w2-b_w1)*R+0.5);
7335  int o_w2 = b_w1<b_w2 ? 0 : int((b_w1-b_w2)*R+0.5);
7336 
7337  double start = b_w1>b_w2 ? b_w1 : b_w2;
7338  double stop = e_w1<e_w2 ? e_w1 : e_w2;
7339  int size = int((stop-start)*R+0.5);
7340 
7341  for(int i=0;i<size;i++) w[i+o_w2] = w1->data[i+o_w1];
7342 
7343  return w;
7344 }
7345 
7346 //______________________________________________________________________________
7349 //
7350 // compute w1+w2
7351 //
7352 //
7353 // Input: w1 - wavearray
7354 // w2 - wavearray
7355 //
7356 // Return w1-w2
7357 //
7358 // Input w1,w2:
7359 //
7360 // |------- w1 ------|
7361 // |---------- w2 ---------------|
7362 //
7363 // Output w:
7364 //
7365 // |__ w1+w2 __|
7366 
7367  wavearray<double> x = *w2;
7368  x*=-1;
7369  return GetDiff(w1, &x);
7370 }
7371 
7372 //______________________________________________________________________________
7375 //
7376 // compute w1-w2
7377 //
7378 //
7379 // Input: w1 - wavearray
7380 // w2 - wavearray
7381 //
7382 // Return w1-w2
7383 //
7384 // Input w1,w2:
7385 //
7386 // |------- w1 ------|
7387 // |---------- w2 ---------------|
7388 //
7389 // Output w:
7390 //
7391 // |__ w1-w2 __|
7392 
7393  double R=w1->rate();
7394 
7395  double b_w1 = w1->start();
7396  double e_w1 = w1->start()+w1->size()/R;
7397  double b_w2 = w2->start();
7398  double e_w2 = w2->start()+w2->size()/R;
7399 
7400  int o_w1 = b_w1>b_w2 ? 0 : int((b_w2-b_w1)*R+0.5);
7401  int o_w2 = b_w1<b_w2 ? 0 : int((b_w1-b_w2)*R+0.5);
7402 
7403  double start = b_w1>b_w2 ? b_w1 : b_w2;
7404  double stop = e_w1<e_w2 ? e_w1 : e_w2;
7405  int size = int((stop-start)*R+0.5);
7406 
7407  wavearray<double> w(size);
7408  w=0.;
7409  w.rate(R);
7410  w.start(b_w1+double(o_w1)/R);
7411 
7412  for(int i=0;i<size;i++) w[i] = w1->data[i+o_w1] - w2->data[i+o_w2];
7413 
7414  return w;
7415 }
7416 
7417 //______________________________________________________________________________
7418 double
7419 CWB::mdc::GetTimeBoundaries(wavearray<double> x, double P, double& bT, double& eT, double T, double Q) {
7420 //
7421 // compute the symmetric time interval including the energy fraction (1-P)
7422 //
7423 //
7424 // Input: x - wavearray
7425 // P - energy fraction (0:1)
7426 // T - reference time
7427 // Q - left energy fraction (0:1), if Q<0 then Q=P
7428 //
7429 // Output: bT - interval begin time
7430 // eT - interval end time
7431 //
7432 // Return eT-bT
7433 //
7434 // if T not belongs to [tstart,tstop] then
7435 //
7436 // |------------ET-----------|
7437 // |xxx-------------------xxx|
7438 // bT <- -> eT
7439 //
7440 // where xxx is (1-P)/2 fraction of total energy ET
7441 //
7442 // if T belongs to [tstart,tstop] then
7443 //
7444 // |---------EL------|--ER---|
7445 // |xxxx-------------|-----xx|
7446 // bT <- T -> eT
7447 //
7448 // where xxx = EL*(1-P) : EL
7449 // where xx = ER*(1-Q) : ER
7450 //
7451 
7452  if(P<0) P=0;
7453  if(P>1) P=1;
7454 
7455  if(Q<0) Q=P;
7456  if(Q>1) Q=1;
7457 
7458  int size = x.size();
7459  double dt = 1./x.rate();
7460  double start = x.start();
7461  double stop = x.start()+size*dt;
7462 
7463  double E = 0;
7464  double ET = 0; // total energy
7465  for(int i=0;i<size;i++) {ET+=x[i]*x[i];}
7466 
7467  double EL=0;
7468  double ER=0;
7469  if((T>=start)&&(T<=stop)) {
7470  for(int i=0;i<size;i++) {
7471  double t=i*dt+start;
7472  if(t<T) EL+=x[i]*x[i]; else ER+=x[i]*x[i];
7473  }
7474  } else {
7475  EL=ER=ET/2;
7476  }
7477 
7478  double el = EL*(1-P); // left side energy
7479  double er = ER*(1-Q); // right side energy
7480 
7481  // search jB sample index which contains EL energy in the left side of the array
7482  E=0;
7483  int jB=0;
7484  for(int i=0;i<size;i++) {
7485  E+=x[i]*x[i];
7486  if(E>el) break;
7487  jB=i;
7488  }
7489 
7490  // search jE sample index which contains ER energy in the right side of the array
7491  E=0;
7492  int jE=size-1;
7493  for(int i=size-1;i>0;i--) {
7494  E+=x[i]*x[i];
7495  if(E>er) break;
7496  jE=i;
7497  }
7498 
7499  bT = start+jB*dt;
7500  eT = start+jE*dt;
7501 
7502  return eT-bT;
7503 }
7504 
7505 //______________________________________________________________________________
7506 double
7508 //
7509 // wavearray w1 is synchronized in phase wrt w2
7510 //
7511 //
7512 // Input: w1 - wavearray to be synchronized wrt w2
7513 // w2 - reference wavearray
7514 //
7515 // Output: sync_phase - synchronization phase
7516 //
7517 // return xcor after synchronization
7518 
7519  int size = w1.size();
7520 
7521  // get 90 deg phase shift wavearray
7522  wavearray<double> W1=w1; CWB::mdc::PhaseShift(W1,90.);
7523  wavearray<double> W2=w2; CWB::mdc::PhaseShift(W2,90.);
7524 
7525  // compute sync_phase
7526  double num=0;
7527  double den=0;
7528  for(int i=0;i<(int)w1.size();i++) {
7529  num+=w1[i]*W2[i]-W1[i]*w2[i];
7530  den+=w1[i]*w2[i]+W1[i]*W2[i];
7531  }
7532  sync_phase = TMath::ATan2(num,den);
7533  sync_phase*=180./TMath::Pi();
7534  CWB::mdc::PhaseShift(w1,-sync_phase);
7535 
7536  // compute sync_xcor w1*w2
7537  double sync_xcor=0.0;
7538  for(int i=0;i<size;i++) sync_xcor+=w1[i]*w2[i];
7539  sync_xcor*=1./(w1.rms()*sqrt(size));
7540  sync_xcor*=1./(w2.rms()*sqrt(size));
7541 
7542  return sync_xcor;
7543 }
7544 
7545 //______________________________________________________________________________
7546 void
7547 CWB::mdc::PhaseSync(wavearray<double>& w, double sync_phase) {
7548 //
7549 // wavearray w1 is shifted in time and phase
7550 //
7551 //
7552 // Input: w1 - wavearray
7553 // sync_phase - phase shift
7554 //
7555 // Output: w1 - time/phase shifted wavearray
7556 
7557  CWB::mdc::PhaseShift(w,-sync_phase);
7558 }
7559 
7560 //______________________________________________________________________________
7561 double
7563 //
7564 // wavearray w1 is synchronized in time wrt w2
7565 //
7566 //
7567 // Input: w1 - wavearray to be synchronized wrt w2
7568 // w2 - reference wavearray
7569 //
7570 // Output: sync_time - synchronization time
7571 //
7572 // return xcor after synchronization
7573 
7574  int size = w1.size();
7575 
7576  wavearray<double> X = GetXCorr(w1,w2);
7577 
7578  // compute max xcor -> sync_xcor
7579  double sync_xcor=-1.e-20;
7580  double isync_xcor=0;
7581  for(int i=0;i<size;i++) if(X[i]>sync_xcor) {isync_xcor=i;sync_xcor=X[i];}
7582  sync_xcor*=1./(w1.rms()*sqrt(size));
7583  sync_xcor*=1./(w2.rms()*sqrt(size));
7584  sync_xcor*=size;
7585 
7586  // compute sync_time
7587  int isync_time = isync_xcor<size/2 ? -isync_xcor : size-isync_xcor;
7588  sync_time = isync_time/w1.rate();
7589  CWB::mdc::TimeShift(w1,sync_time);
7590 
7591  return sync_xcor;
7592 }
7593 
7594 void
7595 CWB::mdc::TimeSync(wavearray<double>& w, double sync_time) {
7596 //
7597 // wavearray w1 is shifted in time and phase
7598 //
7599 //
7600 // Input: w1 - wavearray
7601 // sync_phase - phase shift
7602 //
7603 // Output: w1 - time/phase shifted wavearray
7604 
7605  CWB::mdc::TimeShift(w,sync_time);
7606 }
7607 
7608 //______________________________________________________________________________
7609 double
7610 CWB::mdc::TimePhaseSync(wavearray<double>& w1, wavearray<double>& w2, double& sync_time, double& sync_phase) {
7611 //
7612 // wavearray w1 is synchronized in time and phase wrt w2
7613 //
7614 //
7615 // Input: w1 - wavearray to be synchronized wrt w2
7616 // w2 - reference wavearray
7617 //
7618 // Output: sync_time - synchronization time
7619 // sync_phase - synchronization phase
7620 //
7621 // return xcor after synchronization
7622 
7623  int size = w1.size();
7624 
7625  // get 90 deg phase shift wavearray
7626  wavearray<double> W1=w1; CWB::mdc::PhaseShift(W1,90.);
7627  wavearray<double> W2=w2; CWB::mdc::PhaseShift(W2,90.);
7628 
7629  wavearray<double> w1W2 = GetXCorr(w1,W2);
7630  wavearray<double> W1w2 = GetXCorr(W1,w2);
7631  wavearray<double> w1w2 = GetXCorr(w1,w2);
7632  wavearray<double> W1W2 = GetXCorr(W1,W2);
7633 
7634  wavearray<double> phase(size);
7635  for(int i=0;i<size;i++) phase[i] = TMath::ATan2(w1W2[i]-W1w2[i],w1w2[i]+W1W2[i]);
7636 
7637  wavearray<double> z1(size);
7638  for(int i=0;i<size;i++) z1[i] = w1w2[i]*cos(phase[i])-W1w2[i]*sin(phase[i]);
7639 
7640  double sync_xcor=-1.e-20;
7641  double isync_xcor=0;
7642  for(int i=0;i<size;i++) if(z1[i]>sync_xcor) {isync_xcor=i;sync_xcor=z1[i];}
7643 
7644  int isync_time = isync_xcor<size/2 ? -isync_xcor : size-isync_xcor;
7645  sync_time = isync_time/w1.rate();
7646  CWB::mdc::TimeShift(w1,sync_time);
7647 
7648  int isync_phase = isync_xcor;
7649  sync_phase = phase[isync_phase]*180./TMath::Pi();
7650  CWB::mdc::PhaseShift(w1,-sync_phase);
7651 
7652  sync_xcor=0;
7653  for(int i=0;i<size;i++) sync_xcor+=w1[i]*w2[i];
7654  sync_xcor*=1./(w1.rms()*sqrt(size));
7655  sync_xcor*=1./(w2.rms()*sqrt(size));
7656 
7657  return sync_xcor;
7658 }
7659 
7660 //______________________________________________________________________________
7661 void
7662 CWB::mdc::TimePhaseSync(wavearray<double>& w, double sync_time, double sync_phase) {
7663 //
7664 // wavearray w1 is shifted in time and phase
7665 //
7666 //
7667 // Input: w1 - wavearray
7668 // sync_time - time shift
7669 // sync_phase - phase shift
7670 //
7671 // Output: w1 - time/phase shifted wavearray
7672 
7673  CWB::mdc::TimeShift(w,sync_time);
7674  CWB::mdc::PhaseShift(w,-sync_phase);
7675 }
7676 
7677 //______________________________________________________________________________
7678 int
7680 //
7681 // align w2 wrt w1
7682 //
7683 //
7684 // Input: w1 - wavearray
7685 // w2 - wavearray
7686 //
7687 // Output: w1,w2 - aligned wavarrays
7688 //
7689 // Return no errors -> 0, errors -> -1 and output empty w1,w2
7690 //
7691 // Input:
7692 //
7693 // |------- w1 ------|
7694 // |---------- w2 ---------|
7695 //
7696 // Output:
7697 //
7698 // |000000000000000000------- w1 ------|
7699 // |---------- w2 ----------00000000000|
7700 
7702 
7703  if(w1.size()==0) {cout << "CWB::mdc::Align - Error: w1 size is 0" << endl;w1=w;w2=w;return -1;}
7704  if(w2.size()==0) {cout << "CWB::mdc::Align - Error: w2 size is 0" << endl;w1=w;w2=w;return -1;}
7705  if(w1.rate()!=w2.rate()) {cout << "CWB::mdc::Align - Error: w1 rate != w2 rate" << endl;w1=w;w2=w;return -1;}
7706 
7707  double R=w1.rate();
7708 
7709  double b_w1 = w1.start();
7710  double e_w1 = w1.start()+w1.size()/R;
7711  double b_w2 = w2.start();
7712  double e_w2 = w2.start()+w2.size()/R;
7713 
7714  double b_w = b_w1<b_w2 ? b_w1 : b_w2;;
7715  double e_w = e_w1>e_w2 ? e_w1 : e_w2;;
7716 
7717  int o_w1 = b_w1<b_w2 ? 0 : int((b_w1-b_w2)*R+0.5);
7718  int o_w2 = b_w2<b_w1 ? 0 : int((b_w2-b_w1)*R+0.5);
7719 
7720  w.rate(R);
7721  w.resize(int(R*((e_w-b_w)+0.5)));
7722  w.start(b_w);
7723 
7724  w=0.;
7725  for(int i=0;i<w1.size();i++) w[i+o_w1] = w1[i];
7726  w1=w;
7727 
7728  w=0.;
7729  for(int i=0;i<w2.size();i++) w[i+o_w2] = w2[i];
7730  w2=w;
7731 
7732  return 0;
7733 }
7734 
7735 //______________________________________________________________________________
7736 double
7738  vector<double> tstart, vector<double> tstop) {
7739 //
7740 // compute match factor between vector of wavearrays w1 and w2
7741 // - vector size is the number of detectors
7742 //
7743 // Input: match - ff/of/re: fitting-factor/overlap-factor/residual-energy
7744 // w1 - wavearray vector
7745 // w2 - wavearray vector - is the reference wavearray
7746 // tstart - vector of start times used in the match computation (if tstart.size()=0 then tstart is the start time of the array)
7747 // tstop - vector of stop times used in the match computation (if tstop.size()=0 then tstop is the stop time of the array)
7748 //
7749 // Output: - return match value
7750 
7751 
7752  int vsize=w1.size();
7753  // vector wavearray size consistency
7754  if(w2.size()!=vsize) {
7755  cout << "CWB::mdc::GetMatchFactor - Error: input vectors wavearray are inconsistents, different size" << endl;
7756  return std::numeric_limits<double>::max();
7757  }
7758  // vector tstart size consistency
7759  if((tstart.size()>0) && (tstart.size()!=vsize)) {
7760  cout << "CWB::mdc::GetMatchFactor - Error: input vectors tstart are inconsistents, different size" << endl;
7761  return std::numeric_limits<double>::max();
7762  }
7763  // vector tstop size consistency
7764  if((tstop.size()>0) && (tstop.size()!=vsize)) {
7765  cout << "CWB::mdc::GetMatchFactor - Error: input vectors tstop are inconsistents, different size" << endl;
7766  return std::numeric_limits<double>::max();
7767  }
7768  // check if vsize>0
7769  if(vsize==0) {
7770  cout << "CWB::mdc::GetMatchFactor - Error: input vectors are empty" << endl;
7771  return std::numeric_limits<double>::max();
7772  }
7773  double rate=w1[0].rate();
7774  // wavearray rate consistency
7775  for(int n=0;n<vsize;n++) {
7776  if((w1[n].rate()!=rate)||(w2[n].rate()!=rate)) {
7777  cout << "CWB::mdc::GetMatchFactor - Error: input wavearray are inconsistents, different rate" << endl;
7778  return std::numeric_limits<double>::max();
7779  }
7780  }
7781  double size=w1[0].size();
7782  // wavearray size consistency
7783  for(int n=0;n<vsize;n++) {
7784  if((w1[n].size()!=size)||(w2[n].size()!=size)) {
7785  cout << "CWB::mdc::GetMatchFactor - Error: input wavearray are inconsistents, different size" << endl;
7786  return std::numeric_limits<double>::max();
7787  }
7788  }
7789  double start=w1[0].start();
7790  // wavearray start time consistency
7791  for(int n=0;n<vsize;n++) {
7792  if((w1[n].start()!=start)||(w2[n].start()!=start)) {
7793  cout << "CWB::mdc::GetMatchFactor - Error: input wavearray are inconsistents, different start time" << endl;
7794  return std::numeric_limits<double>::max();
7795  }
7796  }
7797 
7798  double dt = 1./rate;
7799 
7800  if(tstart.size()==0) {tstart.resize(vsize); for(int n=0;n<vsize;n++) tstart[n]=start;}
7801  if(tstop.size()==0) {tstop.resize(vsize); for(int n=0;n<vsize;n++) tstop[n] =start+size*dt;}
7802 
7803  double ew1=0; // w1 energy
7804  double ew2=0; // w2 energy
7805  double ew12=0; // w1,w2 coherent energy
7806  double re=0; // residual energy
7807  for(int n=0;n<vsize;n++) {
7808  for(int j=0;j<size;j++) {
7809  double t=j*dt+start;
7810  if((t<=tstart[n])||(t>tstop[n])) continue;
7811  ew1 += w1[n][j]*w1[n][j];
7812  ew2 += w2[n][j]*w2[n][j];
7813  ew12 += w1[n][j]*w2[n][j];
7814  re += pow(w1[n][j]-w2[n][j],2);
7815  }
7816  }
7817 
7818  if((match=="ff")&&(ew1*ew2==0)) return std::numeric_limits<double>::max();
7819  if((match=="of")&&(ew2==0)) return std::numeric_limits<double>::max();
7820 
7821  if(match=="ff") return ew12/sqrt(ew1*ew2); // fitting factor
7822  if(match=="of") return ew12/sqrt(ew2*ew2); // overlap factor
7823  if(match=="re") return re; // residual energy
7824 }
7825 
7826 //______________________________________________________________________________
7829 //
7830 // compute the envelope of wavearray x
7831 //
7832 // Input:
7833 // x - input wavearray
7834 //
7835 // Output:
7836 // xq - return the envelope of wavearray x
7837 
7838  wavearray<double> xq; // quadrature
7839 
7840  if(x==NULL) return xq;
7841  if(x->size()==0) return xq;
7842 
7843  // get quadrature
7844  xq = *x;
7845  CWB::mdc::PhaseShift(xq,90);
7846 
7847  // get envelope
7848  for(int i=0;i<x->size();i++) xq[i] = sqrt(pow(x->data[i],2)+pow(xq[i],2));
7849 
7850  return xq;
7851 }
7852 
7853 //______________________________________________________________________________
7856 //
7857 // compute the spectrum of wavearray x
7858 //
7859 // Input:
7860 // x - input wavearray
7861 // oneside- trie/false(default) -> one-side/double-side
7862 //
7863 // Output:
7864 // xs - return the spectrum of wavearray x
7865 
7866  wavearray<double> xs = *x;
7867 
7868  if(x==NULL) return xs;
7869  if(x->size()==0) return xs;
7870 
7871  double dt = xs.rate();
7872  int size = xs.size()-xs.size()%2; // size even
7873 
7874  wavearray<double> xa(size);
7875  double df=(double)xs.rate()/(double)xs.size();
7876  xs.FFTW(1);
7877  for (int i=0;i<size;i+=2) xa.data[i/2]=sqrt(pow(xs.data[i],2)+pow(xs.data[i+1],2));
7878  for (int i=0;i<size/2;i++) xs.data[i]=xa.data[i]*(1./df); // double side spectra 1/Hz
7879  if(oneside) for(int i=0;i<size/2;i++) xs.data[i]*=sqrt(2.); // one side spectra 1/Hz
7880  xs.resize(size/2.);
7881  xs.start(0);
7882  xs.rate(1./df);
7883 
7884  return xs;
7885 }
7886 
7887 //______________________________________________________________________________
7889 CWB::mdc::GetBandpass(wavearray<double> x, double bF, double eF) {
7890 //
7891 // apply bandpass cut to wavearray x
7892 //
7893 // Input:
7894 // x - input wavearray
7895 // bF,eF - bandpass frequency range [bF,eF]
7896 //
7897 // Output:
7898 // y - return bandpass x wavearray
7899 
7901 
7902  // cut frequency range bF,eF
7903  double F=0.;
7904  double dF=(y.rate()/(double)y.size())/2.;
7905  y.FFTW(1);
7906  for(int j=0;j<y.size();j+=2) {
7907  F = j*dF;
7908  if(F<bF || F>eF) {y[j]=0;y[j+1]=0;}
7909  }
7910  y.FFTW(-1);
7911 
7912  return y;
7913 }
7914 
7915 //______________________________________________________________________________
7916 double
7917 CWB::mdc::GetFrequencyBoundaries(wavearray<double> x, double P, double& bF, double& eF) {
7918 //
7919 // compute the symmetric frequency interval including the energy fraction P
7920 //
7921 //
7922 // Input: x - wavearray
7923 // P - energy fraction (0:1)
7924 //
7925 // Output: bF - interval begin frequency
7926 // eF - interval end frequency
7927 
7928  x.FFTW(1);
7929 
7930  if(P<0) P=0;
7931  if(P>1) P=1;
7932 
7933  int N = x.size();
7934 
7935  double E = 0;
7936  double ET = 0; // signal energy
7937  for(int i=0;i<N;i++) {ET+=x[i]*x[i];}
7938 
7939  double EF = ET*(1-P);
7940 
7941  // search jB sample index which contains EF/2 energy in the left side of the signal
7942  E=0;
7943  int jB=0;
7944  for(int i=0;i<N;i++) {
7945  E+=x[i]*x[i];
7946  if(E>EF/2) break;
7947  jB=i;
7948  }
7949 
7950  // search jE sample index which contains EF/2 energy in the right side of the signal
7951  E=0;
7952  int jE=0;
7953  for(int i=N-1;i>0;i--) {
7954  E+=x[i]*x[i];
7955  if(E>EF/2) break;
7956  jE=i;
7957  }
7958 
7959  double dF=(x.rate()/(double)x.size())/2.;
7960 
7961  bF = jB*dF;
7962  eF = jE*dF;
7963 
7964  return eF-bF;
7965 }
7966 
7967 #ifdef _USE_LAL
7968 double
7969 CWB::mdc::SimIMRSEOBNRv4ROMTimeOfFrequency(double freq, double m1, double m2, double chi1, double chi2) {
7970 //
7971 // wrapper to XLALSimIMRSEOBNRv4ROMTimeOfFrequency LAL function
7972 // Compute the 'time' elapsed in the ROM waveform from a given starting frequency until the ringdown (model SEOBNRv4_ROM)
7973 // lalsimulation/src/LALSimIMRSEOBNRv4ROM.c
7974 // include/lal/LALSimIMR.h
7975 // int XLALSimIMRSEOBNRv4ROMTimeOfFrequency(REAL8 *t, REAL8 frequency, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2);
7976 //
7977 //
7978 // Input: freq - frequency (Hz)
7979 // m1,m2 - mass components in solar mass
7980 // chi1,chi2 - Dimensionless aligned spinz components
7981 //
7982 // Output: time - time (sec) of 2,2 mode at frequency freq
7983 //
7984 
7985  double Mo = watconstants::SolarMass();
7986 
7987  REAL8 time;
7988  if(XLALSimIMRSEOBNRv4ROMTimeOfFrequency(&time, freq, m1*Mo, m2*Mo, chi1, chi2) == XLAL_FAILURE) {
7989  cout << "CWB::mdc::XLALSimIMRSEOBNRv4ROMTimeOfFrequency error" << endl;
7990  return -1;;
7991  }
7992 
7993  return time;
7994 }
7995 
7996 double
7997 CWB::mdc::SimIMRSEOBNRv4ROMFrequencyOfTime(double time, double m1, double m2, double chi1, double chi2) {
7998 //
7999 // wrapper to XLALSimIMRSEOBNRv4ROMFrequencyOfTime LAL function
8000 // Compute the starting frequency so that the given amount of 'time' elapses in the ROM waveform from the starting frequency until the ringdown.
8001 // lalsimulation/src/LALSimIMRSEOBNRv4ROM.c
8002 // include/lal/LALSimIMR.h
8003 // int XLALSimIMRSEOBNRv4ROMFrequencyOfTime(REAL8 *frequency, REAL8 t, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2);
8004 //
8005 //
8006 // Input: time - time (sec)
8007 // m1,m2 - mass components in solar mass
8008 // chi1,chi2 - Dimensionless aligned spinz components
8009 //
8010 // Output: freq - freq (Hz) of 2,2 mode at time 'time'
8011 //
8012 
8013  double Mo = watconstants::SolarMass();
8014 
8015  REAL8 freq;
8016 
8017  if(XLALSimIMRSEOBNRv4ROMFrequencyOfTime(&freq, time, m1*Mo, m2*Mo, chi1, chi2) == XLAL_FAILURE) {
8018  cout << "CWB::mdc::XLALSimIMRSEOBNRv4ROMFrequencyOfTime error" << endl;
8019  return -1;
8020  }
8021 
8022  return freq;
8023 }
8024 #endif
TVector3 xyz
MDC_DISTRIBUTION
Definition: mdc.hh:176
wavearray< double > t(hp.size())
MDC_DRAW
Definition: mdc.hh:201
std::vector< char * > ifoName
Definition: network.hh:609
size_t mdcTypeSize()
Definition: network.hh:410
detector * getifo(size_t n)
param: detector index
Definition: network.hh:436
void Dump(TString fname, int ID, int id, TString polarization)
Definition: mdc.cc:4394
int id
Definition: mdc.hh:210
double pc
Definition: DrawEBHH.C:15
double rho
detectorParams getDetectorParams()
Definition: detector.cc:218
#define EPZOOM
Definition: mdc.hh:146
int ID
Definition: mdc.hh:239
waveform GetSourceWaveform(int &ID, int &id)
Definition: mdc.cc:2040
TObjString * tdist
Definition: ConvertGWGC.C:42
TString sky_file
Definition: mdc.hh:505
TString inspCLB
Definition: mdc.hh:528
Definition: mdc.hh:202
double xgc
static const double C
Definition: GNGen.cc:28
double GetInjHrss()
Definition: mdc.hh:310
#define MDC_INJ_RATE
Definition: mdc.hh:139
int noverlap
Definition: TestDelta.C:20
TString inspDIR
Definition: mdc.hh:530
TString ofName
static double g(double e)
Definition: GNGen.cc:116
TString GetDateString()
Definition: time.cc:461
double M
Definition: DrawEBHH.C:13
void Init()
Definition: ChirpMass.C:284
watplot * Draw(TString name, int id=0, TString polarization="hp", MDC_DRAW type=MDC_TIME, TString options="ALP", Color_t color=kBlack)
Definition: mdc.cc:2317
double duration
par [0] value
double ygc
Definition: mdc.hh:219
double gc_theta
bool status
Definition: mdc.hh:221
vector< mdcpar > sky_parms
Definition: mdc.hh:507
size_t add(detector *)
param: detector structure return number of detectors in the network
Definition: network.cc:2559
static double GetTimeRange(wavearray< double > x, double &tMin, double &tMax, double efraction=EPZOOM)
Definition: mdc.cc:2860
std::vector< float > psiList
Definition: mdc.hh:512
size_t readMDClog(char *, double=0., int=11, int=12)
param: MDC log file param: approximate gps time
Definition: network.cc:3370
TString Get(wavearray< double > &x, TString ifo)
Definition: mdc.cc:1529
TString inspOptions
Definition: mdc.hh:532
#define GA_FORMULA_WNB
Definition: mdc.cc:3049
Definition: ced.hh:42
double dist
Definition: ConvertGWGC.C:48
double min(double x, double y)
Definition: eBBH.cc:31
int offset
Definition: TestSTFT_2.C:19
std::vector< std::string > mdcList
Definition: mdc.hh:389
double fHigh
virtual void rate(double r)
Definition: wavearray.hh:141
#define MDC_INJ_LENGTH
Definition: mdc.hh:141
float factor
TCanvas * c2
#define MNGD_Md2
Definition: mdc.cc:3416
char logFile[1024]
Definition: cwb_merge_log.C:31
double m1
wavearray< double > a(hp.size())
static double GetCentralTime(wavearray< double > x)
Definition: mdc.cc:2790
int error
Definition: cwb_compile.C:43
WSeries< float > v[nIFO]
Definition: cwb_net.C:80
Definition: mdc.hh:158
Definition: mdc.hh:207
par [0] name
#define B
int n
Definition: cwb_net.C:28
Definition: mdc.hh:203
Definition: mdc.hh:181
wavearray< double > z
Definition: Test10.C:32
double rho_min
double olatitude
double imag() const
Definition: wavecomplex.hh:70
char * watversion(char c='s')
Definition: watversion.hh:21
TString("c")
std::vector< std::string > mdcType
Definition: mdc.hh:390
void output(TTree *, network *, double, bool=true)
Definition: injection.cc:602
wavearray< double > GetSGQ(double frequency, double Q)
Definition: mdc.cc:3005
int ID
Definition: TestMDC.C:70
ofstream out
Definition: cwb_merge.C:214
static void PhaseShift(wavearray< double > &x, double pShift=0.)
Definition: mdc.cc:2955
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 frequency
double phase
INT_4U GetNSec()
Definition: time.cc:654
TF3 * gd3
double SolarMass()
Definition: constants.hh:202
unsigned int srcList_seed
Definition: mdc.hh:525
void GetSourceCoordinates(double &theta, double &phi, double &psi, double &rho, double &iota, double &hrss, int &ID, int &id)
Definition: mdc.cc:1989
double GetInjRate()
Definition: mdc.hh:313
double amplitude
float theta
int nfact
Definition: TestDelta.C:18
int nfft
Definition: TestDelta.C:19
network * net
Definition: mdc.hh:499
TString xmlFile
Definition: Posterior2XML.C:34
std::vector< double > gpsList
Definition: mdc.hh:516
Complex Exp(double phase)
Definition: numpy.cc:51
TH2F * ph
CWB::Toolbox TB
TString waveName
Definition: mdc.hh:533
static void AddExp(wavearray< double > &td, double v, int M)
Definition: mdc.cc:3250
double ilatitude
MDC_TYPE
Definition: mdc.hh:148
double epzoom
Definition: mdc.hh:538
wavearray< double > GetGA(double duration)
Definition: mdc.cc:3130
Long_t flags
std::vector< float > phList
Definition: mdc.hh:511
std::vector< std::string > mdcType
Definition: network.hh:613
wavearray< double > hp
Definition: mdc.hh:226
double inj_rate
Definition: mdc.hh:520
waveform wf
void Draw(int dpaletteId=1, Option_t *option="colfz")
Definition: gskymap.cc:460
int polarization
std::vector< int > IDList
Definition: mdc.hh:517
double olongitude
Long_t size
wavearray< double > hp
Definition: DrawInspiral.C:43
char refIFO[4]
Definition: test_config1.C:14
void setPolarization(POLARIZATION polarization=TENSOR)
Definition: detector.hh:306
TTree * setTree()
Definition: injection.cc:223
int m
Definition: cwb_net.C:28
virtual void start(double s)
Definition: wavearray.hh:137
std::vector< size_t > mdc__ID
Definition: network.hh:615
int j
Definition: cwb_net.C:28
i drho i
double longitude
Definition: detector.hh:52
#define MNGD_DENOMINATOR
Definition: mdc.cc:3411
void SetGridxColor(Color_t colorGridx=kBlack)
Definition: gskymap.hh:142
TList * list
static bool checkFile(TString fName, bool question=false, TString message="")
Definition: Toolbox.cc:4670
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
int isize
std::vector< detector * > ifoList
Definition: network.hh:608
double GetDelay(TString ifo1, TString ifo2, double phi, double theta)
Definition: mdc.cc:4523
#define N
watplot * DrawTime(wavearray< double > &x, TString options="ALP", Color_t color=kBlack)
Definition: mdc.cc:2410
watplot * pts
Definition: mdc.hh:542
mdc & operator=(const mdc &)
Definition: mdc.cc:305
cout<< "SNR "<< xsnr<< endl;wavearray< double > f
Definition: ComputeSNR.C:75
#define MNGD_A3
Definition: mdc.cc:3419
mdcid AddWaveform(MDC_TYPE mdc_type, vector< mdcpar > par, TString uname="")
Definition: mdc.cc:472
void Print(int level=0)
Definition: mdc.cc:2736
Definition: mdc.hh:163
char ifoLabel[64]
r add(tfmap, const_cast< char *>("hchannel"))
double pi
Definition: TestChirp.C:18
char ifo[NIFO_MAX][8]
std::vector< std::string > nameList
Definition: mdc.hh:509
network ** net
NOISE_MDC_SIMULATION.
void Draw(double t1=0.0, double t2=0.0, double f1=0.0, double f2=0.0, double z1=0.0, double z2=0.0, int dpaletteId=DUMMY_PALETTE_ID, Option_t *option="colfz")
Definition: STFT.cc:94
size_t ifoListSize()
Definition: network.hh:431
double gps
Definition: mdc.hh:232
void SetSkyDistribution(MDC_DISTRIBUTION sky_distribution, vector< mdcpar > par, int seed=0, bool add=false)
Definition: mdc.cc:3444
fprintf(stdout,"start=%f duration=%f rate=%f\, x.start(), x.size()/x.rate(), x.rate())
TString GetTemporaryFileName(TString tag="mdc", TString ext="txt", TString dir="/tmp", bool mkdir=false)
Definition: mdc.cc:5693
Definition: mdc.hh:156
double GetInjJitter()
Definition: mdc.hh:319
#define PI
Definition: watfun.hh:32
#define MDC_INJ_JITTER
Definition: mdc.hh:140
size_t mode
double GetPar(TString name, vector< mdcpar > par, bool &error)
Definition: mdc.cc:432
Definition: mdc.hh:204
int GetWaveformID(TString name)
Definition: mdc.cc:2718
TString inspXML
Definition: mdc.hh:529
virtual double rms()
Definition: wavearray.cc:1206
wavearray< double > w
Definition: Test1.C:27
nc append(pix)
#define nIFO
POLARIZATION getPolarization()
Definition: detector.hh:307
double tstart
virtual size_t size() const
Definition: wavearray.hh:145
#define MNGD_NUMERATOR
Definition: mdc.cc:3410
TCanvas * canvas
Definition: watplot.hh:192
void FillData(int size, double *phi, double *theta, double *binc)
Definition: gskymap.cc:394
std::vector< std::string > xmlType
Definition: mdc.hh:391
void DrawSkyDistribution(TString name="skymap", TString projection="", TString coordinate="Geographic", double resolution=2, bool background=true)
Definition: mdc.cc:4164
tlive_fix Write()
#define RD_FORMULA
Definition: mdc.cc:3164
wavearray< double > GetCGQ(double frequency, double Q)
Definition: mdc.cc:3028
float phi
TString chName[NIFO_MAX]
double ra
Definition: ConvertGWGC.C:46
#define MNGD_Md3
Definition: mdc.cc:3418
Definition: mdc.hh:155
static void AddGauss(wavearray< double > &td, double v, double u=0.)
Definition: mdc.cc:3230
Definition: mdc.hh:168
char str[1024]
wavearray< double > freq
Definition: Regression_H1.C:79
double rho
Definition: mdc.hh:236
TString name
Definition: mdc.hh:222
x plot
wavecomplex antenna(double, double, double=0.)
param: source theta,phi, polarization angle psi in degrees
Definition: detector.cc:490
double hrss
Definition: TestMDC.C:70
float psi
TString hxPath
Definition: mdc.hh:224
double G
Definition: DrawEBHH.C:12
CWB::STFT * stft
Definition: mdc.hh:541
int ID
Definition: mdc.hh:209
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
wavearray< double > hx
Definition: DrawInspiral.C:44
TString WriteFrameFile(TString frDir, TString frLabel, size_t gps, size_t length=1000, bool log=false, vector< TString > chName=vector< TString >())
Definition: mdc.cc:4283
#define GA_FORMULA
Definition: mdc.cc:3126
TF3 * gd1
Definition: mdc.hh:153
double real() const
Definition: wavecomplex.hh:69
double deg2rad
static void convertSampleRate(wavearray< double > iw, wavearray< double > ow)
Definition: Toolbox.cc:5829
static wavearray< double > GetEnvelope(wavearray< double > *x)
Definition: mdc.cc:7828
TCanvas * c1
i() int(T_cor *100))
double rho_max
static wavearray< double > GetAdd(wavearray< double > *w1, wavearray< double > *w2)
Definition: mdc.cc:7348
void DumpLogHeader(TString fName, TString label="", int size=0)
Definition: mdc.cc:4567
#define MDC_SAMPLE_RATE
Definition: mdc.hh:144
Float_t xq[6]
double hrss
Definition: mdc.hh:238
int id
Definition: mdc.hh:240
TString label
Definition: MergeTrees.C:21
double Pi
static wavearray< double > GetAligned(wavearray< double > *w1, wavearray< double > *w2)
Definition: mdc.cc:7302
std::vector< std::string > mdcList
Definition: network.hh:612
const int NIFO_MAX
Definition: wat.hh:22
bool log
Definition: WaveMDC.C:41
vector< mdcpar > par
Definition: mdc.hh:225
const char * DistributionToString(MDC_DISTRIBUTION n)
Definition: mdc.hh:187
TString frDir[NIFO_MAX]
TString GetBurst(wavearray< double > &x, TString ifo)
Definition: mdc.cc:1556
int ninj
Definition: cwb_mkeff.C:70
double D[50000]
static wavearray< double > GetXCorr(wavearray< double > &w1, wavearray< double > &w2)
Definition: mdc.cc:7261
waveform wf
Definition: mdc.hh:241
char cut[512]
printf("total live time: non-zero lags = %10.1f \, liveTot)
#define MNGD_B
Definition: mdc.cc:3413
static double tau
Definition: geodesics.cc:26
char fname[1024]
float mchirp
Definition: mdc.hh:213
Int_t GetEntries()
Definition: injection.cc:205
cout<< "Injected signals: "<< mdc.GetEntries()<< endl;cout<< "Injected signals in histogram factor_events_inj: "<< NEVTS<< endl;float myifar, ecor, m1, m2, netcc[3], neted, penalty;float rho[2];float chirp[6];float range[2];float frequency[2];float iSNR[3], sSNR[3];sim.SetBranchAddress("mass", mass);sim.SetBranchAddress("factor", &factor);sim.SetBranchAddress("range", range);sim.SetBranchAddress("chirp", chirp);sim.SetBranchAddress("rho", rho);sim.SetBranchAddress("netcc", netcc);sim.SetBranchAddress("neted", &neted);sim.SetBranchAddress("ifar", &myifar);sim.SetBranchAddress("ecor", &ecor);sim.SetBranchAddress("penalty", &penalty);sim.SetBranchAddress("time", mytime);sim.SetBranchAddress("iSNR", iSNR);sim.SetBranchAddress("sSNR", sSNR);sim.SetBranchAddress("spin", spin);sim.SetBranchAddress("frequency", frequency);float **volume=new float *[NBINS_mass1];float **volume_first_shell=new float *[NBINS_mass1];float **radius=new float *[NBINS_mass1];float **error_volume=new float *[NBINS_mass1];float **error_volume_first_shell=new float *[NBINS_mass1];float **error_radius=new float *[NBINS_mass1];for(int i=0;i< NBINS_mass1;i++) { volume[i]=new float[NBINS_mass2];volume_first_shell[i]=new float[NBINS_mass2];radius[i]=new float[NBINS_mass2];error_volume[i]=new float[NBINS_mass2];error_volume_first_shell[i]=new float[NBINS_mass2];error_radius[i]=new float[NBINS_mass2];for(int j=0;j< NBINS_mass2;j++) { volume[i][j]=0.;volume_first_shell[i][j]=0.;radius[i][j]=0.;error_volume[i][j]=0.;error_volume_first_shell[i][j]=0.;error_radius[i][j]=0.;} } float **spin_mtot_volume=new float *[NBINS_MTOT+1];float **spin_mtot_radius=new float *[NBINS_MTOT+1];float **error_spin_mtot_volume=new float *[NBINS_MTOT+1];float **error_spin_mtot_radius=new float *[NBINS_MTOT+1];for(int i=0;i< NBINS_MTOT+1;i++) { spin_mtot_volume[i]=new float[NBINS_SPIN+1];spin_mtot_radius[i]=new float[NBINS_SPIN+1];error_spin_mtot_volume[i]=new float[NBINS_SPIN+1];error_spin_mtot_radius[i]=new float[NBINS_SPIN+1];for(int j=0;j< NBINS_SPIN+1;j++) { spin_mtot_volume[i][j]=0.;error_spin_mtot_volume[i][j]=0.;spin_mtot_radius[i][j]=0.;error_spin_mtot_radius[i][j]=0.;} } char fname[1024];sprintf(fname, "%s/recovered_signals.txt", netdir);ofstream fev;fev.open(fname, std::ofstream::out);sprintf(line, "#GPS@L1 FAR[Hz] eFAR[Hz] Pval " "ePval factor rho frequency iSNR sSNR \");fev<< line<< endl;ofstream *fev_single=new ofstream[nfactor];for(int l=1;l< nfactor+1;l++) { sprintf(fname, "%s/recovered_signals_%d.txt", netdir, l);fev_single[l - 1].open(fname, std::ofstream::out);fev_single[l - 1]<< line<< endl;} double Vrho[RHO_NBINS], eVrho[RHO_NBINS], Rrho[RHO_NBINS], eRrho[RHO_NBINS], Trho[RHO_NBINS];for(int i=0;i< RHO_NBINS;i++) { Vrho[i]=0.;eVrho[i]=0.;Rrho[i]=0.;eRrho[i]=0.;Trho[i]=RHO_MIN+i *RHO_BIN;} double dV, dV1, dV_spin_mtot, nevts, internal_volume;int nT;int countv=0;int cnt=0;int cnt2=0;int cntfreq=0;bool bcut=false;double liveTot=sim.GetMaximum("ifar");double BKG_LIVETIME_yr=liveTot/CYS;double BKG_LIVETIME_Myr=BKG_LIVETIME_yr/(1.e6);cout.precision(14);cout<< "Total live time ---> background
wavearray< double > GetWNB(double frequency, double bandwidth, double duration, int seed=0, bool mode=0)
Definition: mdc.cc:3053
size_t mdc__IDSize()
Definition: network.hh:414
Definition: mdc.hh:151
#define speedlight
Definition: watfun.hh:33
char output[256]
int k
double tstop
UserGroup_t * uinfo
Definition: cwb_frdisplay.C:91
double Parsec()
Definition: constants.hh:206
double RA2phi(double ph, double gps)
Definition: skymap.hh:213
Definition: mdc.hh:152
#define MNGD_XMAX
Definition: mdc.cc:3421
static double A
Definition: geodesics.cc:26
TObjArray * token
double F
Definition: skymap.hh:63
double latitude
Definition: detector.hh:51
std::vector< int > idList
Definition: mdc.hh:518
vector< mdcpar > par
void SetGridyColor(Color_t colorGridy=kBlack)
Definition: gskymap.hh:146
TString inspName
Definition: mdc.hh:531
double * entry
Definition: cwb_setcuts.C:224
double e
#define MNGD_YMAX
Definition: mdc.cc:3422
static wavearray< double > GetBandpass(wavearray< double > x, double bF, double eF)
Definition: mdc.cc:7889
void DrawTF(wavearray< double > &x, TString options="")
Definition: mdc.cc:2502
static double TimeSync(wavearray< double > &w1, wavearray< double > &w2, double &sync_time)
Definition: mdc.cc:7562
watplot * DrawFFT(wavearray< double > &x, TString options="ALP", Color_t color=kBlack)
Definition: mdc.cc:2456
static double GetTimeBoundaries(wavearray< double > x, double P, double &bT, double &eT, double T=-1., double Q=-1.)
Definition: mdc.cc:7419
double phi2RA(double ph, double gps)
Definition: skymap.hh:212
vector< waveform > wfList
Definition: mdc.hh:387
char tag[256]
Definition: cwb_merge.C:92
TFile * froot
TString GetString(TTree *tree, int run, int lag, TString psfix)
Definition: Toolfun.hh:283
double inj_jitter
Definition: mdc.hh:522
static double cosi2e(double cosi)
Definition: mdc.cc:5040
double gc_rho
static void AddCGBurst(wavearray< double > &td, double a, double f, double s, double d=0.)
Definition: mdc.cc:3321
double inj_offset
Definition: mdc.hh:521
double dt
double iota
Definition: mdc.hh:237
TString GetBurstLog(source src, double FrameGPS, double SimHpHp, double SimHcHc, double SimHpHc)
Definition: mdc.cc:2180
virtual void FFTW(int=1)
Definition: wavearray.cc:896
#define MNGD_Md1
Definition: mdc.cc:3414
regression r
Definition: Regression_H1.C:44
double GravitationalConstant()
Definition: constants.hh:131
static void TimeShift(wavearray< double > &x, double tShift=0.)
Definition: mdc.cc:2903
double zgc
double Rv[3]
Definition: detector.hh:330
s s
Definition: cwb_net.C:155
injection * inj
Definition: mdc.hh:500
double rad2deg
double flow
MDC_COORDINATES mdc_coordinates
Definition: mdc.hh:503
static void AddWGNoise(wavearray< double > &td, double a, double s)
Definition: mdc.cc:3363
TF3 * gd2
char options[256]
Definition: mdc.hh:149
double inj_length
Definition: mdc.hh:524
Definition: mdc.hh:180
mdc()
Definition: mdc.cc:203
wavearray< double > hx
Definition: mdc.hh:227
double e0
Definition: RescaleEBBH.C:17
skymap sm
Definition: mdc.hh:536
char cmd_line[512]
Definition: cwb_net.C:154
double psi
Definition: mdc.hh:235
double gps
std::vector< std::string > mdcName
Definition: mdc.hh:393
double ilongitude
double T
Definition: testWDM_4.C:11
static TString getParameter(TString options, TString param="")
Definition: Toolbox.cc:6727
static wavearray< double > GetDiff(wavearray< double > *w1, wavearray< double > *w2)
Definition: mdc.cc:7374
ifstream in
TString xml_filename
Definition: mdc.hh:506
double fLow
MDC_DISTRIBUTION sky_distribution
Definition: mdc.hh:504
static double PhaseSync(wavearray< double > &w1, wavearray< double > &w2, double &sync_phase)
Definition: mdc.cc:7507
wavearray< int > index
std::vector< float > rhoList
Definition: mdc.hh:513
vector< source > GetSourceList(double start, double stop)
Definition: mdc.cc:2055
char Name[16]
Definition: detector.hh:327
int getEBBH(double m1, double m2, double rmin0, double e0, wavearray< double > &Hp, wavearray< double > &Hx, double t_end)
Definition: eBBH.cc:71
static int Align(wavearray< double > &w1, wavearray< double > &w2)
Definition: mdc.cc:7679
double fabs(const Complex &x)
Definition: numpy.cc:55
double inj_hrss
Definition: mdc.hh:523
static double a2
Definition: geodesics.cc:26
double m2
void resample(const wavearray< DataType_t > &, double, int=6)
Definition: wavearray.cc:503
double Q
double theta
Definition: mdc.hh:233
waveform GetWaveform(int ID, int id=0)
Definition: mdc.cc:2541
TCanvas * GetCanvas()
Definition: STFT.hh:70
char cmd[1024]
int estat
void ReadWaveform(wavearray< double > &x, TString fName, double srate)
Definition: mdc.cc:1877
strcpy(RunLabel, RUN_LABEL)
int cnt
double df
static double e2cosi(double e)
Definition: mdc.cc:5000
double gc_phi
long int num
sprintf(tfres,"(1/%g)x(%g) (sec)x(Hz)", 2 *df, df)
TObjString * tra
Definition: ConvertGWGC.C:40
void GalacticToEquatorial(double ilongitude, double ilatitude, double &olongitude, double &olatitude)
Definition: skycoord.hh:47
~mdc()
Definition: mdc.cc:285
double getTau(double, double)
param: source theta,phi angles in degrees
Definition: detector.cc:698
char wf_name[256]
Long_t mt
#define MNGD_A2
Definition: mdc.cc:3417
double distance_source_Kpc
Definition: DrawEBHH.C:16
TString GetParString(TString name, vector< mdcpar > par, bool &error)
Definition: mdc.cc:452
float distance
TF3 * gd
std::vector< double > hrssList
Definition: mdc.hh:515
std::vector< float > iotaList
Definition: mdc.hh:514
void Posterior2XML(TString gwname, int seed=-1)
Definition: GWOSC_Tools.C:160
DataType_t * data
Definition: wavearray.hh:319
#define MNGD_A1
Definition: mdc.cc:3415
static double TimePhaseSync(wavearray< double > &w1, wavearray< double > &w2, double &sync_time, double &sync_phase)
Definition: mdc.cc:7610
INT_4S GetSec()
Definition: time.cc:646
void DumpLog(TString fName, TString label="", bool append=false)
Definition: mdc.cc:5068
Long_t id
#define INT_4S
Definition: time.hh:34
TObjString * tdec
Definition: ConvertGWGC.C:41
void Init(int seed=0)
Definition: mdc.cc:380
std::vector< source > srcList
Definition: mdc.hh:394
double GetDouble()
Definition: time.cc:320
static double GetCentralFrequency(wavearray< double > x)
Definition: mdc.cc:2832
#define MNGD_SOLAR_SISTEM_DISTANCE_FROM_GC
Definition: mdc.cc:3424
double GetAntennaPattern(TString ifo, double phi, double theta, double psi=0., TString polarization="hp")
Definition: mdc.cc:4495
char formula[256]
void GeographicToCwb(double ilongitude, double ilatitude, double &olongitude, double &olatitude)
Definition: skycoord.hh:421
bool save
std::vector< double > mdcTime
Definition: mdc.hh:392
char line[1024]
string version
Definition: cWB_conf.py:108
POLARIZATION
Definition: detector.hh:60
double phi
Definition: mdc.hh:234
Definition: mdc.hh:231
gskymap * psp
Definition: mdc.hh:540
wavearray< double > GetRD(double frequency, double tau, double iota, bool polarization=0)
Definition: mdc.cc:3168
#define MDC_INJ_HRSS
Definition: mdc.hh:142
static double GetFrequencyBoundaries(wavearray< double > x, double P, double &bF, double &eF)
Definition: mdc.cc:7917
char fName[256]
for(int i=0;i< 101;++i) Cos2[2][i]=0
pointers to detectors
void exit(int err)
Definition: mdc.hh:497
virtual void resize(unsigned int)
Definition: wavearray.cc:463
int check
Definition: mdc.hh:157
double length
Definition: TestBandPass.C:18
wavearray< double > y
Definition: Test10.C:31
double rp0
Definition: RescaleEBBH.C:16
MDC_TYPE type
Definition: mdc.hh:220
TString name
Definition: mdc.hh:208
TString frLabel[NIFO_MAX]
void SetOptions(TString projection="hammer", TString coordinate="Geographic", double resolution=1, bool goff=false)
Definition: gskymap.cc:84
Definition: mdc.hh:166
TTree * inj_tree
Definition: mdc.hh:501
double fparm
Definition: TestDelta.C:22
TString hpPath
Definition: mdc.hh:223
Definition: mdc.hh:159
Definition: mdc.hh:165
char GravEn_SimID[1024]
detector ** pD
static wavearray< double > GetSpectrum(wavearray< double > *x, bool oneside=false)
Definition: mdc.cc:7855
static void AddSGBurst(wavearray< double > &td, double a, double f, double s, double d=0.)
Definition: mdc.cc:3279
TString ifos[60]
std::vector< float > thList
Definition: mdc.hh:510
void SetZaxisTitle(TString zAxisTitle)
Definition: gskymap.hh:150
MDC SetInspiral("inspNameTEST", inspOptions)
exit(0)
double SpeedOfLightInVacuo()
Definition: constants.hh:114
bool isBuiltin()
Definition: detector.hh:304
double avr