LALApps 10.1.0.1-eeff03c
coh_PTF_utils.c
Go to the documentation of this file.
1#include "config.h"
2#include "coh_PTF.h"
3
6 REAL4TimeSeries **channel,
7 REAL4FrequencySeries **invspec,
8 RingDataSegments **segments,
9 REAL4FFTPlan *fwdplan,
10 REAL4FFTPlan *psdplan,
11 REAL4FFTPlan *revplan,
12 REAL4 **timeSlideVectorsP,
13 struct timeval startTime
14)
15{
16 REAL4 *timeSlideVectors;
17 timeSlideVectors=LALCalloc(1, (LAL_NUM_IFO+1)*
18 params->numOverlapSegments*sizeof(REAL4));
19 memset(timeSlideVectors, 0,
20 (LAL_NUM_IFO+1) * params->numOverlapSegments * sizeof(REAL4));
21
22
23 UINT4 ifoNumber;
24 INT4 numSegments = -1;
25 /* loop over ifos */
26 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
27 {
28
29 /* if ifo is on: */
30 if (params->haveTrig[ifoNumber])
31 {
32 /* Read in data from the various ifos */
33 channel[ifoNumber] = coh_PTF_get_data(params, params->channel[ifoNumber],
34 params->dataCache[ifoNumber],
35 ifoNumber);
36 coh_PTF_rescale_data(channel[ifoNumber], params->dynRangeFac);
37
38 /* compute the spectrum */
39 invspec[ifoNumber] = coh_PTF_get_invspec(channel[ifoNumber], fwdplan,
40 revplan, psdplan, params);
41
42 /* create the segments */
43
44 segments[ifoNumber] = coh_PTF_get_segments(channel[ifoNumber],
45 invspec[ifoNumber],fwdplan, ifoNumber,
46 timeSlideVectors, params);
47
48 if (numSegments < 0)
49 {
50 if (segments[ifoNumber])
51 {
52 numSegments = segments[ifoNumber]->numSgmnt;
53 }
54 else
55 {
56 numSegments = 0;
57 }
58 }
59 else
60 {
61 if ( (! segments[ifoNumber]) )
62 {
63 if (numSegments != 0)
64 {
65 error("ERROR: Disagreement in number of segments in ifos.");
66 }
67 }
68 else if (numSegments != (INT4)segments[ifoNumber]->numSgmnt)
69 {
70 error("ERROR: Disagreement in number of segments in ifos.");
71 }
72 }
73
74 verbose("Created segments for one ifo %ld \n",
76 }
77 }
78 *timeSlideVectorsP = timeSlideVectors;
79 return numSegments;
80}
81
82
83
84
85/* gets the data, performs any injections, and conditions the data */
87 struct coh_PTF_params *params,
88 const char *ifoChannel,
89 const char *dataCache,
90 UINT4 ifoNumber )
91{
92 int stripPad = 0;
94
95 /* compute the start and duration needed to pad data */
96 params->frameDataStartTime = params->startTime;
97 XLALGPSAdd( &params->frameDataStartTime, -1.0 * params->padData );
98 params->frameDataDuration = params->duration + 2.0 * params->padData;
99
100 if ( params->getData )
101 {
102 if ( params->simData )
103 {
104 // First set the simulated PSD
105 REAL8FrequencySeries *spectrum = NULL;
106 /* Value of 1E-20 is used for white spectrum. It sets the PSD scale
107 to give SNRs that are kind of comparable to iLIGO PSD */
108 spectrum = generate_theoretical_psd(1./params->sampleRate,
109 params->duration,params->simDataType, 1E-20);
110 channel = get_simulated_data_new( ifoChannel, &params->startTime,
111 params->duration, params->sampleRate,
112 params->randomSeed+ 100*ifoNumber, spectrum );
114 }
115 else if ( params->zeroData )
116 {
117 channel = get_zero_data( ifoChannel, &params->startTime,
119 }
120 else if ( (ifoNumber == LAL_IFO_V1 && params->virgoDoubleData)
121 || (ifoNumber != LAL_IFO_V1 && params->ligoDoubleData) )
122 {
123 channel = get_frame_data_dbl_convert( dataCache, ifoChannel,
124 &params->frameDataStartTime, params->frameDataDuration,
126 params->highpassFrequency);
127 stripPad = 1;
128 }
129 else
130 {
131 channel = ring_get_frame_data( dataCache, ifoChannel,
132 &params->frameDataStartTime, params->frameDataDuration,
134 stripPad = 1;
135 }
136 if ( params->writeRawData ) /* write raw data */
138
139 /* Function to put injections overhead */
140 /*snprintf( channel->name, LALNameLength * sizeof(CHAR), "ZENITH" );*/
141
142 /* inject signals */
143 if ( params->injectFile )
145 NULL, 1.0, NULL );
146 if ( params->writeRawData )
148
149 /* condition the data: resample and highpass */
151 if ( params->writeProcessedData ) /* write processed data */
153
154 if (! params->zeroData )
155 {
156 highpass_REAL4TimeSeries( channel, params->highpassFrequency );
157 if ( params->writeProcessedData ) /* write processed data */
159 }
160
161 if ( stripPad )
162 {
164 if ( params->writeProcessedData ) /* write data with padding removed */
166 }
167 }
168
169 return channel;
170}
171
173 struct coh_PTF_params *params,
174 REAL4TimeSeries **channel,
175 REAL4FrequencySeries **invspec,
176 RingDataSegments **segments,
177 REAL4 *Fplustrig,
178 REAL4 *Fcrosstrig,
179 REAL4 *timeOffsets,
180 REAL4FFTPlan *fwdplan,
181 REAL4FFTPlan *revplan,
182 REAL4FFTPlan *psdplan,
183 REAL4 *timeSlideVectors,
184 struct timeval startTime
185)
186{
187 /* FIXME: The null stream probably will be broken by the timesliding stuff */
188 /* It may be worth deprecating this entirely, but if not then a timeslid */
189 /* null stream construction should be implemented. */
190 /* My vote is to deprecate the null stream. */
191
192 UINT4 ui;
193
194 /* Read in data from the various ifos */
195 if (coh_PTF_get_null_stream(params, channel, Fplustrig, Fcrosstrig,
196 timeOffsets))
197 {
198 error("Null stream construction failure\n");
199 }
200
201 /* compute the spectrum */
203 revplan, psdplan, params);
204 /* If white spectrum need to scale this. */
205 if (params->whiteSpectrum)
206 {
207 for(ui=0 ; ui < invspec[LAL_NUM_IFO]->data->length; ui++)
208 {
209 /* FIXME: The factor here is hardcoded and wrong. */
210 /* Should be dynamically calculated. */
211 invspec[LAL_NUM_IFO]->data->data[ui] *= pow(1./0.3403324,2);
212 }
213 }
214
215 /* create the segments */
217 invspec[LAL_NUM_IFO],fwdplan,\
218 LAL_NUM_IFO,timeSlideVectors, params);
219
220 verbose("Created segments for null stream at %ld \n",
222}
223
224/* This function is used to generate the null stream */
225/* Be aware this is separate from the null SNR! */
227 struct coh_PTF_params *params,
228 REAL4TimeSeries *channel[LAL_NUM_IFO+1],
229 REAL4 *Fplus,
230 REAL4 *Fcross,
231 REAL4 *timeOffsets )
232{
233 UINT4 j,n[3],ifoNumber;
234 INT4 i,t[3];
235 INT4 timeOffsetPoints[LAL_NUM_IFO];
238 /* Determine how many detectors we are dealing with and assign 1-3 */
239 i = -1;
240 for( ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
241 {
242 if ( params->haveTrig[ifoNumber] )
243 {
244 i++;
245 if (i == 3)
246 {
247 fprintf(stderr,"Currently Null stream can only be constructed for three ifo combinations \n");
248 return 1;
249 }
250 n[i] = ifoNumber;
251 }
252 }
253 if (i < 2)
254 {
255 fprintf(stderr,"Null stream requires at least three detectors\n");
256 return 1;
257 }
258
259
260 /* Determine time offset as number of data poitns */
261 deltaT = channel[n[0]]->deltaT;
262 coh_PTF_convert_time_offsets_to_points(params,timeOffsets,timeOffsetPoints);
263
264 /* Initialise the null stream structures */
265 series = LALCalloc( 1, sizeof( *series ) );
266 series->data = XLALCreateREAL4Vector( channel[n[0]]->data->length );
267 snprintf( series->name, sizeof( series->name ), "NULL_STREAM");
268 series->epoch = channel[n[0]]->epoch;
269 series->deltaT = deltaT;
270 series->sampleUnits = lalStrainUnit;
271 for ( j = 0; j < series->data->length; ++j )
272 {
273 for ( i =0 ; i < 3; i++ )
274 {
275 t[i] = j + timeOffsetPoints[n[i]];
276 if (t[i] < 0)
277 {
278 t[i] = t[i] + series->data->length;
279 }
280 if (t[i] > (INT4)(series->data->length-1))
281 {
282 t[i] = t[i] - series->data->length;
283 }
284 }
285 series->data->data[j] = (Fplus[n[1]]*Fcross[n[2]] - Fplus[n[2]]*Fcross[n[1]]) * channel[n[0]]->data->data[t[0]];
286 series->data->data[j] += (Fplus[n[2]]*Fcross[n[0]] - Fplus[n[0]]*Fcross[n[2]]) * channel[n[1]]->data->data[t[1]];
287 series->data->data[j] += (Fplus[n[0]]*Fcross[n[1]] - Fplus[n[1]]*Fcross[n[0]]) * channel[n[2]]->data->data[t[2]];
288 }
289 if ( params->writeProcessedData ) /* write processed data */
292
293 return 0;
294}
295
296/* computes the inverse power spectrum */
298 REAL4TimeSeries *channel,
299 REAL4FFTPlan *fwdplan,
300 REAL4FFTPlan *revplan,
301 REAL4FFTPlan *psdplan,
302 struct coh_PTF_params *params
303 )
304{
305 REAL4FrequencySeries *invspec = NULL;
306 if ( params->getSpectrum )
307 {
308 if ( ! params->whiteSpectrum)
309 {
310 UINT4 recordLength,psdSegmentLength,segmentStride,numDoublePsdSegs;
311 UINT4 neededDataLength;
312 /* compute raw average spectrum; store spectrum in invspec for now */
313 REAL4FrequencySeries *invspecorig = NULL;
314 /* If the data length is no appropriate, don't use all of it */
315 recordLength = params->duration * params->sampleRate;
316 psdSegmentLength = floor(params->psdSegmentDuration * \
317 params->sampleRate + 0.5);
318 segmentStride = floor(params->psdStrideDuration * params->sampleRate \
319 + 0.5);
320 sanity_check( segmentStride > 0 );
321 numDoublePsdSegs = 1 + (recordLength - psdSegmentLength)/ \
322 (segmentStride);
323 numDoublePsdSegs /= 2;
324 // Need enough psd segments for good estimation
325 sanity_check(numDoublePsdSegs > 5);
326 neededDataLength = ((2*numDoublePsdSegs)-1) * segmentStride + psdSegmentLength;
327 verbose("Using %e of %e seconds for PSD estimation in %d segments.\n",\
328 neededDataLength/params->sampleRate,params->duration,\
329 2*numDoublePsdSegs);
330 // Adjust channel length for PSD calculation
331 channel->data->length = neededDataLength;
332 invspecorig = compute_average_spectrum( channel,
333 LALRINGDOWN_SPECTRUM_MEDIAN_MEAN, params->psdSegmentDuration,
334 params->psdStrideDuration, psdplan, 0 );
335 // Set the channel length back
336 channel->data->length = recordLength;
337 /* Resample if necessary */
338 if (params->psdSegmentDuration != params->segmentDuration)
339 {
340 if ( params->writeInvSpectrum ) /* Write spectrum before resampling */
341 write_REAL4FrequencySeries( invspecorig );
342 verbose("Resampling PSD\n");
343 invspec = resample_psd(invspecorig, params->sampleRate,
344 params->segmentDuration);
345 }
346 else
347 {
348 invspec = invspecorig;
349 }
350 }
351 else
352 {
353 UINT4 k;
354 REAL8FrequencySeries *spectrum;
355 spectrum = generate_theoretical_psd(1./params->sampleRate,
356 params->segmentDuration,params->simDataType, 1E-20);
357
358 /* Need to convert to a REAL4 FrequencySeries */
359 invspec = XLALCreateREAL4FrequencySeries("TEMP",&(channel->epoch),0,
360 1.0/params->segmentDuration,&lalDimensionlessUnit,
361 params->numFreqPoints);
362 if((int)sizeof(invspec->name) <= snprintf( invspec->name, sizeof( invspec->name),
363 "%s_SPEC", channel->name))
364 XLAL_ERROR_NULL(XLAL_FAILURE,"String truncated");
365 for ( k = 0; k < spectrum->data->length; ++k )
366 {
367 invspec->data->data[k] = (REAL4)(spectrum->data->data[k]*1E40);
368 }
370 }
371
372 if ( params->writeInvSpectrum ) /* Write spectrum before inversion */
374
375 /* invert spectrum */
376 invert_spectrum( invspec, params->sampleRate, params->strideDuration,
377 params->truncateDuration, params->highpassFrequency, fwdplan,
378 revplan );
379
380 if ( params->writeInvSpectrum ) /* write inverse calibrated spectrum */
382 }
383
384 return invspec;
385}
386
387/* Function to rescale the data to avoid floating point errors*/
388void coh_PTF_rescale_data (REAL4TimeSeries *channel, REAL8 rescaleFactor)
389{
390 UINT4 k;
391 for ( k = 0; k < channel->data->length; ++k )
392 {
393 channel->data->data[k] *= rescaleFactor;
394 }
395}
396
397/* creates the requested data segments (those in the list of segments to do) */
399 REAL4TimeSeries *channel,
400 REAL4FrequencySeries *invspec,
401 REAL4FFTPlan *fwdplan,
402 InterferometerNumber NumberIFO,
403 REAL4 *timeSlideVectors,
404 struct coh_PTF_params *params
405 )
406{
407 RingDataSegments *segments = NULL;
408 COMPLEX8FrequencySeries *response = NULL;
409 UINT4 sgmnt,i,j, slidSegNum;
410 UINT4 segListToDo[params->numOverlapSegments];
411
412 segments = LALCalloc( 1, sizeof( *segments ) );
413
414 if ( params->analyzeInjSegsOnly )
415 {
416 /* NOTE: Using this flag will override anything given by the option
417 * --only-analyse-segments, do not try and use both together */
418 /* Figure out which segments the injections are in. If an injection is
419 * within 1s of a segment boundary, analyse both segments. */
420 for ( i = 0 ; i < params->numOverlapSegments; i++)
421 segListToDo[i] = 0;
422 SimInspiralTable *injectList = NULL;
423 REAL8 deltaTime,segBoundDiff;
424 INT4 segNumber;
425 if (! params->injectList)
426 {
427 injectList = XLALSimInspiralTableFromLIGOLw( params->injectFile );
428 params->injectList = injectList;
429 }
430 else
431 {
432 injectList = params->injectList;
433 }
434 while (injectList)
435 {
436 /* Calculate the epoch of the injection relative to the gps-start */
437 deltaTime = injectList->geocent_end_time.gpsSeconds;
438 deltaTime += injectList->geocent_end_time.gpsNanoSeconds * 1E-9;
439 deltaTime -= params->startTime.gpsSeconds;
440 deltaTime -= params->startTime.gpsNanoSeconds * 1E-9;
441
442 /* Adjust to the epoch relative to the analysis start */
443 deltaTime -= params->analStartTime;
444
445 /* And figure out the segment number */
446 segNumber = floor( deltaTime / params->strideDuration);
447 if (segNumber >= (INT4) params->numOverlapSegments)
448 {
449 verbose("Injection at %" LAL_INT8_FORMAT " after analysis window.\n",\
450 injectList->geocent_end_time.gpsSeconds);
451 }
452 else if (segNumber < 0)
453 {
454 verbose("Injection at %" LAL_INT8_FORMAT " before analysis window.\n",\
455 injectList->geocent_end_time.gpsSeconds);
456 }
457 else
458 {
459 segListToDo[segNumber] = 1;
460 }
461 /* Check if injection is near a segment boundary */
462 for ( j = 0 ; j < params->numOverlapSegments; j++)
463 {
464 segBoundDiff = deltaTime - j * params->strideDuration/2;
465 if (segBoundDiff > 0 && segBoundDiff < params->injSearchWindow)
466 {
467 if (j != 0)
468 {
469 segListToDo[segNumber-1] = 1;
470 }
471 }
472 if (segBoundDiff < 0 && segBoundDiff > -params->injSearchWindow)
473 {
474 if ((j+1) != params->numOverlapSegments)
475 {
476 segListToDo[segNumber+1] = 1;
477 }
478 }
479 }
480 injectList = injectList->next;
481 }
482 }
483 else
484 {
485 params->injectList = NULL;
486 }
487
488 /* FIXME: For all sky mode trig start/end time needs to be implemented */
489 /* these probably work in the ring code! */
490
491 /* if todo list is empty then do them all */
492 if ( (! params->segmentsToDoList || ! strlen( params->segmentsToDoList )) && (! params->analyzeInjSegsOnly) )
493 {
494 /* Not convinved the code ever goes here, because empty segmentsToDoList
495 * does not evaluate to false. The loop below still works though! */
496 segments->numSgmnt = params->numOverlapSegments;
497 segments->sgmnt = LALCalloc( segments->numSgmnt, sizeof(*segments->sgmnt) );
498 for ( sgmnt = 0; sgmnt < params->numOverlapSegments; ++sgmnt )
499 {
500 slidSegNum = ( sgmnt + ( params->slideSegments[NumberIFO] ) ) % ( segments->numSgmnt );
501 timeSlideVectors[NumberIFO*params->numOverlapSegments + sgmnt] =
502 ((INT4)slidSegNum-(INT4)sgmnt)*params->strideDuration;
503 compute_data_segment( &segments->sgmnt[sgmnt], slidSegNum, channel,
504 invspec, response, params->segmentDuration, params->strideDuration,
505 fwdplan );
506 }
507 }
508 else /* only do the segments in the todo list */
509 {
510 UINT4 count;
511
512 /* first count the number of segments to do */
513 count = 0;
514 for ( sgmnt = 0; sgmnt < params->numOverlapSegments; ++sgmnt )
515 {
516 if ( params->analyzeInjSegsOnly )
517 {
518 if ( segListToDo[sgmnt] == 1)
519 ++count;
520 else
521 continue;
522 }
523 else
524 {
525 if ( is_in_list( sgmnt, params->segmentsToDoList ) )
526 ++count;
527 else
528 continue; /* skip this segment: it is not in todo list */
529 }
530 }
531
532 if ( ! count ) /* no segments to do */
533 {
534 LALFree(segments);
535 return NULL;
536 }
537
538 segments->numSgmnt = count;
539 segments->sgmnt = LALCalloc( segments->numSgmnt, sizeof(*segments->sgmnt) );
540
541 count = 0;
542 for ( sgmnt = 0; sgmnt < params->numOverlapSegments; ++sgmnt )
543 {
544 if ( params->analyzeInjSegsOnly )
545 {
546 /* NOTE: Time slide injection analysis is not currently possible */
547 if ( segListToDo[sgmnt] == 1)
548 compute_data_segment( &segments->sgmnt[count++], sgmnt, channel,
549 invspec, response, params->segmentDuration, params->strideDuration,
550 fwdplan );
551 }
552 else
553 {
554 if ( is_in_list( sgmnt, params->segmentsToDoList ) )
555 /* we are sliding the names of segments here */
556 {
557 slidSegNum = ( sgmnt + ( params->slideSegments[NumberIFO] ) ) % ( params->numOverlapSegments );
558 timeSlideVectors[NumberIFO*params->numOverlapSegments + count] =
559 ((INT4)slidSegNum-(INT4)sgmnt)*params->strideDuration;
560 compute_data_segment( &segments->sgmnt[count++], slidSegNum, channel,
561 invspec, response, params->segmentDuration, params->strideDuration,
562 fwdplan );
563 }
564 }
565 }
566 }
567 if ( params->writeSegment) /* write data segment */
568 {
569 for ( sgmnt = 0; sgmnt < segments->numSgmnt; ++sgmnt )
570 {
571 write_COMPLEX8FrequencySeries( &segments->sgmnt[sgmnt] ) ;
572 }
573 }
574
575 return segments;
576}
577
578
579/*
580 * Create a TimeSlideSegmentMap structure.
581 */
582
584{
585 TimeSlideSegmentMapTable *new = XLALMalloc(sizeof(*new));
586
587 if(!new)
589
590 new->next = NULL;
591 new->time_slide_id = -1;
592 new->segment_def_id = -1;
593
594 return new;
595}
596
597
598/*
599 * Destroy a TimeSlideSegmentMap structure.
600 */
601
602
604{
605 XLALFree(row);
606}
607
608
609/*
610 * Destroy a TimeSlideSegmentMap linked list.
611 */
612
613
615{
616 while(head)
617 {
618 TimeSlideSegmentMapTable *next = head->next;
620 head = next;
621 }
622}
623
624
625
627 struct coh_PTF_params *params,
628 INT8 *slideIDList,
629 RingDataSegments **segments,
630 TimeSlide **time_slide_headP,
631 TimeSlideSegmentMapTable **time_slide_map_headP,
632 SegmentTable **segment_table_headP,
633 TimeSlideVectorList **longTimeSlideListP,
634 TimeSlideVectorList **shortTimeSlideListP,
635 REAL4 *timeSlideVectors,
637)
638{
639 TimeSlide *time_slide_head = NULL;
640 TimeSlide *curr_slide = NULL;
641 TimeSlideSegmentMapTable *time_slide_map_head = NULL;
642 TimeSlideSegmentMapTable *curr_time_slide_map = NULL;
643 SegmentTable *segment_table_head = NULL;
644 SegmentTable *curr_slide_segment = NULL;
645 TimeSlideVectorList *longTimeSlideList = LALCalloc(\
647 CHAR ifoName[LIGOMETA_IFO_MAX];
648 UINT4 longSlideCount = 0;
649 UINT4 shortSlideCount = 0;
650 INT4 i;
651 UINT4 ui,uj,ifoNumber,ifoNum,lastStartPoint,wrapPoint,currId,ifoCount;
652 UINT4 slideSegmentCount, calculatedFlag;
653 REAL8 currBaseOffset,currBaseIfoOffset[LAL_NUM_IFO],wrapTime,currIfoOffset;
654 LIGOTimeGPS slideStartTime,slideEndTime, tmpSlideStartTime, tmpSlideEndTime;
655
656 /* First construct the list of long slides */
657 for (i = 0 ; i < numSegments ; i++)
658 {
659 UINT4 slideDuplicate = 0;
660 if (longSlideCount)
661 {
662 for (uj = 0; uj < longSlideCount; uj++)
663 {
664 UINT4 slideChecking = 1;
665 /* Here we check if the time-slid segment i is the same slide as the
666 * timeSlideList[uj] */
667 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
668 {
669 if (params->haveTrig[ifoNumber])
670 {
671 if (timeSlideVectors[ifoNumber*params->numOverlapSegments+i] != \
672 longTimeSlideList[uj].timeSlideVectors[ifoNumber])
673 {
674 slideChecking = 0;
675 }
676 }
677 }
678 if (slideChecking)
679 {
680 slideDuplicate = 1;
681 slideIDList[i] = longTimeSlideList[uj].timeSlideID;
682 }
683 }
684 }
685 if (! slideDuplicate)
686 {
687 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
688 {
689 if (params->haveTrig[ifoNumber])
690 {
691 longTimeSlideList[longSlideCount].timeSlideVectors[ifoNumber] =
692 timeSlideVectors[ifoNumber*params->numOverlapSegments+i];
693 }
694 }
695 longTimeSlideList[longSlideCount].timeSlideID = longSlideCount;
696 slideIDList[i] = longTimeSlideList[longSlideCount].timeSlideID;
697 longSlideCount++;
698 }
699 }
700
701 TimeSlideVectorList *shortTimeSlideList = LALCalloc(\
702 params->numShortSlides, sizeof(TimeSlideVectorList));
703
704 /* Next construct the list of short time slides */
705 /* Always have a zero-lag short slide */
706 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
707 {
708 if (params->haveTrig[ifoNumber])
709 {
710 shortTimeSlideList[0].timeSlideVectors[ifoNumber] = 0.;
711 }
712 }
713 shortTimeSlideList[0].timeSlideID = 0;
714 shortTimeSlideList[0].analStartPoint = params->analStartPoint;
715 shortTimeSlideList[0].analEndPoint = params->analEndPoint;
716 shortSlideCount = 1;
717
718 if (params->doShortSlides)
719 {
720 currBaseOffset = params->shortSlideOffset;
721 while (1)
722 {
723 /* Calculate offsets for each detector */
724 ifoNum = 0;
725 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
726 {
727 currBaseIfoOffset[ifoNumber] = 0;
728 if (params->haveTrig[ifoNumber])
729 {
730 currBaseIfoOffset[ifoNumber] = currBaseOffset * ifoNum;
731 /* If the offset is bigger than the stride then this cannot be done*/
732 /* FIXME: We should check if the offset is not bigger than the */
733 /* stride minus the BaseOffset, otherwise we can end up with short */
734 /* slides whose offsets are very similar to the long slides */
735 if (currBaseIfoOffset[ifoNumber] > \
736 (params->strideDuration) )
737 {
738 break;
739 }
740 ifoNum += 1;
741 }
742 }
743 if (ifoNumber != LAL_NUM_IFO)
744 { /* If I did not finish the previous for loop due to break, break here*/
745 /* THIS IS THE ONLY PLACE THAT I MIGHT BREAK FROM THE WHILE LOOP */
746 break;
747 }
748
749 /* This avoids "WARNING: May be used unset" warning */
750 lastStartPoint = 0;
751 /* Now we need to consider the wrapping and set slides */
752 for (ui = 0; ui < ifoNum; ui++)
753 {
754 /* Begin by initializing the slide */
755 shortTimeSlideList[shortSlideCount].timeSlideID = shortSlideCount;
756
757 /* Next we populate the slide's start and end times */
758 /* We're actually going to loop backwards, so ui = 0 corresponds to the
759 * end of the segment where are slides will have wrapped */
760 if (ui == 0)
761 {
762 /* If ui=0 we know the end point of slide will be analEndPoint */
763 shortTimeSlideList[shortSlideCount].analEndPoint = \
764 params->analEndPoint;
765 }
766 else
767 {
768 /* Otherwise end at where we started before */
769 shortTimeSlideList[shortSlideCount].analEndPoint = lastStartPoint;
770 }
771 if (ui == ifoNum - 1)
772 {
773 /* If ui = ifoNum we have to start at analStartPoint */
774 shortTimeSlideList[shortSlideCount].analStartPoint = \
775 params->analStartPoint;
776 }
777 else
778 {
779 /* Now the tricky one, we have to figure out where the next (previous
780 * as we're looping backwards) wrap point will be. */
781 wrapTime = params->strideDuration - (ui + 1) * currBaseOffset;
782 wrapPoint = floor(wrapTime * params->sampleRate + 0.5);
783 /* Start point is then start point + wrap point */
784 shortTimeSlideList[shortSlideCount].analStartPoint = \
785 params->analStartPoint + wrapPoint;
786 }
787 lastStartPoint = shortTimeSlideList[shortSlideCount].analStartPoint;
788 /* Now we construct the wrapped offsets and store*/
789 ifoCount = 0;
790 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
791 {
792 /* We are looping backwards so invert this */
793 if (params->haveTrig[ifoNumber])
794 {
795 currIfoOffset = currBaseIfoOffset[ifoNumber];
796 if (ifoCount > ui)
797 { /* Need to wrap */
798 currIfoOffset -= params->strideDuration;
799 }
800 shortTimeSlideList[shortSlideCount].timeSlideVectors[ifoNumber] =
801 currIfoOffset;
802 ifoCount++;
803 }
804 }
805 shortSlideCount++;
806 } /* End loop over wrap points */
807 currBaseOffset += params->shortSlideOffset;
808 } /* End the while(1) loop over base offsets */
809 } /* End if do short slides */
810 sanity_check(shortSlideCount == params->numShortSlides);
811
812 /* Time slide table will contain every long+short slide combination */
813 for (ui = 0 ; ui < longSlideCount; ui++)
814 { /* Loop over long slides */
815 for (uj = 0 ; uj < shortSlideCount; uj++)
816 { /* Loop over short slides */
817 /* Construct the ID from the current long and short slide */
818 currId = longTimeSlideList[ui].timeSlideID*shortSlideCount;
819 currId += shortTimeSlideList[uj].timeSlideID;
820 /* Create an entry in the time_slide_map */
821 if (! time_slide_map_head)
822 {
823 time_slide_map_head=XLALCreateTimeSlideSegmentMapTableRow();
824 curr_time_slide_map = time_slide_map_head;
825 }
826 else
827 {
828 curr_time_slide_map->next = XLALCreateTimeSlideSegmentMapTableRow();
829 curr_time_slide_map = curr_time_slide_map->next;
830 }
831 /* Set the ID in the time_slide_table */
832 curr_time_slide_map->time_slide_id = currId;
833 curr_time_slide_map->segment_def_id = currId;
834
835 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
836 {
837 if (params->haveTrig[ifoNumber])
838 {
839 /* We need an entry for every ifo and every slide */
840 if (! time_slide_head)
841 { /* Create table if it doesn't exist */
842 time_slide_head=XLALCreateTimeSlide();
843 curr_slide= time_slide_head;
844 }
845 else
846 { /* Or setup the next entry in the linked list */
847 curr_slide->next=XLALCreateTimeSlide();
848 curr_slide = curr_slide->next;
849 }
850 /* Set the ID in the time_slide_table */
851 curr_slide->time_slide_id = currId;
852 /* Set the IFO */
853 XLALReturnIFO(ifoName,ifoNumber);
854 strncpy(curr_slide->instrument,ifoName,\
855 sizeof(curr_slide->instrument)-1);
856 /* Set the offset as the sum of the short and long offests */
857 curr_slide->offset = \
858 longTimeSlideList[ui].timeSlideVectors[ifoNumber];
859 curr_slide->offset += \
860 shortTimeSlideList[uj].timeSlideVectors[ifoNumber];
861 /* Process IDs will be 0 */
862 curr_slide->process_id=0;
863 }
864 } /* End ifo loop */
865 } /* End short slide loop */
866 } /* End long slide loop */
867
868 /* Now we construct the list of analysed segments for each time slide_id
869 * This will be a segment for *every* segment+short_slide combination */
870 slideSegmentCount = 0;
871 for (i = 0 ; i < numSegments ; i++)
872 { /* Loop over segments */
873 for (uj = 0 ; uj < shortSlideCount; uj++)
874 { /* Loop over short slides */
875 /* Contruct the ID form the current long+short slide */
876 currId = slideIDList[i]*shortSlideCount;
877 currId += shortTimeSlideList[uj].timeSlideID;
878 /* Construct the segment start and end times */
879 calculatedFlag = 0;
880 for (ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
881 {
882 if (params->haveTrig[ifoNumber])
883 {
884 tmpSlideStartTime = segments[ifoNumber]->sgmnt[i].epoch;
885 tmpSlideEndTime = segments[ifoNumber]->sgmnt[i].epoch;
886 XLALGPSAdd(&tmpSlideStartTime, \
887 -timeSlideVectors[ifoNumber*params->numOverlapSegments+i]);
888 XLALGPSAdd(&tmpSlideEndTime, \
889 -timeSlideVectors[ifoNumber*params->numOverlapSegments+i]);
890 if (calculatedFlag)
891 {
892 if (XLALGPSCmp(&tmpSlideStartTime, &slideStartTime))
893 {
894 fprintf(stderr, "1: %d %d\n", tmpSlideStartTime.gpsSeconds, slideStartTime.gpsSeconds);
895 fprintf(stderr, "1: %d %d\n", tmpSlideStartTime.gpsNanoSeconds, slideStartTime.gpsNanoSeconds);
896 error("Error long slide epochs not agreeing with the slid times. This suggests broken code, please contact a developer.\n");
897
898 }
899 if (XLALGPSCmp(&tmpSlideEndTime, &slideEndTime))
900 {
901 fprintf(stderr, "2: %d %d\n", tmpSlideEndTime.gpsSeconds, slideEndTime.gpsSeconds);
902 fprintf(stderr, "2: %d %d\n", tmpSlideEndTime.gpsNanoSeconds, slideEndTime.gpsNanoSeconds);
903 error("Error long slide epochs not agreeing with the slid times. This suggests broken code, please contact a developer.");
904 }
905 }
906 else
907 {
908 slideStartTime.gpsSeconds=tmpSlideStartTime.gpsSeconds;
909 slideStartTime.gpsNanoSeconds=tmpSlideStartTime.gpsNanoSeconds;
910 slideEndTime.gpsSeconds=tmpSlideEndTime.gpsSeconds;
911 slideEndTime.gpsNanoSeconds=tmpSlideEndTime.gpsNanoSeconds;
912 calculatedFlag = 1;
913 }
914 }
915 }
916 XLALGPSAdd(&slideStartTime, \
917 ((REAL8)shortTimeSlideList[uj].analStartPoint) / params->sampleRate );
918 XLALGPSAdd(&slideEndTime, \
919 ((REAL8)shortTimeSlideList[uj].analEndPoint) / params->sampleRate );
920 /* Add this to the segment table */
921 if (! segment_table_head)
922 { /* Create table if it doesn't exist */
923 segment_table_head=XLALCreateSegmentTableRow(NULL);
924 curr_slide_segment= segment_table_head;
925 }
926 else
927 { /* Or setup the next entry in the linked list */
928 curr_slide_segment->next=XLALCreateSegmentTableRow(NULL);
929 curr_slide_segment = curr_slide_segment->next;
930 }
931 curr_slide_segment->segment_id = slideSegmentCount;
932 curr_slide_segment->segment_def_id = currId;
933 curr_slide_segment->start_time = slideStartTime;
934 curr_slide_segment->end_time = slideEndTime;
935 curr_slide_segment->process_id = 0;
936 slideSegmentCount++;
937 }
938 }
939
940 *time_slide_headP = time_slide_head;
941 *time_slide_map_headP = time_slide_map_head;
942 *segment_table_headP = segment_table_head;
943 *shortTimeSlideListP = shortTimeSlideList;
944 *longTimeSlideListP = longTimeSlideList;
945}
946
948 struct coh_PTF_params *params,
949 LALDetector **detectors,
950 REAL4 *timeOffsets,
951 REAL4 *Fplustrig,
952 REAL4 *Fcrosstrig,
954 UINT4 skyPointNum
955)
956{
957 UINT4 ifoNumber,ui;
958 REAL8 FplusTmp,FcrossTmp;
959 REAL8 detLoc[3];
960
961 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
962 {
963 if (! detectors[ifoNumber])
964 {
965 detectors[ifoNumber] = LALCalloc(1, sizeof(*detectors[ifoNumber]));
966 XLALReturnDetector(detectors[ifoNumber], ifoNumber);
967 }
968 /* get location in three dimensions */
969 for (ui = 0; ui < 3; ui++)
970 {
971 detLoc[ui] = (double) detectors[ifoNumber]->location[ui];
972 }
973 /* calculate time offsets */
974 timeOffsets[ifoNumber] = (REAL4)
976 skyPoints->data[skyPointNum].longitude,
977 skyPoints->data[skyPointNum].latitude,
978 &(params->trigTime));
979 /* calculate response functions for trigger */
980 XLALComputeDetAMResponse(&FplusTmp, &FcrossTmp,
981 (const REAL4 (*)[3])detectors[ifoNumber]->response,
982 skyPoints->data[skyPointNum].longitude,
983 skyPoints->data[skyPointNum].latitude, 0.,
985 Fplustrig[ifoNumber] = (REAL4) FplusTmp;
986 Fcrosstrig[ifoNumber] = (REAL4) FcrossTmp;
987 }
988}
989
991 struct coh_PTF_params *params,
992 FindChirpTemplate **fcTmpltP,
993 FindChirpTmpltParams **fcTmpltParamsP,
994 REAL8Array **PTFM,
995 REAL8Array **PTFN,
996 COMPLEX8VectorSequence **PTFqVec,
997 REAL4FFTPlan *fwdplan
998)
999{
1000 UINT4 ifoNumber;
1001
1002 FindChirpTemplate *fcTmplt;
1003 FindChirpTmpltParams *fcTmpltParams;
1004
1008
1009 /* finchirp parameters */
1010 fcTmplt = LALCalloc(1, sizeof(*fcTmplt));
1011 fcTmpltParams = LALCalloc(1, sizeof(*fcTmpltParams));
1012 fcTmpltParams->approximant = params->approximant;
1013 fcTmpltParams->order = params->order;
1014
1015 /* Note that although non-spinning only uses Q1, the PTF
1016 * generator still generates Q1-5, thus size of these vectors */
1017 if (params->approximant == FindChirpPTF)
1018 {
1019 fcTmplt->PTFQtilde =
1020 XLALCreateCOMPLEX8VectorSequence(5, params->numFreqPoints);
1021 fcTmplt->PTFQ = XLALCreateVectorSequence(5, params->numTimePoints);
1022 fcTmpltParams->PTFphi = XLALCreateVector(params->numTimePoints);
1023 fcTmpltParams->PTFomega_2_3 = XLALCreateVector(params->numTimePoints);
1024 fcTmpltParams->PTFe1 = XLALCreateVectorSequence(3, params->numTimePoints);
1025 fcTmpltParams->PTFe2 = XLALCreateVectorSequence(3, params->numTimePoints);
1026 }
1027 else if (params->approximant == FindChirpSP)
1028 {
1029 fcTmplt->PTFQtilde =
1030 XLALCreateCOMPLEX8VectorSequence(1, params->numFreqPoints);
1031 fcTmplt->data = XLALCreateCOMPLEX8Vector(params->numFreqPoints);
1032 fcTmpltParams->xfacVec = XLALCreateVector(params->numFreqPoints);
1033 fcTmpltParams->PTFphi = XLALCreateVector(params->numFreqPoints);
1034 /* Set the values of xfacVec This is k^(-1/3)
1035 * also PTFphi which is k^(-7/6). As these are expensive to compute it
1036 * is cheaper to do it once rather than many times. */
1037 const REAL4 xfacExponent = -1.0/3.0;
1038 REAL4 *xfac = NULL;
1039 UINT4 ui;
1040 xfac = fcTmpltParams->xfacVec->data;
1041 xfac[0] = 0;
1042 fcTmpltParams->PTFphi->data[0] = 0;
1043 for (ui = 1; ui < fcTmpltParams->xfacVec->length; ++ui)
1044 {
1045 xfac[ui] = pow((REAL4) ui, xfacExponent);
1046 fcTmpltParams->PTFphi->data[ui] = pow((REAL4) ui, -7.0/6.0);
1047 }
1048 }
1049 else
1050 {
1051 fcTmplt->PTFQtilde =
1052 XLALCreateCOMPLEX8VectorSequence(1, params->numFreqPoints);
1053 fcTmplt->data = XLALCreateCOMPLEX8Vector(params->numFreqPoints);
1054 fcTmpltParams->xfacVec = XLALCreateVector(params->numTimePoints);
1055 }
1056
1057 fcTmpltParams->fwdPlan = fwdplan;
1058 fcTmpltParams->deltaT = 1.0/params->sampleRate;
1059 if (params->dynTempLength)
1060 {
1061 fcTmpltParams->dynamicTmpltFlow = 1;
1062 }
1063 else
1064 {
1065 fcTmpltParams->dynamicTmpltFlow = 0;
1066 fcTmpltParams->fLow = params->lowTemplateFrequency;
1067 }
1068 /* This option holds 2x the length of data that is junk in each segment
1069 * because of conditioning and the PSD.*/
1070 fcTmpltParams->invSpecTrunc = params->truncateDuration;
1071 fcTmpltParams->maxTempLength = params->maxTempLength;
1072 fcTmpltParams->dynRange = params->dynRangeFac;
1073
1074 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
1075 {
1076 if (params->haveTrig[ifoNumber])
1077 {
1078 if (params->approximant == FindChirpPTF)
1079 {
1080 PTFM[ifoNumber] = XLALCreateREAL8ArrayL(2, 5, 5);
1081 PTFN[ifoNumber] = XLALCreateREAL8ArrayL(2, 5, 5);
1082 PTFqVec[ifoNumber] = XLALCreateCOMPLEX8VectorSequence\
1083 (5, params->numTimePoints);
1084 }
1085 else
1086 {
1087 PTFM[ifoNumber] = XLALCreateREAL8ArrayL(2, 1, 1);
1088 PTFN[ifoNumber] = XLALCreateREAL8ArrayL(2, 1, 1);
1089 PTFqVec[ifoNumber] = XLALCreateCOMPLEX8VectorSequence\
1090 (1, params->numTimePoints);
1091 }
1092 }
1093 }
1094
1095 if (params->doNullStream)
1096 {
1097 if (params->approximant == FindChirpPTF)
1098 {
1099 PTFM[LAL_NUM_IFO] = XLALCreateREAL8ArrayL(2, 5, 5);
1100 PTFN[LAL_NUM_IFO] = XLALCreateREAL8ArrayL(2, 5, 5);
1102 (5, params->numTimePoints);
1103 }
1104 else
1105 {
1106 PTFM[LAL_NUM_IFO] = XLALCreateREAL8ArrayL(2, 1, 1);
1107 PTFN[LAL_NUM_IFO] = XLALCreateREAL8ArrayL(2, 1, 1);
1109 (1, params->numTimePoints);
1110 }
1111 }
1112 /* Send the output back to the parent function */
1113 *fcTmpltP = fcTmplt;
1114 *fcTmpltParamsP = fcTmpltParams;
1115
1116}
1117
1119 struct coh_PTF_params *params,
1120 LIGOTimeGPS segStartTime,
1121 REAL8 fLower,
1122 REAL4TimeSeries **cohSNRP,
1123 REAL4TimeSeries **nullSNRP,
1124 REAL4TimeSeries **traceSNRP,
1125 REAL4TimeSeries **bankVeto,
1126 REAL4TimeSeries **autoVeto,
1127 REAL4TimeSeries **chiSquare,
1128 REAL4TimeSeries **snrComps,
1129 REAL4TimeSeries **pValues,
1130 REAL4TimeSeries **gammaBeta,
1131 UINT4 spinTemplates
1132)
1133{
1134 UINT4 ifoNumber,vecLength,vecLengthTwo,ui;
1135 REAL4TimeSeries *cohSNR,*nullSNR,*traceSNR;
1136 char name[LALNameLength];
1137 CHAR ifoName[LIGOMETA_IFO_MAX];
1138 cohSNR = NULL;
1139 nullSNR = NULL;
1140 traceSNR = NULL;
1141
1142 /* Generate the various time series as needed*/
1143 /* We only want to store data from middle half of segment */
1144 cohSNR = XLALCreateREAL4TimeSeries("cohSNR", &segStartTime,\
1145 fLower,(1.0/params->sampleRate),\
1147 params->numAnalPoints);
1148
1149 if (params->doNullStream)
1150 nullSNR = XLALCreateREAL4TimeSeries("nullSNR", &segStartTime,\
1151 fLower,(1.0/params->sampleRate),\
1153 params->numAnalPoints);
1154
1155 if (params->doTraceSNR)
1156 traceSNR = XLALCreateREAL4TimeSeries("traceSNR", &segStartTime,\
1157 fLower,(1.0/params->sampleRate),\
1159 params->numAnalPoints);
1160
1161 for (ifoNumber = 0;ifoNumber < LAL_NUM_IFO; ifoNumber++)
1162 {
1163 if (params->haveTrig[ifoNumber])
1164 {
1165 XLALReturnIFO(ifoName,ifoNumber);
1166 snprintf( name, sizeof( name ), "%s_snr",ifoName);
1167 snrComps[ifoNumber] = XLALCreateREAL4TimeSeries(name,
1168 &segStartTime,fLower,(1.0/params->sampleRate),
1169 &lalDimensionlessUnit,params->numAnalPointsBuf);
1170 }
1171 }
1172
1173 if (params->doBankVeto)
1174 {
1175 if (params->numIFO != 1)
1176 {
1177 bankVeto[LAL_NUM_IFO] = XLALCreateREAL4TimeSeries("bank_veto",\
1178 &segStartTime,\
1179 fLower,(1.0/params->sampleRate),\
1181 params->numAnalPoints);
1182 }
1183 if (params->doSnglChiSquared)
1184 {
1185 for (ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
1186 {
1187 if (params->haveTrig[ifoNumber])
1188 {
1189 XLALReturnIFO(ifoName,ifoNumber);
1190 snprintf( name, sizeof( name ), "%s_bank_veto",ifoName);
1191 bankVeto[ifoNumber] = XLALCreateREAL4TimeSeries(name,&segStartTime,\
1192 fLower,(1.0/params->sampleRate),\
1194 params->numAnalPoints);
1195 }
1196 }
1197 }
1198 }
1199
1200 if (params->doAutoVeto)
1201 {
1202 if (params->numIFO != 1)
1203 {
1204 autoVeto[LAL_NUM_IFO] = XLALCreateREAL4TimeSeries("auto_veto",\
1205 &segStartTime,\
1206 fLower,(1.0/params->sampleRate),\
1208 params->numAnalPoints);
1209 }
1210 if (params->doSnglChiSquared)
1211 {
1212 for (ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
1213 {
1214 if (params->haveTrig[ifoNumber])
1215 {
1216 XLALReturnIFO(ifoName,ifoNumber);
1217 snprintf( name, sizeof( name ), "%s_auto_veto",ifoName);
1218 autoVeto[ifoNumber] = XLALCreateREAL4TimeSeries(name,&segStartTime,\
1219 fLower,(1.0/params->sampleRate),\
1221 params->numAnalPoints);
1222 }
1223 }
1224 }
1225 }
1226
1227 if (params->doChiSquare)
1228 {
1229 if (params->numIFO != 1)
1230 {
1231 chiSquare[LAL_NUM_IFO] = XLALCreateREAL4TimeSeries("chi_square",\
1232 &segStartTime,\
1233 fLower,(1.0/params->sampleRate),\
1235 params->numAnalPoints);
1236 }
1237 if (params->doSnglChiSquared)
1238 {
1239 for (ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
1240 {
1241 if (params->haveTrig[ifoNumber])
1242 {
1243 XLALReturnIFO(ifoName,ifoNumber);
1244 snprintf( name, sizeof( name ), "%s_chi_square",ifoName);
1245 chiSquare[ifoNumber] = XLALCreateREAL4TimeSeries(name,&segStartTime,\
1246 fLower,(1.0/params->sampleRate),\
1248 params->numAnalPoints);
1249 }
1250 }
1251 }
1252 }
1253
1254 /* Work out how many pValue arrays are needed */
1255 if (spinTemplates)
1256 vecLength = 5;
1257 else
1258 vecLength = 2;
1259 if (params->numIFO == 1 || params->singlePolFlag || params->faceOnStatistic)
1260 vecLengthTwo = vecLength;
1261 else
1262 vecLengthTwo = 2* vecLength;
1263
1264 for (ui = 0 ; ui < vecLengthTwo ; ui++)
1265 {
1266 pValues[ui] = XLALCreateREAL4TimeSeries("Pvalue", &segStartTime,\
1267 fLower, (1.0/params->sampleRate),\
1269 params->numAnalPoints);
1270 }
1271
1272 if (spinTemplates)
1273 {
1274 for (ui = 0 ; ui < 2 ; ui++)
1275 {
1276 gammaBeta[ui] = XLALCreateREAL4TimeSeries("Pvalue", &segStartTime,\
1277 fLower, (1.0/params->sampleRate),\
1279 params->numAnalPoints);
1280 }
1281 }
1282
1283 *cohSNRP = cohSNR;
1284 *nullSNRP = nullSNR;
1285 *traceSNRP = traceSNR;
1286
1287}
1288
1290 struct coh_PTF_params *params,
1291 LIGOTimeGPS segStartTime,
1292 REAL4TimeSeries *cohSNR,
1293 REAL4TimeSeries *nullSNR,
1294 REAL4TimeSeries *traceSNR,
1295 REAL4TimeSeries **bankVeto,
1296 REAL4TimeSeries **autoVeto,
1297 REAL4TimeSeries **chiSquare,
1298 REAL4TimeSeries **snrComps,
1299 REAL4TimeSeries **pValues,
1300 REAL4TimeSeries **gammaBeta,
1301 UINT4 spinTemplates
1302)
1303{
1304 UINT4 ifoNumber,vecLength,vecLengthTwo,ui;
1305
1306 /* For each of the time series we reset the epoch*/
1307 cohSNR->epoch.gpsSeconds = segStartTime.gpsSeconds;
1308 cohSNR->epoch.gpsNanoSeconds = segStartTime.gpsNanoSeconds;
1309 /* And memset to 0 all values */
1310 memset(cohSNR->data->data, 0, params->numAnalPoints * sizeof(REAL4));
1311
1312 for (ifoNumber = 0;ifoNumber < LAL_NUM_IFO; ifoNumber++)
1313 {
1314 if (params->haveTrig[ifoNumber])
1315 {
1316 snrComps[ifoNumber]->epoch.gpsSeconds = segStartTime.gpsSeconds;
1317 snrComps[ifoNumber]->epoch.gpsNanoSeconds = \
1318 segStartTime.gpsNanoSeconds;
1319 memset(snrComps[ifoNumber]->data->data, 0,\
1320 params->numAnalPointsBuf * sizeof(REAL4));
1321 }
1322 }
1323
1324
1325 if (params->doNullStream)
1326 {
1327 nullSNR->epoch.gpsSeconds = segStartTime.gpsSeconds;
1328 nullSNR->epoch.gpsNanoSeconds = segStartTime.gpsNanoSeconds;
1329 memset(nullSNR->data->data, 0, params->numAnalPoints * sizeof(REAL4));
1330 }
1331
1332 if (params->doTraceSNR)
1333 {
1334 traceSNR->epoch.gpsSeconds = segStartTime.gpsSeconds;
1335 traceSNR->epoch.gpsNanoSeconds = segStartTime.gpsNanoSeconds;
1336 memset(traceSNR->data->data, 0, params->numAnalPoints * sizeof(REAL4));
1337 }
1338
1339 if (params->doBankVeto)
1340 {
1341 if (params->numIFO != 1)
1342 {
1343 bankVeto[LAL_NUM_IFO]->epoch.gpsSeconds = segStartTime.gpsSeconds;
1344 bankVeto[LAL_NUM_IFO]->epoch.gpsNanoSeconds = segStartTime.gpsNanoSeconds;
1345 memset(bankVeto[LAL_NUM_IFO]->data->data, 0,\
1346 params->numAnalPoints * sizeof(REAL4));
1347 }
1348 if (params->doSnglChiSquared)
1349 {
1350 for (ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
1351 {
1352 if (params->haveTrig[ifoNumber])
1353 {
1354 bankVeto[ifoNumber]->epoch.gpsSeconds = segStartTime.gpsSeconds;
1355 bankVeto[ifoNumber]->epoch.gpsNanoSeconds = \
1356 segStartTime.gpsNanoSeconds;
1357 memset(bankVeto[ifoNumber]->data->data, 0,\
1358 params->numAnalPoints * sizeof(REAL4));
1359 }
1360 }
1361 }
1362 }
1363
1364 if (params->doAutoVeto)
1365 {
1366 if (params->numIFO != 1)
1367 {
1368 autoVeto[LAL_NUM_IFO]->epoch.gpsSeconds = segStartTime.gpsSeconds;
1369 autoVeto[LAL_NUM_IFO]->epoch.gpsNanoSeconds = segStartTime.gpsNanoSeconds;
1370 memset(autoVeto[LAL_NUM_IFO]->data->data, 0,\
1371 params->numAnalPoints * sizeof(REAL4));
1372 }
1373 if (params->doSnglChiSquared)
1374 {
1375 for (ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
1376 {
1377 if (params->haveTrig[ifoNumber])
1378 {
1379 autoVeto[ifoNumber]->epoch.gpsSeconds = segStartTime.gpsSeconds;
1380 autoVeto[ifoNumber]->epoch.gpsNanoSeconds = \
1381 segStartTime.gpsNanoSeconds;
1382 memset(autoVeto[ifoNumber]->data->data, 0,\
1383 params->numAnalPoints * sizeof(REAL4));
1384 }
1385 }
1386 }
1387 }
1388
1389 if (params->doChiSquare)
1390 {
1391 if (params->numIFO != 1)
1392 {
1393 chiSquare[LAL_NUM_IFO]->epoch.gpsSeconds = segStartTime.gpsSeconds;
1394 chiSquare[LAL_NUM_IFO]->epoch.gpsNanoSeconds = \
1395 segStartTime.gpsNanoSeconds;
1396 memset(chiSquare[LAL_NUM_IFO]->data->data, 0,\
1397 params->numAnalPoints * sizeof(REAL4));
1398 }
1399 if (params->doSnglChiSquared)
1400 {
1401 for (ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
1402 {
1403 if (params->haveTrig[ifoNumber])
1404 {
1405 chiSquare[ifoNumber]->epoch.gpsSeconds = segStartTime.gpsSeconds;
1406 chiSquare[ifoNumber]->epoch.gpsNanoSeconds = \
1407 segStartTime.gpsNanoSeconds;
1408 memset(chiSquare[ifoNumber]->data->data, 0,\
1409 params->numAnalPoints * sizeof(REAL4));
1410 }
1411 }
1412 }
1413 }
1414
1415 /* Work out how many pValue arrays are needed */
1416 if (spinTemplates)
1417 vecLength = 5;
1418 else
1419 vecLength = 2;
1420 if (params->numIFO == 1 || params->singlePolFlag || params->faceOnStatistic)
1421 vecLengthTwo = vecLength;
1422 else
1423 vecLengthTwo = 2* vecLength;
1424
1425 for (ui = 0 ; ui < vecLengthTwo ; ui++)
1426 {
1427 pValues[ui]->epoch.gpsSeconds = segStartTime.gpsSeconds;
1428 pValues[ui]->epoch.gpsNanoSeconds = segStartTime.gpsNanoSeconds;
1429 memset(pValues[ui]->data->data, 0,\
1430 params->numAnalPoints * sizeof(REAL4));
1431 }
1432
1433 if (spinTemplates)
1434 {
1435 for (ui = 0 ; ui < 2 ; ui++)
1436 {
1437 gammaBeta[ui]->epoch.gpsSeconds = segStartTime.gpsSeconds;
1438 gammaBeta[ui]->epoch.gpsNanoSeconds = segStartTime.gpsNanoSeconds;
1439 memset(gammaBeta[ui]->data->data,0 ,\
1440 params->numAnalPoints * sizeof(REAL4));
1441 }
1442 }
1443
1444}
1445
1446
1448 REAL4TimeSeries *cohSNR,
1449 REAL4TimeSeries *nullSNR,
1450 REAL4TimeSeries *traceSNR,
1451 REAL4TimeSeries **bankVeto,
1452 REAL4TimeSeries **autoVeto,
1453 REAL4TimeSeries **chiSquare,
1454 REAL4TimeSeries **pValues,
1455 REAL4TimeSeries **gammaBeta,
1456 REAL4TimeSeries **snrComps
1457)
1458{
1459 UINT4 k;
1460
1461 if (cohSNR) XLALDestroyREAL4TimeSeries(cohSNR);
1462 if (nullSNR) XLALDestroyREAL4TimeSeries(nullSNR);
1463 if (traceSNR) XLALDestroyREAL4TimeSeries(traceSNR);
1464
1465 for (k = 0; k < LAL_NUM_IFO+1; k++)
1466 {
1467 if (bankVeto[k])
1468 {
1469 XLALDestroyREAL4TimeSeries(bankVeto[k]);
1470 bankVeto[k]=NULL;
1471 }
1472 if (autoVeto[k])
1473 {
1474 XLALDestroyREAL4TimeSeries(autoVeto[k]);
1475 autoVeto[k]=NULL;
1476 }
1477 if (chiSquare[k])
1478 {
1479 XLALDestroyREAL4TimeSeries(chiSquare[k]);
1480 chiSquare[k]=NULL;
1481 }
1482 }
1483
1484
1485 for (k = 0 ; k < 10 ; k++)
1486 {
1487 if (pValues[k])
1488 {
1489 XLALDestroyREAL4TimeSeries(pValues[k]);
1490 pValues[k] = NULL;
1491 }
1492 }
1493
1494 for (k = 0; k < LAL_NUM_IFO; k++)
1495 {
1496 if (snrComps[k])
1497 {
1498 XLALDestroyREAL4TimeSeries(snrComps[k]);
1499 snrComps[k] = NULL;
1500 }
1501 }
1502 for (k = 0; k < 2; k++)
1503 {
1504 if (gammaBeta[k])
1505 {
1506 XLALDestroyREAL4TimeSeries(gammaBeta[k]);
1507 gammaBeta[k] = NULL;
1508 }
1509 }
1510}
1511
1513 struct coh_PTF_params *params,
1514 FindChirpTemplate *fcTmplt,
1515 REAL4FrequencySeries **invspec,
1516 REAL8Array **PTFM,
1517 COMPLEX8VectorSequence **PTFqVec,
1518 REAL4TimeSeries **snrComps,
1519 UINT4 **snglAcceptPoints,
1520 UINT4 *snglAcceptCount,
1521 RingDataSegments **segments,
1522 COMPLEX8FFTPlan *invPlan,
1523 UINT4 spinTemplate,
1524 UINT4 segNum
1525)
1526{
1527 UINT4 ifoNumber,ui,uj,localCount;
1528 REAL4 reSNRcomp,imSNRcomp;
1529 REAL4 *localSNRData;
1530 UINT4 *localAcceptPoints;
1531
1532 REAL4 acceptThresh = params->snglSNRThreshold;
1533
1534 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
1535 {
1536 if (params->haveTrig[ifoNumber])
1537 {
1538 localCount = 0;
1539 localSNRData = snrComps[ifoNumber]->data->data;
1540 localAcceptPoints = snglAcceptPoints[ifoNumber];
1541 /* Zero the storage vectors for the PTF filters */
1542 if (params->approximant == FindChirpPTF)
1543 {
1544 memset(PTFM[ifoNumber]->data, 0, 25 * sizeof(REAL8));
1545 memset(PTFqVec[ifoNumber]->data, 0,
1546 5 * params->numTimePoints * sizeof(COMPLEX8));
1547 }
1548 else
1549 {
1550 memset(PTFM[ifoNumber]->data, 0, 1 * sizeof(REAL8));
1551 memset(PTFqVec[ifoNumber]->data, 0,
1552 1 * params->numTimePoints * sizeof(COMPLEX8));
1553 }
1554
1555 /* Here (h|s) and (h|h) are calculated */
1556 coh_PTF_normalize(params, fcTmplt, invspec[ifoNumber],
1557 PTFM[ifoNumber], NULL, PTFqVec[ifoNumber],
1558 &segments[ifoNumber]->sgmnt[segNum], invPlan,
1559 spinTemplate);
1560
1561 /* Here we calculate the single detector SNR */
1562 if (spinTemplate)
1563 {
1564 localCount = coh_PTF_calculate_single_det_spin_snr(params,PTFM,PTFqVec,\
1565 snrComps,ifoNumber,localAcceptPoints);
1566 }
1567 else
1568 {
1569 for (ui = params->analStartPointBuf; ui < params->analEndPointBuf; ++ui)
1570 { /* Loop over time */
1571 uj = ui - params->analStartPointBuf;
1572 reSNRcomp = crealf(PTFqVec[ifoNumber]->data[ui]);
1573 imSNRcomp = cimagf(PTFqVec[ifoNumber]->data[ui]);
1574 localSNRData[uj] = sqrt((reSNRcomp*reSNRcomp + imSNRcomp*imSNRcomp)/
1575 PTFM[ifoNumber]->data[0]);
1576 if (localSNRData[uj] > acceptThresh)
1577 {
1578 localAcceptPoints[localCount] = uj;
1579 localCount++;
1580 }
1581 }
1582 }
1583 snglAcceptCount[ifoNumber] = localCount;
1584
1585 }
1586 }
1587}
1588
1590 struct coh_PTF_params *params,
1591 REAL8Array **PTFM,
1592 COMPLEX8VectorSequence **PTFqVec,
1593 REAL4TimeSeries **snrComps,
1594 UINT4 ifoNumber,
1595 UINT4 *localAcceptPoints
1596)
1597{
1598 UINT4 ui,uj,uk,localCount;
1599 gsl_matrix *PTFmatrix;
1600 gsl_vector *eigenvalsSngl;
1601 gsl_matrix *eigenvecsSngl;
1602 gsl_eigen_symmv_workspace *matTemp = gsl_eigen_symmv_alloc(5);
1603 REAL4 v1_dot_u1, v1_dot_u2, v2_dot_u1, v2_dot_u2,max_eigen;
1604 REAL4 *snglv1p,*snglv2p;
1605 eigenvecsSngl = gsl_matrix_alloc(5,5);
1606 eigenvalsSngl = gsl_vector_alloc(5);
1607 snglv1p = LALCalloc(5 , sizeof(REAL4));
1608 snglv2p = LALCalloc(5 , sizeof(REAL4));
1609 REAL4 acceptThresh = params->snglSNRThreshold;
1610
1611 /* convert PTFM to gsl_matrix */
1612 PTFmatrix = gsl_matrix_alloc(5,5);
1613 for (ui = 0; ui < 5; ui++ )
1614 {
1615 for (uj = 0; uj < 5; uj++ )
1616 {
1617 gsl_matrix_set(PTFmatrix, ui, uj, PTFM[ifoNumber]->data[ui*5+uj]);
1618 }
1619 }
1620
1621 /* calculate eigenvectors and eigenvalues of (h|h)*/
1622 gsl_eigen_symmv(PTFmatrix, eigenvalsSngl, eigenvecsSngl,matTemp);
1623 gsl_eigen_symmv_free(matTemp);
1624 gsl_matrix_free(PTFmatrix);
1625 localCount = 0;
1626 for (ui = params->analStartPointBuf; ui < params->analEndPointBuf; ++ui)
1627 { /* loop over time */
1628 uk = ui - params->analStartPointBuf;
1629 coh_PTF_calculate_rotated_vectors(params,PTFqVec,snglv1p,snglv2p,NULL,\
1630 NULL,NULL,eigenvecsSngl,eigenvalsSngl,\
1631 params->numTimePoints,ui,5,5,ifoNumber);
1632
1633 /* Compute the dot products */
1634 v1_dot_u1 = v1_dot_u2 = v2_dot_u1 = v2_dot_u2 = max_eigen = 0.0;
1635 for (uj = 0; uj < 5; uj++)
1636 {
1637 v1_dot_u1 += snglv1p[uj] * snglv1p[uj];
1638 v1_dot_u2 += snglv1p[uj] * snglv2p[uj];
1639 v2_dot_u2 += snglv2p[uj] * snglv2p[uj];
1640 }
1641 max_eigen =0.5 * (v1_dot_u1 + v2_dot_u2 + sqrt((v1_dot_u1 - v2_dot_u2) * \
1642 (v1_dot_u1 - v2_dot_u2) + 4 * v1_dot_u2 * v1_dot_u2));
1643 snrComps[ifoNumber]->data->data[ui-params->analStartPointBuf] =\
1644 sqrt(max_eigen);
1645 if (snrComps[ifoNumber]->data->data[ui-params->analStartPointBuf] >\
1646 acceptThresh)
1647 {
1648 localAcceptPoints[localCount] = uk;
1649 localCount++;
1650 }
1651
1652 }
1653 LALFree(snglv1p);
1654 LALFree(snglv2p);
1655 return localCount;
1656}
1657
1659 REAL4 *v1p,
1660 REAL4 *v2p,
1661 UINT4 vecLengthTwo
1662)
1663{
1664 UINT4 ui;
1665 REAL4 v1_dot_u1,v1_dot_u2,v2_dot_u2,max_eigen;
1666 v1_dot_u1 = v1_dot_u2 = v2_dot_u2 = 0.0;
1667 for (ui =0; ui < vecLengthTwo; ui++)
1668 {
1669 v1_dot_u1 += v1p[ui] * v1p[ui];
1670 v2_dot_u2 += v2p[ui] * v2p[ui];
1671 v1_dot_u2 += v1p[ui] * v2p[ui];
1672 }
1673 max_eigen = 0.5 * (v1_dot_u1 + v2_dot_u2 + sqrt((v1_dot_u1 - v2_dot_u2)
1674 * (v1_dot_u1 - v2_dot_u2) + 4 * v1_dot_u2 * v1_dot_u2));
1675 return sqrt(max_eigen);
1676}
1677
1678/* THIS FUNCTION IS COMMENTED OUT SO IT CAN BE VERIFIED AND FIXED*/
1679/* void coh_PTF_get_spin_amp_terms(
1680XXXXX
1681)
1682 coh_PTF_calculate_rotated_vectors(params,PTFqVec,v1p,v2p,Fplus,Fcross,timeOffsetPoints,
1683 eigenvecs,eigenvals,numPoints,i,vecLength,vecLengthTwo,LAL_NUM_IFO);
1684 v1_dot_u1 = v1_dot_u2 = v2_dot_u1 = v2_dot_u2 = 0;
1685 for (j = 0; j < vecLengthTwo; j++)
1686 {
1687 u1[j] = v1p[j] / (pow(gsl_vector_get(eigenvals,j),0.5));
1688 u2[j] = v2p[j] / (pow(gsl_vector_get(eigenvals,j),0.5));
1689 v1[j] = u1[j] * gsl_vector_get(eigenvals,j);
1690 v2[j] = u2[j] * gsl_vector_get(eigenvals,j);
1691 v1_dot_u1 += v1[j]*u1[j];
1692 v1_dot_u2 += v1[j]*u2[j];
1693 v2_dot_u2 += v2[j]*u2[j];
1694 }
1695 dCee = (max_eigen - v1_dot_u1) / v1_dot_u2;
1696 dAlpha = 1./(v1_dot_u1 + dCee * 2 * v1_dot_u2 + dCee*dCee*v2_dot_u2);
1697 dAlpha = pow(dAlpha,0.5);
1698 dBeta = dCee*dAlpha;
1699 // The p Values are calculated in the rotated frame
1700 for (j = 0 ; j < vecLengthTwo ; j++)
1701 {
1702 pValsTemp[j] = dAlpha*u1[j] + dBeta*u2[j];
1703 pValues[j]->data->data[i - numPoints/4] = 0.;
1704 }
1705 // This loop can be used to verify that the SNR obtained is as before
1706 recSNR = 0;
1707 for (j = 0 ; j < vecLengthTwo ; j++)
1708 {
1709 for (k = 0 ; k < vecLengthTwo ; k++)
1710 {
1711 recSNR += pValsTemp[j]*pValsTemp[k] * (v1[j]*v1[k]+v2[j]*v2[k]);
1712 }
1713 }
1714 // Then we calculate the two phase/amplitude terms beta and gamma
1715 // These are explained in Diego's thesis
1716 betaGammaTemp[0] = 0;
1717 betaGammaTemp[1] = 0;
1718 for (j = 0 ; j < vecLengthTwo ; j++)
1719 {
1720 betaGammaTemp[0] += pValsTemp[j]*v1[j];
1721 betaGammaTemp[1] += pValsTemp[j]*v2[j];
1722 }
1723 gammaBeta[0]->data->data[i - numPoints/4] = betaGammaTemp[0];
1724 gammaBeta[1]->data->data[i - numPoints/4] = betaGammaTemp[1];
1725
1726 // The p Values need to be rotated back into the original frame.
1727 // Currently we are recording values in rotated frame
1728 for (j = 0 ; j < vecLengthTwo ; j++)
1729 {
1730 for (k = 0 ; k < vecLengthTwo ; k++)
1731 {
1732 pValues[j]->data->data[i-numPoints/4]+=gsl_matrix_get(eigenvecs,j,k)*pValsTemp[k];
1733 }
1734 }
1735
1736 // And we check that this still gives the expected SNR in the
1737 // unrotated basis.
1738 for (j = 0; j < vecLengthTwo ; j++) // Construct the vi vectors
1739 {
1740 v1[j] = 0.;
1741 v2[j] = 0.;
1742 for(k = 0; k < LAL_NUM_IFO; k++)
1743 {
1744 if (params->haveTrig[k])
1745 {
1746 if (j < vecLength)
1747 {
1748 v1[j] += Fplus[k] * crealf(PTFqVec[k]->data[j*numPoints+i+timeOffsetPoints[k]]);
1749 v2[j] += Fplus[k] * cimagf(PTFqVec[k]->data[j*numPoints+i+timeOffsetPoints[k]]);
1750 }
1751 else
1752 {
1753 v1[j] += Fcross[k] * crealf(PTFqVec[k]->data[(j-vecLength)*numPoints+i+timeOffsetPoints[k]]);
1754 v2[j] += Fcross[k] * cimagf(PTFqVec[k]->data[(j-vecLength)*numPoints+i+timeOffsetPoints[k]]);
1755 }
1756 }
1757 }
1758 }
1759 recSNR = 0;
1760 for (j = 0 ; j < vecLengthTwo ; j++)
1761 {
1762 for (k = 0 ; k < vecLengthTwo ; k++)
1763 {
1764 recSNR += pValues[j]->data->data[i-numPoints/4]*pValues[k]->data->data[i-numPoints/4] * (v1[j]*v1[k]+v2[j]*v2[k]);
1765 }
1766 }
1767}
1768*/
1769
1771 struct coh_PTF_params *params,
1772 REAL4 *snrData,
1773 REAL4TimeSeries **pValues,
1774 REAL4TimeSeries **snrComps,
1775 INT4 *timeOffsetPoints,
1776 COMPLEX8VectorSequence **PTFqVec,
1777 REAL4 *Fplus,
1778 REAL4 *Fcross,
1779 gsl_matrix *eigenvecs,
1780 gsl_vector *eigenvals,
1781 UINT4 segStartPoint,
1782 UINT4 segEndPoint,
1783 UINT4 vecLength,
1784 UINT4 vecLengthTwo,
1785 UINT4 spinTemplate,
1786 UINT4 **snglAcceptPoints,
1787 UINT4 *snglAcceptCount
1788)
1789{
1790 REAL4 snglSNRthresh = params->snglSNRThreshold;
1791 REAL4 *v1p = LALCalloc(vecLengthTwo , sizeof(REAL4));
1792 REAL4 *v2p = LALCalloc(vecLengthTwo , sizeof(REAL4));
1793
1794 UINT4 i,j,k,ifoNumber,ifoNumber2,currPointLoc,ifoNum1,ifoNum2;
1795 UINT4 localCount,*localAcceptPoints,localOffset;
1796 INT4 tOffset1,tOffset2;
1797 REAL4 v1_dot_u1,v2_dot_u2,max_eigen,coincSNR;
1798 REAL4 cohSNRThresholdSq = params->threshold * params->threshold;
1799
1800 /* If only two detectors & standard analysis identify the 2 detectors
1801 * up front for speed
1802 */
1803 ifoNum1 = ifoNum2 = tOffset1 = tOffset2 = 0;
1804 if (params->numIFO == 2 && (! params->singlePolFlag) &&\
1805 (!params->faceOnStatistic) )
1806 {
1807 for (ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
1808 {
1809 if (params->haveTrig[ifoNumber])
1810 {
1811 if (ifoNum1 == 0)
1812 ifoNum1 = ifoNumber;
1813 else if (ifoNum2 == 0)
1814 ifoNum2 = ifoNumber;
1815 }
1816 }
1817 tOffset1 = timeOffsetPoints[ifoNum1] - params->analStartPointBuf;
1818 tOffset2 = timeOffsetPoints[ifoNum2] - params->analStartPointBuf;
1819 }
1820
1821 for (ifoNumber2 = 0; ifoNumber2 < LAL_NUM_IFO; ifoNumber2++)
1822 {
1823 if (! params->haveTrig[ifoNumber2])
1824 {
1825 continue;
1826 }
1827 localCount = snglAcceptCount[ifoNumber2];
1828 localAcceptPoints = snglAcceptPoints[ifoNumber2];
1829 localOffset = params->analStartPointBuf-timeOffsetPoints[ifoNumber2];
1830 for (k = 0; k < localCount; ++k)
1831 {
1832 i = localAcceptPoints[k] + localOffset;
1833 currPointLoc = i-params->analStartPoint;
1834 /* Continue if not in this analysis segment */
1835 if ((i < segStartPoint) || (i > segEndPoint))
1836 {
1837 continue;
1838 }
1839
1840 /* Don't bother calculating coherent SNR if all ifo's SNR is less than
1841 some value */
1842 for (ifoNumber = 0;ifoNumber < LAL_NUM_IFO; ifoNumber++)
1843 {
1844 if (params->haveTrig[ifoNumber])
1845 {
1846 if (snrComps[ifoNumber]->data->
1847 data[i-params->analStartPointBuf+timeOffsetPoints[ifoNumber]]
1848 > snglSNRthresh)
1849 {
1850 break;
1851 }
1852 }
1853 }
1854 if (ifoNumber == LAL_NUM_IFO)
1855 {
1856 snrData[currPointLoc] = 0;
1857 fprintf(stderr,"I shouldn't be here now!!\n");
1858 continue;
1859 }
1860
1861 if (params->numIFO == 2 && (! params->singlePolFlag) &&\
1862 (!params->faceOnStatistic) )
1863 { /*If only 2 detectors cohSNR = coincident SNR. SO just use that */
1864 max_eigen = snrComps[ifoNum1]->data->data[i+tOffset1] *
1865 snrComps[ifoNum1]->data->data[i+tOffset1] +
1866 snrComps[ifoNum2]->data->data[i+tOffset2] *
1867 snrComps[ifoNum2]->data->data[i+tOffset2];
1868 if (max_eigen < cohSNRThresholdSq)
1869 {
1870 snrData[currPointLoc] = 0;
1871 continue;
1872 }
1873 snrData[currPointLoc] = sqrt(max_eigen);
1874 if (params->storeAmpParams)
1875 {
1876 coh_PTF_calculate_rotated_vectors(params,PTFqVec,v1p,v2p,Fplus,Fcross,
1877 timeOffsetPoints,eigenvecs,eigenvals,
1878 params->numTimePoints,i,vecLength,vecLengthTwo,LAL_NUM_IFO);
1879 for (j = 0 ; j < vecLengthTwo ; j++)
1880 {
1881 pValues[j]->data->data[currPointLoc] = \
1882 v1p[j] / (pow(gsl_vector_get(eigenvals,j),0.5));
1883 pValues[j+vecLengthTwo]->data->data[currPointLoc] = \
1884 v2p[j] / (pow(gsl_vector_get(eigenvals,j),0.5));
1885 }
1886 }
1887 }
1888 else
1889 {
1890 coincSNR = 0;
1891 /* Calculate the coincident SNR at this time point*/
1892 for (ifoNumber = 0;ifoNumber < LAL_NUM_IFO; ifoNumber++)
1893 {
1894 if (params->haveTrig[ifoNumber])
1895 {
1896 coincSNR += snrComps[ifoNumber]->data->data[\
1897 i - params->analStartPointBuf + timeOffsetPoints[ifoNumber]]
1898 * snrComps[ifoNumber]->data->data[\
1899 i - params->analStartPointBuf + timeOffsetPoints[ifoNumber]];
1900 }
1901 }
1902 /* Do not need to calculate coherent SNR if coinc SNR < threshold */
1903 /* NOTE: Cheaper to compare coincSNRSq than use pow(x,0.5) */
1904 if (coincSNR < cohSNRThresholdSq)
1905 {
1906 snrData[currPointLoc] = 0;
1907 continue;
1908 }
1909
1910 /* This function combines the various (Q_i | s) and rotates them into
1911 * the orthonormal basis, using the eigen[vector,value]s.
1912 */
1913 coh_PTF_calculate_rotated_vectors(params,PTFqVec,v1p,v2p,Fplus,Fcross,
1914 timeOffsetPoints,eigenvecs,eigenvals,
1915 params->numTimePoints,i,vecLength,vecLengthTwo,LAL_NUM_IFO);
1916
1917 /* And SNR is calculated
1918 * For non-spin+multi-site+coherent:
1919 * v1p[0] * v1p[0] = (\bf{F}_+\bf{h}_0 | \bf{s})^2
1920 * v1p[1] * v1p[1] = (\bf{F}_x\bf{h}_0 | \bf{s})^2
1921 * v2p[0] * v2p[0] = (\bf{F}_+\bf{h}_{\pi/2} | \bf{s})^2
1922 * v2p[1] * v2p[1] = (\bf{F}_x\bf{h}_{\pi/2} | \bf{s})^2
1923 * For non-spin+single-site/face-on there will only be two components
1924 * in this calculation, but otherwise the same.
1925 */
1926 if (spinTemplate == 0)
1927 {
1928 v1_dot_u1 = v2_dot_u2 = 0.0;
1929 for (j = 0; j < vecLengthTwo; j++)
1930 {
1931 v1_dot_u1 += v1p[j] * v1p[j];
1932 v2_dot_u2 += v2p[j] * v2p[j];
1933 }
1934 max_eigen = (v1_dot_u1 + v2_dot_u2);
1935 if (max_eigen < cohSNRThresholdSq)
1936 {
1937 snrData[currPointLoc] = 0;
1938 continue;
1939 }
1940 else
1941 {
1942 snrData[currPointLoc] = sqrt(max_eigen);
1943 if (params->storeAmpParams)
1944 {
1945 for (j = 0 ; j < vecLengthTwo ; j++)
1946 {
1947 pValues[j]->data->data[currPointLoc] = \
1948 v1p[j] / (pow(gsl_vector_get(eigenvals,j),0.5));
1949 pValues[j+vecLengthTwo]->data->data[currPointLoc] = \
1950 v2p[j] / (pow(gsl_vector_get(eigenvals,j),0.5));
1951 }
1952 }
1953 }
1954 }
1955 else
1956 { /* Spinning case follow PTF notation to get SNR */
1957 snrData[i-params->analStartPoint] = \
1958 coh_PTF_get_spin_SNR(v1p,v2p,vecLengthTwo);
1959 if (params->storeAmpParams)
1960 {
1961 fprintf(stderr,"Spinning amplitude stuff is currently disabled\n");
1962 /* coh_PTF_get_spin_amp_terms(.......) */
1963 }
1964 }
1965 }
1966 }
1967 }
1968}
1969
1971 struct coh_PTF_params *params,
1972 REAL4TimeSeries *cohSNR,
1973 UINT4 *acceptPoints,
1974 INT4 *timeOffsetPoints,
1975 INT4 numPointCheck,
1976 UINT4 startPoint,
1977 UINT4 endPoint,
1978 UINT4 **snglAcceptPoints,
1979 UINT4 *snglAcceptCount
1980)
1981{
1982 UINT4 ui,ifoNumber2,k,i;
1983 UINT4 count = 0;
1984 UINT4 logicArray[cohSNR->data->length];
1985 INT4 tempPoint, tempPointStart, tempPointEnd;
1986 /* FIXME: Bizarrely, the mac clang compiler will "optimize away" this variable
1987 * if I do not use the volatile keyword, which causes seg faults as it should
1988 * not be "optimized away". Is this a bug in clang??? */
1989 volatile INT4 localOffset;
1990 UINT4 localCount,*localAcceptPoints;
1991 /* Have to cast from UINT4 to INT4 to avoid warning */
1992 INT4 startPointI = (INT4) startPoint;
1993 INT4 endPointI = (INT4) endPoint;
1994
1995 REAL4 *snrData = cohSNR->data->data;
1996
1997 for (ifoNumber2 = 0; ifoNumber2 < LAL_NUM_IFO; ifoNumber2++)
1998 {
1999 if (! params->haveTrig[ifoNumber2])
2000 {
2001 continue;
2002 }
2003 localCount = snglAcceptCount[ifoNumber2];
2004 localAcceptPoints = snglAcceptPoints[ifoNumber2];
2005 localOffset = params->analStartPointBuf-timeOffsetPoints[ifoNumber2];
2006 for (k = 0; k < localCount; ++k)
2007 {
2008 i = localAcceptPoints[k] + localOffset;
2009 ui = i-params->analStartPoint;
2010 /* Continue if not in this analysis segment */
2011 if ((ui < startPoint) || (ui > endPoint))
2012 {
2013 continue;
2014 }
2015 logicArray[ui] = 1;
2016 if (snrData[ui])
2017 {
2018 tempPointStart = ui - numPointCheck;
2019 if (tempPointStart < startPointI)
2020 {
2021 tempPointStart = startPointI;
2022 }
2023 tempPointEnd = ui + numPointCheck;
2024 if (tempPointEnd >= endPointI)
2025 {
2026 tempPointEnd = endPointI;
2027 }
2028 for (tempPoint = tempPointStart; tempPoint < tempPointEnd; tempPoint++)
2029 {
2030 if (snrData[tempPoint] > snrData[ui])
2031 {
2032 logicArray[ui] = 0;
2033 break;
2034 }
2035 }
2036 }
2037 }
2038 }
2039
2040 for (ifoNumber2 = 0; ifoNumber2 < LAL_NUM_IFO; ifoNumber2++)
2041 {
2042 if (! params->haveTrig[ifoNumber2])
2043 {
2044 continue;
2045 }
2046 localCount = snglAcceptCount[ifoNumber2];
2047 localAcceptPoints = snglAcceptPoints[ifoNumber2];
2048 localOffset = params->analStartPointBuf-timeOffsetPoints[ifoNumber2];
2049 for (k = 0; k < localCount; ++k)
2050 {
2051 i = localAcceptPoints[k] + localOffset;
2052 ui = i-params->analStartPoint;
2053 /* Continue if not in this analysis segment */
2054 if ((ui < startPoint) || (ui > endPoint))
2055 {
2056 continue;
2057 }
2058
2059 if (! logicArray[ui])
2060 {
2061 snrData[ui] = 0.;
2062 }
2063 else if (logicArray[ui] == 1)
2064 {
2065 if (snrData[ui])
2066 {
2067 acceptPoints[count] = ui;
2068 count++;
2069 logicArray[ui] = 2;
2070 }
2071 }
2072 }
2073 }
2074 return count;
2075}
2076
2078 struct coh_PTF_params *params,
2079 REAL4TimeSeries *cohSNR,
2080 REAL4TimeSeries *nullSNR,
2081 REAL4TimeSeries **bankVeto,
2082 REAL4TimeSeries **autoVeto,
2083 UINT4 currPointLoc
2084)
2085{
2086 /* This function checks whether chisq needs to be calculated. It does this
2087 * by checking if the trigger will fail the bank/auto/null vetoes */
2088
2089 /* NOTE: The code currently uses the null stream SNR. It should instead/also
2090 * use the nullSNR calculated from coincSNR - cohSNR */
2091
2092 UINT4 numDOF;
2093 REAL4 bestNR,currSNR;
2094
2095 numDOF = 4.;
2096 if (params->singlePolFlag || params->faceOnStatistic || params->numIFO == 1)
2097 numDOF = 2.;
2098
2099 currSNR = cohSNR->data->data[currPointLoc];
2100
2101 /* IS the null stream too large? */
2102 if (params->doNullStream)
2103 {
2104 if (nullSNR->data->data[currPointLoc] > params->nullStatThreshold \
2105 && currSNR < params->nullStatGradOn)
2106 {
2107 return 1;
2108 }
2109 if (currSNR > params->nullStatGradOn)
2110 {
2111 if (nullSNR->data->data[currPointLoc] > (params->nullStatThreshold \
2112 + (currSNR - params->nullStatGradOn)*params->nullStatGradient))
2113 {
2114 return 1;
2115 }
2116 }
2117 }
2118
2119 /* Is bank new SNR too large? */
2120 if (params->doBankVeto)
2121 {
2122 if (bankVeto[LAL_NUM_IFO]->data->data[currPointLoc] > \
2123 params->BVsubBankSize*numDOF)
2124 {
2125 bestNR = currSNR / pow( ( 1. + pow( \
2126 bankVeto[LAL_NUM_IFO]->data->data[currPointLoc] / \
2127 ((REAL4)params->BVsubBankSize*numDOF ) , \
2128 params->bankVetoq/params->bankVeton) )/2. , 1./params->bankVetoq);
2129 if (bestNR < params->chiSquareCalcThreshold)
2130 {
2131 return 1;
2132 }
2133 }
2134 }
2135
2136 /* Is auto new SNR too large */
2137 if (params->doAutoVeto)
2138 {
2139 if (autoVeto[LAL_NUM_IFO]->data->data[currPointLoc] > \
2140 params->numAutoPoints*numDOF)
2141 {
2142 bestNR = currSNR / pow( ( 1. + pow( \
2143 autoVeto[LAL_NUM_IFO]->data->data[currPointLoc] / \
2144 ((REAL4)params->numAutoPoints*numDOF ) , \
2145 params->autoVetoq/params->autoVeton) )/2. , 1./params->autoVetoq);
2146 if (bestNR < params->chiSquareCalcThreshold)
2147 {
2148 return 1;
2149 }
2150 }
2151 }
2152 return 0;
2153}
2154
2156 struct coh_PTF_params *params,
2157 FindChirpTemplate *fcTmplt,
2158 REAL4FrequencySeries **invspec,
2159 REAL8Array **PTFM,
2160 COMPLEX8VectorSequence **PTFqVec,
2161 RingDataSegments **segments,
2162 COMPLEX8FFTPlan *invPlan,
2163 UINT4 spinTemplate,
2164 UINT4 segNum
2165)
2166{
2168 {
2169 memset(PTFM[LAL_NUM_IFO]->data, 0, 25*sizeof(REAL8));
2170 memset(PTFqVec[LAL_NUM_IFO]->data, 0,\
2171 5*params->numTimePoints*sizeof(COMPLEX8));
2172 }
2173 else
2174 {
2175 memset(PTFM[LAL_NUM_IFO]->data, 0, 1*sizeof(REAL8));
2176 memset(PTFqVec[LAL_NUM_IFO]->data, 0,\
2177 1*params->numTimePoints*sizeof(COMPLEX8));
2178 }
2179 coh_PTF_normalize(params, fcTmplt, invspec[LAL_NUM_IFO],
2180 PTFM[LAL_NUM_IFO], NULL, PTFqVec[LAL_NUM_IFO],
2181 &segments[LAL_NUM_IFO]->sgmnt[segNum], invPlan,
2182 spinTemplate);
2183}
2184
2186 UINT4 vecLength,
2187 gsl_matrix *eigenvecsNull,
2188 gsl_vector *eigenvalsNull,
2189 REAL8Array *PTFM[LAL_NUM_IFO+1]
2190)
2191{
2192 /* This function calculates the eigenvectors/values needed to orthonormalize
2193 * the filters when using the null stream
2194 */
2195
2196 /* For non-spinning case this is trivial */
2197 if (vecLength == 1)
2198 {
2199 gsl_matrix_set(eigenvecsNull, 0 , 0, 1);
2200 gsl_vector_set(eigenvalsNull, 0, PTFM[LAL_NUM_IFO]->data[0]);
2201 }
2202 /* For spinning case there is more to this */
2203 else
2204 {
2205 UINT4 i,j;
2206 gsl_eigen_symmv_workspace *matTempNull = gsl_eigen_symmv_alloc(vecLength);
2207 gsl_matrix *B2Null = gsl_matrix_alloc(vecLength, vecLength);
2208 for (i = 0; i < vecLength; i++)
2209 {
2210 for (j = 0; j < vecLength; j++)
2211 {
2212 gsl_matrix_set(B2Null, i, j, PTFM[LAL_NUM_IFO]->data[i*5+j]);
2213 }
2214 }
2215 gsl_eigen_symmv(B2Null, eigenvalsNull, eigenvecsNull, matTempNull);
2216 }
2217}
2218
2220 struct coh_PTF_params *params,
2221 REAL4TimeSeries *nullSNR,
2222 COMPLEX8VectorSequence **PTFqVec,
2223 gsl_matrix *eigenvecsNull,
2224 gsl_vector *eigenvalsNull,
2225 UINT4 spinTemplate,
2226 UINT4 vecLength,
2227 UINT4 vecLoc,
2228 UINT4 snrLoc
2229)
2230{
2231 UINT4 j,k;
2232 REAL4 v1_dot_u1,v1_dot_u2,v2_dot_u2,max_eigen;
2233 REAL4 v1N[vecLength],v2N[vecLength],u1N[vecLength],u2N[vecLength];
2234 /* Begin by rotating to the preferred vector */
2235 /* NOTE: For non-spin vecLength=1 and some of this is trivial */
2236 /* NOTE: This code could be optimized, but is rarely used so has not been */
2237 for (j = 0; j < vecLength; j++)
2238 {
2239 v1N[j] = crealf(PTFqVec[LAL_NUM_IFO]->data[j*params->numTimePoints+vecLoc]);
2240 v2N[j] = cimagf(PTFqVec[LAL_NUM_IFO]->data[j*params->numTimePoints+vecLoc]);
2241 }
2242
2243 for (j = 0 ; j < vecLength ; j++)
2244 {
2245 u1N[j] = 0.;
2246 u2N[j] = 0.;
2247 for (k = 0 ; k < vecLength ; k++)
2248 {
2249 u1N[j] += gsl_matrix_get(eigenvecsNull,k,j)*v1N[k];
2250 u2N[j] += gsl_matrix_get(eigenvecsNull,k,j)*v2N[k];
2251 }
2252 u1N[j] = u1N[j] / (pow(gsl_vector_get(eigenvalsNull,j),0.5));
2253 u2N[j] = u2N[j] / (pow(gsl_vector_get(eigenvalsNull,j),0.5));
2254 }
2255 /* Compute the dot products */
2256 v1_dot_u1 = v1_dot_u2 = v2_dot_u2 = 0.0;
2257 for (j = 0; j < vecLength; j++)
2258 {
2259 v1_dot_u1 += u1N[j] * u1N[j];
2260 v1_dot_u2 += u1N[j] * u2N[j];
2261 v2_dot_u2 += u2N[j] * u2N[j];
2262 }
2263 if (spinTemplate == 0)
2264 {
2265 max_eigen = 0.5 * (v1_dot_u1 + v2_dot_u2);
2266 }
2267 else
2268 {
2269 max_eigen = 0.5*(v1_dot_u1+v2_dot_u2+sqrt((v1_dot_u1-v2_dot_u2)
2270 * (v1_dot_u1 - v2_dot_u2) + 4 * v1_dot_u2 * v1_dot_u2));
2271 }
2272 nullSNR->data->data[snrLoc] = sqrt(max_eigen);
2273}
2274
2276 struct coh_PTF_params *params,
2277 REAL4TimeSeries *traceSNR,
2278 COMPLEX8VectorSequence **PTFqVec,
2279 gsl_matrix *eigenvecs,
2280 gsl_vector *eigenvals,
2281 REAL4 *Fplus,
2282 REAL4 *Fcross,
2283 INT4 *timeOffsetPoints,
2284 UINT4 spinTemplate,
2285 UINT4 vecLength,
2286 UINT4 vecLengthTwo,
2287 UINT4 vecLoc,
2288 UINT4 snrLoc
2289)
2290{
2291 UINT4 j,k,m;
2292 REAL4 v1_dot_u1,v1_dot_u2,v2_dot_u2,max_eigen,traceSNRsq;
2293 REAL4 v1[vecLength],v2[vecLength],u1[vecLength],u2[vecLength];
2294
2295 /* Trace SNR is the coherent SNR with no cross-detector terms */
2296 traceSNRsq = 0;
2297 for(k = 0; k < LAL_NUM_IFO; k++)
2298 {
2299 if (params->haveTrig[k])
2300 {
2301 for (j = 0; j < vecLengthTwo ; j++)
2302 {
2303 if (j < vecLength)
2304 {
2305 v1[j] = Fplus[k] * crealf(PTFqVec[k]->data[\
2306 j*params->numTimePoints+vecLoc+timeOffsetPoints[k]]);
2307 v2[j] = Fplus[k] * cimagf(PTFqVec[k]->data[\
2308 j*params->numTimePoints+vecLoc+timeOffsetPoints[k]]);
2309 }
2310 else
2311 {
2312 v1[j] = Fcross[k] * crealf(PTFqVec[k]->data[ (j-vecLength) * \
2313 params->numTimePoints+vecLoc+timeOffsetPoints[k]]);
2314 v2[j] = Fcross[k] * cimagf(PTFqVec[k]->data[ (j-vecLength) * \
2315 params->numTimePoints+vecLoc+timeOffsetPoints[k]]);
2316 }
2317 }
2318 for (j = 0 ; j < vecLengthTwo ; j++)
2319 {
2320 u1[j] = 0.;
2321 u2[j] = 0.;
2322 for (m = 0 ; m < vecLengthTwo ; m++)
2323 {
2324 u1[j] += gsl_matrix_get(eigenvecs,m,j)*v1[m];
2325 u2[j] += gsl_matrix_get(eigenvecs,m,j)*v2[m];
2326 }
2327 u1[j] = u1[j] / (pow(gsl_vector_get(eigenvals,j),0.5));
2328 u2[j] = u2[j] / (pow(gsl_vector_get(eigenvals,j),0.5));
2329 }
2330 /* Compute the dot products */
2331 v1_dot_u1 = v1_dot_u2 = v2_dot_u2 = max_eigen = 0.0;
2332 for (j = 0; j < vecLengthTwo; j++)
2333 {
2334 v1_dot_u1 += u1[j] * u1[j];
2335 v1_dot_u2 += u1[j] * u2[j];
2336 v2_dot_u2 += u2[j] * u2[j];
2337 }
2338 if (spinTemplate == 0)
2339 {
2340 max_eigen = (v1_dot_u1 + v2_dot_u2);
2341 }
2342 else
2343 {
2344 max_eigen = 0.5 * (v1_dot_u1 + v2_dot_u2 + sqrt((v1_dot_u1 - v2_dot_u2)
2345 * (v1_dot_u1 - v2_dot_u2) + 4 * v1_dot_u2 * v1_dot_u2));
2346 }
2347 traceSNRsq += max_eigen;
2348 }
2349 }
2350 traceSNR->data->data[snrLoc] = sqrt(traceSNRsq);
2351}
2352
2354 struct coh_PTF_params *params,
2355 REAL4 *timeOffsets,
2356 INT4 *timeOffsetPoints
2357)
2358{
2359 UINT4 i;
2360 REAL4 deltaT = (1.0/params->sampleRate);
2361 for (i = 0; i < LAL_NUM_IFO; i++)
2362 {
2363 timeOffsetPoints[i] = (int) floor(timeOffsets[i]/deltaT + 0.5);
2364 }
2365 /* The following is useful for debugging */
2366
2367 /*
2368 verbose("Time offsets (s): ");
2369 for (i = 0; i < LAL_NUM_IFO; i++)
2370 {
2371 if (params->haveTrig[i])
2372 {
2373 verbose("%f ", timeOffsets[i]);
2374 }
2375 }
2376 verbose("\n");
2377 verbose("Time offsets (points): ");
2378 for (i = 0; i < LAL_NUM_IFO; i++)
2379 {
2380 if (params->haveTrig[i])
2381 {
2382 verbose("%d " , timeOffsetPoints[i]);
2383 }
2384 }
2385 verbose("\n");
2386 */
2387}
2388
2390 struct coh_PTF_params *params,
2391 gsl_matrix *eigenvecs,
2392 gsl_vector *eigenvals,
2393 REAL4 Fplus[LAL_NUM_IFO],
2394 REAL4 Fcross[LAL_NUM_IFO],
2395 REAL8Array *PTFM[LAL_NUM_IFO+1],
2396 UINT4 vecLength,
2397 UINT4 vecLengthTwo,
2398 UINT4 PTFMlen
2399 )
2400{
2401 // This function calculates the eigenvectors and eigenvalues of the
2402 // coherent "B" matrix. This is the matrix that appears as B^{-1} in the
2403 // original definition of SNR for spin.
2404 // For non spin, the eigenvalues can be used to rotate to the dominant
2405 // polarization frame.
2406 UINT4 i,j,k;
2407 UINT4 vecLengthSquare = vecLength*vecLength;
2408 REAL4 zh[vecLengthSquare],sh[vecLengthSquare],yu[vecLengthSquare];
2409 gsl_matrix *B2 = gsl_matrix_alloc(vecLengthTwo,vecLengthTwo);
2410 gsl_eigen_symmv_workspace *matTemp = gsl_eigen_symmv_alloc (vecLengthTwo);
2411 /* Create and invert the Bmatrix */
2412 /* Note for nonSpin PTFM contains one entry per ifo, this is loop is then
2413 a lot simpler than it looks! For PTF there are 25 entries in PTFM!
2414 For non spin this stores (h_0|h_0)*/
2415 for (i = 0; i < vecLength; i++ )
2416 {
2417 for (j = 0; j < vecLength; j++ )
2418 {
2419 zh[i*vecLength+j] = 0;
2420 sh[i*vecLength+j] = 0;
2421 yu[i*vecLength+j] = 0;
2422 for( k = 0; k < LAL_NUM_IFO; k++)
2423 {
2424 if ( params->haveTrig[k] )
2425 {
2426 if ( params->faceOnStatistic )
2427 {
2428 zh[i*vecLength+j] += (Fplus[k]*Fplus[k] + Fcross[k] * Fcross[k])* PTFM[k]->data[i*PTFMlen+j];
2429 }
2430 else
2431 {
2432 zh[i*vecLength+j] += Fplus[k]*Fplus[k] * PTFM[k]->data[i*PTFMlen+j];
2433 sh[i*vecLength+j] += Fcross[k]*Fcross[k] * PTFM[k]->data[i*PTFMlen+j];
2434 yu[i*vecLength+j] += Fplus[k]*Fcross[k] * PTFM[k]->data[i*PTFMlen+j];
2435 }
2436 }
2437 }
2438 }
2439 }
2440
2441 /* GSL is used to do the rotation */
2442 for (i = 0; i < vecLengthTwo; i++ )
2443 {
2444 for (j = 0; j < vecLengthTwo; j++ )
2445 {
2446 if ( i < vecLength && j < vecLength )
2447 {
2448 gsl_matrix_set(B2,i,j,zh[i*vecLength+j]);
2449 }
2450 else if ( i > (vecLength-1) && j > (vecLength-1))
2451 {
2452 gsl_matrix_set(B2,i,j,sh[(i-vecLength)*vecLength + (j-vecLength)]);
2453 }
2454 else if ( i < vecLength && j > (vecLength-1))
2455 {
2456 gsl_matrix_set(B2,i,j, yu[i*vecLength + (j-vecLength)]);
2457 }
2458 else if ( i > (vecLength-1) && j < vecLength)
2459 {
2460 gsl_matrix_set(B2,i,j,yu[j*vecLength + (i-vecLength)]);
2461 }
2462 else
2463 fprintf(stderr,"BUGGER! Something went wrong.");
2464 }
2465 }
2466
2467 /* Here we compute the eigenvalues and eigenvectors of B2 */
2468 gsl_eigen_symmv (B2,eigenvals,eigenvecs,matTemp);
2469 gsl_eigen_symmv_free(matTemp);
2470 gsl_matrix_free(B2);
2471}
2472
2473
2475 struct coh_PTF_params *params,
2476 COMPLEX8VectorSequence **PTFqVec,
2477 REAL4 *u1,
2478 REAL4 *u2,
2479 REAL4 *Fplus,
2480 REAL4 *Fcross,
2481 INT4 *timeOffsetPoints,
2482 gsl_matrix *eigenvecs,
2483 gsl_vector *eigenvals,
2485 UINT4 position,
2486 UINT4 vecLength,
2487 UINT4 vecLengthTwo,
2488 UINT4 detectorNum)
2489{
2490 /* IMPORTANT!!! This function is probably the dominant computational cost
2491 * when running in lots-of-sky-points mode. Optimizing this is important! */
2492
2493 // This function calculates the coherent time series and rotates them into
2494 // the basis where the B matrix is the identity.
2495 // This is the dominant polarization frame with some normalization
2496
2497 UINT4 j,k;
2498 REAL4 v1[vecLengthTwo],v2[vecLengthTwo];
2499
2500 for ( j = 0; j < vecLengthTwo ; j++ ) /* Construct the vi vectors */
2501 {
2502 v1[j] = 0.;
2503 v2[j] = 0.;
2504 if (detectorNum == LAL_NUM_IFO)
2505 {
2506 for( k = 0; k < LAL_NUM_IFO; k++)
2507 {
2508 if ( params->haveTrig[k] )
2509 {
2510 if ( params->faceOnStatistic)
2511 {
2512 /* Currently non-spin only! */
2513 if (params->faceOnStatistic == 1)
2514 {
2515 v1[j] += Fplus[k] * crealf(PTFqVec[k]->data[j*numPoints+position+timeOffsetPoints[k]]);
2516 v1[j] += Fcross[k] * cimagf(PTFqVec[k]->data[j*numPoints+position+timeOffsetPoints[k]]);
2517 v2[j] += Fcross[k] * crealf(PTFqVec[k]->data[j*numPoints+position+timeOffsetPoints[k]]);
2518 v2[j] -= Fplus[k] * cimagf(PTFqVec[k]->data[j*numPoints+position+timeOffsetPoints[k]]);
2519 }
2520 else if (params->faceOnStatistic == 2)
2521 {
2522 v1[j] += Fplus[k] * crealf(PTFqVec[k]->data[j*numPoints+position+timeOffsetPoints[k]]);
2523 v1[j] -= Fcross[k] * cimagf(PTFqVec[k]->data[j*numPoints+position+timeOffsetPoints[k]]);
2524 v2[j] += Fcross[k] * crealf(PTFqVec[k]->data[j*numPoints+position+timeOffsetPoints[k]]);
2525 v2[j] += Fplus[k] * cimagf(PTFqVec[k]->data[j*numPoints+position+timeOffsetPoints[k]]);
2526 }
2527 else
2528 {
2529 fprintf(stderr,"Face-on stat is not working!");
2530 }
2531 }
2532 else if (j < vecLength)
2533 {
2534 v1[j] += Fplus[k] * crealf(PTFqVec[k]->data[j*numPoints+position+timeOffsetPoints[k]]);
2535 v2[j] += Fplus[k] * cimagf(PTFqVec[k]->data[j*numPoints+position+timeOffsetPoints[k]]);
2536 }
2537 else
2538 {
2539 v1[j] += Fcross[k] * crealf(PTFqVec[k]->data[(j-vecLength)*numPoints+position+timeOffsetPoints[k]]);
2540 v2[j] += Fcross[k] * cimagf(PTFqVec[k]->data[(j-vecLength)*numPoints+position+timeOffsetPoints[k]]);
2541 }
2542 }
2543 }
2544 }
2545 else
2546 {
2547 v1[j] += crealf(PTFqVec[detectorNum]->data[j*numPoints+position]);
2548 v2[j] += cimagf(PTFqVec[detectorNum]->data[j*numPoints+position]);
2549 }
2550 }
2551
2552 /* Now we rotate the v1 and v2 to be in orthogonal basis */
2553 /* We can use gsl multiplication stuff to do this */
2554 /* BLAS stuff is complicated so we'll do it explicitly! */
2555
2556 for ( j = 0 ; j < vecLengthTwo ; j++ )
2557 {
2558 u1[j] = 0.;
2559 u2[j] = 0.;
2560 for ( k = 0 ; k < vecLengthTwo ; k++ )
2561 {
2562 u1[j] += gsl_matrix_get(eigenvecs,k,j)*v1[k];
2563 u2[j] += gsl_matrix_get(eigenvecs,k,j)*v2[k];
2564 }
2565 u1[j] = u1[j] / (pow(gsl_vector_get(eigenvals,j),0.5));
2566 u2[j] = u2[j] / (pow(gsl_vector_get(eigenvals,j),0.5));
2567 }
2568
2569}
2570
2572 struct coh_PTF_params *params,
2573 REAL4TimeSeries *cohSNR,
2574 FindChirpTemplate *fcTmplt,
2575 InspiralTemplate PTFTemplate,
2576 UINT8 *eventId,
2577 UINT4 spinTrigger,
2578 REAL4TimeSeries **pValues,
2579 REAL4TimeSeries **gammaBeta,
2580 REAL4TimeSeries **snrComps,
2581 REAL4TimeSeries *nullSNR,
2582 REAL4TimeSeries *traceSNR,
2583 REAL4TimeSeries **bankVeto,
2584 REAL4TimeSeries **autoVeto,
2585 REAL4TimeSeries **chiSquare,
2586 REAL8Array **PTFM,
2587 REAL4 rightAscension,
2588 REAL4 declination,
2589 INT8 slideId,
2590 INT4 *timeOffsetPoints,
2591 UINT4 currPos
2592)
2593{
2594 LIGOTimeGPS trigTime;
2595 UINT4 numDOF = 4;
2596 if (params->singlePolFlag || params->faceOnStatistic || params->numIFO == 1)
2597 numDOF = 2;
2598
2599 MultiInspiralTable *currEvent;
2600 currEvent = (MultiInspiralTable *)
2601 LALCalloc(1, sizeof(MultiInspiralTable));
2602 currEvent->event_id=*eventId;
2603 currEvent->time_slide_id=slideId;
2604 (*eventId)++;
2605 trigTime = cohSNR->epoch;
2606 XLALGPSAdd(&trigTime,currPos*cohSNR->deltaT);
2607 currEvent->snr = cohSNR->data->data[currPos];
2608 currEvent->mass1 = PTFTemplate.mass1;
2609 currEvent->mass2 = PTFTemplate.mass2;
2610 currEvent->chi = PTFTemplate.chi;
2611 currEvent->kappa = PTFTemplate.kappa;
2612 currEvent->mchirp = PTFTemplate.totalMass*pow(PTFTemplate.eta,3.0/5.0);
2613 currEvent->eta = PTFTemplate.eta;
2614 /* FIXME: Add spins to MultiInspiralTable */
2615 currEvent->chi = PTFTemplate.spin1[2];
2616 currEvent->kappa = PTFTemplate.spin2[2];
2617 currEvent->end_time = trigTime;
2618 /* add sky position, but need to track back to sky fixed sky position */
2619 currEvent->ra = rightAscension -
2622 currEvent->dec = declination;
2623 if (params->doNullStream)
2624 currEvent->null_statistic = nullSNR->data->data[currPos];
2625 if (params->doTraceSNR)
2626 currEvent->trace_snr = traceSNR->data->data[currPos];
2627 if (params->doBankVeto)
2628 {
2629 if (params->numIFO != 1)
2630 {
2631 currEvent->bank_chisq = bankVeto[LAL_NUM_IFO]->data->data[currPos];
2632 currEvent->bank_chisq_dof = numDOF * params->BVsubBankSize;
2633 }
2634 if (params->doSnglChiSquared)
2635 {
2636 if (bankVeto[LAL_IFO_G1])
2637 {
2638 currEvent->bank_chisq_g = bankVeto[LAL_IFO_G1]->data->data[currPos];
2639 if (params->numIFO == 1)
2640 {
2641 currEvent->bank_chisq = bankVeto[LAL_IFO_G1]->data->data[currPos];
2642 currEvent->bank_chisq_dof = numDOF * params->BVsubBankSize;
2643 }
2644 }
2645 if (bankVeto[LAL_IFO_H1])
2646 {
2647 currEvent->bank_chisq_h1 = bankVeto[LAL_IFO_H1]->data->data[currPos];
2648 if (params->numIFO == 1)
2649 {
2650 currEvent->bank_chisq = bankVeto[LAL_IFO_H1]->data->data[currPos];
2651 currEvent->bank_chisq_dof = numDOF * params->BVsubBankSize;
2652 }
2653 }
2654 if (bankVeto[LAL_IFO_H2])
2655 {
2656 currEvent->bank_chisq_h2 = bankVeto[LAL_IFO_H2]->data->data[currPos];
2657 if (params->numIFO == 1)
2658 {
2659 currEvent->bank_chisq = bankVeto[LAL_IFO_H2]->data->data[currPos];
2660 currEvent->bank_chisq_dof = numDOF * params->BVsubBankSize;
2661 }
2662 }
2663 if (bankVeto[LAL_IFO_L1])
2664 {
2665 currEvent->bank_chisq_l = bankVeto[LAL_IFO_L1]->data->data[currPos];
2666 if (params->numIFO == 1)
2667 {
2668 currEvent->bank_chisq = bankVeto[LAL_IFO_L1]->data->data[currPos];
2669 currEvent->bank_chisq_dof = numDOF * params->BVsubBankSize;
2670 }
2671 }
2672 if (bankVeto[LAL_IFO_T1])
2673 {
2674 currEvent->bank_chisq_t = bankVeto[LAL_IFO_T1]->data->data[currPos];
2675 if (params->numIFO == 1)
2676 {
2677 currEvent->bank_chisq = bankVeto[LAL_IFO_T1]->data->data[currPos];
2678 currEvent->bank_chisq_dof = numDOF * params->BVsubBankSize;
2679 }
2680 }
2681 if (bankVeto[LAL_IFO_V1])
2682 {
2683 currEvent->bank_chisq_v = bankVeto[LAL_IFO_V1]->data->data[currPos];
2684 if (params->numIFO == 1)
2685 {
2686 currEvent->bank_chisq = bankVeto[LAL_IFO_V1]->data->data[currPos];
2687 currEvent->bank_chisq_dof = numDOF * params->BVsubBankSize;
2688 }
2689 }
2690 }
2691 }
2692 if (params->doAutoVeto)
2693 {
2694 if (params->numIFO != 1)
2695 {
2696 currEvent->cont_chisq = autoVeto[LAL_NUM_IFO]->data->data[currPos];
2697 currEvent->cont_chisq_dof = numDOF * params->numAutoPoints;
2698 }
2699 if (params->doSnglChiSquared)
2700 {
2701 if (autoVeto[LAL_IFO_G1])
2702 {
2703 currEvent->cont_chisq_g = autoVeto[LAL_IFO_G1]->data->data[currPos];
2704 if (params->numIFO == 1)
2705 {
2706 currEvent->cont_chisq = autoVeto[LAL_IFO_G1]->data->data[currPos];
2707 currEvent->cont_chisq_dof = numDOF * params->numAutoPoints;
2708 }
2709 }
2710 if (autoVeto[LAL_IFO_H1])
2711 {
2712 currEvent->cont_chisq_h1 = autoVeto[LAL_IFO_H1]->data->data[currPos];
2713 if (params->numIFO == 1)
2714 {
2715 currEvent->cont_chisq = autoVeto[LAL_IFO_H1]->data->data[currPos];
2716 currEvent->cont_chisq_dof = numDOF * params->numAutoPoints;
2717 }
2718 }
2719 if (autoVeto[LAL_IFO_H2])
2720 {
2721 currEvent->cont_chisq_h2 = autoVeto[LAL_IFO_H2]->data->data[currPos];
2722 if (params->numIFO == 1)
2723 {
2724 currEvent->cont_chisq = autoVeto[LAL_IFO_H2]->data->data[currPos];
2725 currEvent->cont_chisq_dof = numDOF * params->numAutoPoints;
2726 }
2727 }
2728 if (autoVeto[LAL_IFO_L1])
2729 {
2730 currEvent->cont_chisq_l = autoVeto[LAL_IFO_L1]->data->data[currPos];
2731 if (params->numIFO == 1)
2732 {
2733 currEvent->cont_chisq = autoVeto[LAL_IFO_L1]->data->data[currPos];
2734 currEvent->cont_chisq_dof = numDOF * params->numAutoPoints;
2735 }
2736 }
2737 if (autoVeto[LAL_IFO_T1])
2738 {
2739 currEvent->cont_chisq_t = autoVeto[LAL_IFO_T1]->data->data[currPos];
2740 if (params->numIFO == 1)
2741 {
2742 currEvent->cont_chisq = autoVeto[LAL_IFO_T1]->data->data[currPos];
2743 currEvent->cont_chisq_dof = numDOF * params->numAutoPoints;
2744 }
2745 }
2746 if (autoVeto[LAL_IFO_V1])
2747 {
2748 currEvent->cont_chisq_v = autoVeto[LAL_IFO_V1]->data->data[currPos];
2749 if (params->numIFO == 1)
2750 {
2751 currEvent->cont_chisq = autoVeto[LAL_IFO_V1]->data->data[currPos];
2752 currEvent->cont_chisq_dof = numDOF * params->numAutoPoints;
2753 }
2754 }
2755 }
2756 }
2757 if (params->doChiSquare)
2758 {
2759 if (params->numIFO != 1)
2760 {
2761 currEvent->chisq = chiSquare[LAL_NUM_IFO]->data->data[currPos];
2762 currEvent->chisq_dof = numDOF * (params->numChiSquareBins - 1);
2763 }
2764 if (params->doSnglChiSquared)
2765 {
2766 if (chiSquare[LAL_IFO_G1])
2767 {
2768 currEvent->chisq_g = chiSquare[LAL_IFO_G1]->data->data[currPos];
2769 if (params->numIFO == 1)
2770 {
2771 currEvent->chisq = chiSquare[LAL_IFO_G1]->data->data[currPos];
2772 currEvent->chisq_dof = numDOF * (params->numChiSquareBins - 1);
2773 }
2774 }
2775 if (chiSquare[LAL_IFO_H1])
2776 {
2777 currEvent->chisq_h1 = chiSquare[LAL_IFO_H1]->data->data[currPos];
2778 if (params->numIFO == 1)
2779 {
2780 currEvent->chisq = chiSquare[LAL_IFO_H1]->data->data[currPos];
2781 currEvent->chisq_dof = numDOF * (params->numChiSquareBins - 1);
2782 }
2783 }
2784 if (chiSquare[LAL_IFO_H2])
2785 {
2786 currEvent->chisq_h2 = chiSquare[LAL_IFO_H2]->data->data[currPos];
2787 if (params->numIFO == 1)
2788 {
2789 currEvent->chisq = chiSquare[LAL_IFO_H2]->data->data[currPos];
2790 currEvent->chisq_dof = numDOF * (params->numChiSquareBins - 1);
2791 }
2792 }
2793 if (chiSquare[LAL_IFO_L1])
2794 {
2795 currEvent->chisq_l = chiSquare[LAL_IFO_L1]->data->data[currPos];
2796 if (params->numIFO == 1)
2797 {
2798 currEvent->chisq = chiSquare[LAL_IFO_L1]->data->data[currPos];
2799 currEvent->chisq_dof = numDOF * (params->numChiSquareBins - 1);
2800 }
2801 }
2802 if (chiSquare[LAL_IFO_T1])
2803 {
2804 currEvent->chisq_t = chiSquare[LAL_IFO_T1]->data->data[currPos];
2805 if (params->numIFO == 1)
2806 {
2807 currEvent->chisq = chiSquare[LAL_IFO_T1]->data->data[currPos];
2808 currEvent->chisq_dof = numDOF * (params->numChiSquareBins - 1);
2809 }
2810 }
2811 if (chiSquare[LAL_IFO_V1])
2812 {
2813 currEvent->chisq_v = chiSquare[LAL_IFO_V1]->data->data[currPos];
2814 if (params->numIFO == 1)
2815 {
2816 currEvent->chisq = chiSquare[LAL_IFO_V1]->data->data[currPos];
2817 currEvent->chisq_dof = numDOF * (params->numChiSquareBins - 1);
2818 }
2819 }
2820 }
2821 }
2822
2823 REAL8 sigmasqCorrFac, invSigmaCorrFac;
2824 sigmasqCorrFac = ( (REAL8)fcTmplt->tmpltNorm);
2825 sigmasqCorrFac *= ( (REAL8)params->tempCorrFac);
2826 invSigmaCorrFac = 1. / pow(sigmasqCorrFac, 0.5);
2827
2828 if (pValues[0])
2829 currEvent->amp_term_1 = pValues[0]->data->data[currPos] * invSigmaCorrFac;
2830 if (pValues[1])
2831 currEvent->amp_term_2 = pValues[1]->data->data[currPos] * invSigmaCorrFac;
2832 if (pValues[2])
2833 currEvent->amp_term_3 = pValues[2]->data->data[currPos] * invSigmaCorrFac;
2834 if (pValues[3])
2835 currEvent->amp_term_4 = pValues[3]->data->data[currPos] * invSigmaCorrFac;
2836 /* If here, also populate distance and other parameters */
2837 currEvent->distance = ( currEvent->amp_term_1*currEvent->amp_term_1 + \
2838 currEvent->amp_term_2*currEvent->amp_term_2 + \
2839 currEvent->amp_term_3*currEvent->amp_term_3 + \
2840 currEvent->amp_term_4*currEvent->amp_term_4 );
2841 currEvent->distance = pow(2. / currEvent->distance, 0.5);
2842 if (pValues[4])
2843 currEvent->amp_term_5 = pValues[4]->data->data[currPos] * invSigmaCorrFac;
2844 if (pValues[5])
2845 currEvent->amp_term_6 = pValues[5]->data->data[currPos] * invSigmaCorrFac;
2846 if (pValues[6])
2847 currEvent->amp_term_7 = pValues[6]->data->data[currPos] * invSigmaCorrFac;
2848 if (pValues[7])
2849 currEvent->amp_term_8 = pValues[7]->data->data[currPos] * invSigmaCorrFac;
2850 if (pValues[8])
2851 currEvent->amp_term_9 = pValues[8]->data->data[currPos] * invSigmaCorrFac;
2852 if (pValues[9])
2853 currEvent->amp_term_10 = pValues[9]->data->data[currPos] * invSigmaCorrFac;
2854 /* Note that these two terms are only used for debugging
2855 * * at the moment. When they are used properly they will be
2856 * * moved into sane columns! For spin they give Amp*cos(Phi_0) and
2857 * * Amp*sin(Phi_0). For non spinning the second is 0 and the
2858 * * first is some arbitrary amplitude. */
2859 if (gammaBeta[0])
2860 {
2861 currEvent->g1quad = crectf( gammaBeta[0]->data->data[currPos], gammaBeta[1]->data->data[currPos] );
2862 }
2863
2864 if (snrComps[LAL_IFO_G1])
2865 {
2866 currEvent->snr_g = snrComps[LAL_IFO_G1]->data->
2867 data[currPos+params->numBufferPoints+timeOffsetPoints[LAL_IFO_G1]];
2868 currEvent->sigmasq_g = PTFM[LAL_IFO_G1]->data[0] * sigmasqCorrFac;
2869 }
2870 if (snrComps[LAL_IFO_H1])
2871 {
2872 currEvent->snr_h1 = snrComps[LAL_IFO_H1]->data->
2873 data[currPos+params->numBufferPoints+timeOffsetPoints[LAL_IFO_H1]];
2874 currEvent->sigmasq_h1 = PTFM[LAL_IFO_H1]->data[0] * sigmasqCorrFac;
2875 }
2876 if (snrComps[LAL_IFO_H2])
2877 {
2878 currEvent->snr_h2 = snrComps[LAL_IFO_H2]->data->
2879 data[currPos+params->numBufferPoints+timeOffsetPoints[LAL_IFO_H2]];
2880 currEvent->sigmasq_h2 = PTFM[LAL_IFO_H2]->data[0] * sigmasqCorrFac;
2881 }
2882 if (snrComps[LAL_IFO_L1])
2883 {
2884 currEvent->snr_l = snrComps[LAL_IFO_L1]->data->
2885 data[currPos+params->numBufferPoints+timeOffsetPoints[LAL_IFO_L1]];
2886 currEvent->sigmasq_l = PTFM[LAL_IFO_L1]->data[0] * sigmasqCorrFac;
2887 }
2888 if (snrComps[LAL_IFO_T1])
2889 {
2890 currEvent->snr_t = snrComps[LAL_IFO_T1]->data->
2891 data[currPos+params->numBufferPoints+timeOffsetPoints[LAL_IFO_T1]];
2892 currEvent->sigmasq_t = PTFM[LAL_IFO_T1]->data[0] * sigmasqCorrFac;
2893 }
2894 if (snrComps[LAL_IFO_V1])
2895 {
2896 currEvent->snr_v = snrComps[LAL_IFO_V1]->data->
2897 data[currPos+params->numBufferPoints+timeOffsetPoints[LAL_IFO_V1]];
2898 currEvent->sigmasq_v = PTFM[LAL_IFO_V1]->data[0] * sigmasqCorrFac;
2899 }
2900 if (spinTrigger == 1)
2901 {
2902 if (params->numIFO == 1)
2903 currEvent->snr_dof = 6;
2904 else
2905 currEvent->snr_dof = 12;
2906 }
2907 else
2908 {
2909 currEvent->snr_dof = numDOF;
2910 }
2911
2912 /* store ifos */
2913 if (params->numIFO == 1)
2914 {
2915 snprintf(currEvent->ifos, LIGOMETA_IFOS_MAX,\
2916 "%s", params->ifoName[0]);
2917 }
2918 else if(params->numIFO == 2)
2919 {
2920 XLALStringPrint(currEvent->ifos, LIGOMETA_IFOS_MAX, "%s%s",
2921 params->ifoName[0], params->ifoName[1]);
2922 }
2923 else if (params->numIFO == 3)
2924 {
2925 XLALStringPrint(currEvent->ifos, LIGOMETA_IFOS_MAX, "%s%s%s",
2926 params->ifoName[0], params->ifoName[1], params->ifoName[2]);
2927 }
2928 else if (params->numIFO == 4)
2929 {
2930 XLALStringPrint(currEvent->ifos, LIGOMETA_IFOS_MAX, "%s%s%s%s",
2931 params->ifoName[0], params->ifoName[1], params->ifoName[2],
2932 params->ifoName[3]);
2933 }
2934 if (params->faceOnStatistic == 2)
2935 {
2936 currEvent->inclination = LAL_PI/2.;
2937 }
2938
2939 return currEvent;
2940}
2941
2943 struct coh_PTF_params *params,
2944 SnglInspiralTable **eventList,
2945 SnglInspiralTable **thisEvent,
2946 REAL4TimeSeries *cohSNR,
2947 FindChirpTemplate *fcTmplt,
2948 InspiralTemplate PTFTemplate,
2949 UINT8 eventId,
2950 REAL4TimeSeries **pValues,
2951 REAL4TimeSeries **bankVeto,
2952 REAL4TimeSeries **autoVeto,
2953 REAL4TimeSeries **chiSquare,
2954 REAL8Array **PTFM,
2955 UINT4 startPoint,
2956 UINT4 endPoint
2957)
2958{
2959 /* This function adds SnglInspiral events to the event list */
2960
2961 UINT4 i;
2962 SnglInspiralTable *lastEvent = *thisEvent;
2963 SnglInspiralTable *currEvent = NULL;
2964
2965 for (i = startPoint ; i < endPoint ; i++)
2966 {
2967 if (cohSNR->data->data[i])
2968 {
2969 currEvent = coh_PTF_create_sngl_event(params,cohSNR,fcTmplt,PTFTemplate,\
2970 &eventId,pValues,bankVeto,autoVeto,chiSquare,PTFM,i);
2971
2972 /* Check trigger against trig times */
2973 if (coh_PTF_trig_time_check(params,currEvent->end,\
2974 currEvent->end))
2975 {
2977 continue;
2978 }
2979 /* And add the trigger to the lists. IF it passes clustering! */
2980 if (!*eventList)
2981 {
2982 *eventList = currEvent;
2983 lastEvent = currEvent;
2984 }
2985 else
2986 {
2987 if (! params->clusterFlag)
2988 {
2989 lastEvent->next = currEvent;
2990 lastEvent = currEvent;
2991 }
2992 else if (coh_PTF_accept_sngl_trig_check(params,eventList,*currEvent) )
2993 {
2994 lastEvent->next = currEvent;
2995 lastEvent = currEvent;
2996 }
2997 else
2998 {
3000 }
3001 }
3002 }
3003 }
3004 *thisEvent = lastEvent;
3005 return eventId;
3006}
3007
3009 struct coh_PTF_params *params,
3010 REAL4TimeSeries *cohSNR,
3011 FindChirpTemplate *fcTmplt,
3012 InspiralTemplate PTFTemplate,
3013 UINT8 *eventId,
3014 REAL4TimeSeries **pValues,
3015 REAL4TimeSeries **bankVeto,
3016 REAL4TimeSeries **autoVeto,
3017 REAL4TimeSeries **chiSquare,
3018 REAL8Array **PTFM,
3019 UINT4 currPos
3020)
3021{
3022 LIGOTimeGPS trigTime;
3023 UINT4 numDOF = 2;
3024 UINT4 ifoNumber;
3025 CHAR searchName[LIGOMETA_SEARCH_MAX];
3026
3027 SnglInspiralTable *thisEvent;
3028 thisEvent = (SnglInspiralTable *)
3029 LALCalloc(1, sizeof(SnglInspiralTable));
3030 thisEvent->event_id = (*eventId)++;
3031 /* Set end times */
3032 trigTime = cohSNR->epoch;
3033 XLALGPSAdd(&trigTime,currPos*cohSNR->deltaT);
3034 thisEvent->end = trigTime;
3036 &thisEvent->end), LAL_TWOPI) * 24.0 / LAL_TWOPI; /* hours */
3037
3038 /* Set SNR, chisqs, sigmasq, eff_distance */
3039 REAL8 sigmasqCorrFac;
3040 sigmasqCorrFac = ( (REAL8)fcTmplt->tmpltNorm);
3041 sigmasqCorrFac *= ( (REAL8)params->tempCorrFac);
3042
3043 thisEvent->snr = cohSNR->data->data[currPos];
3044 for( ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
3045 {
3046 if ( params->haveTrig[ifoNumber] )
3047 {
3048 thisEvent->chisq = chiSquare[ifoNumber]->data->data[currPos];
3049 thisEvent->bank_chisq = bankVeto[ifoNumber]->data->data[currPos];
3050 thisEvent->cont_chisq = autoVeto[ifoNumber]->data->data[currPos];
3051 thisEvent->sigmasq = PTFM[ifoNumber]->data[0] * sigmasqCorrFac;
3052 }
3053 }
3054 /* FIXME: Should be fixed so that this actually stores the DOF! */
3055 thisEvent->chisq_dof = params->numChiSquareBins;
3056 thisEvent->bank_chisq_dof = numDOF * params->BVsubBankSize;
3057 thisEvent->cont_chisq_dof = numDOF * params->numAutoPoints;
3058 thisEvent->eff_distance = sqrt( thisEvent->sigmasq ) / thisEvent->snr;
3059 /* FIXME: What is this? What is it used for? */
3060 thisEvent->event_duration = 0;
3061 /* FIXME: What does coa_phase actually mean here? */
3062 thisEvent->coa_phase = (REAL4)
3063 atan2( pValues[0]->data->data[currPos], pValues[1]->data->data[currPos]);
3064
3065 /* set the impulse time for the event FIXME:Check this! */
3066 thisEvent->template_duration = (REAL8) PTFTemplate.tC;
3067
3068 /* record the ifo name for the event */
3069 snprintf(thisEvent->ifo, LIGOMETA_IFO_MAX, "%s", params->ifoName[0]);
3070 /* Set the channel name */
3071 for( ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
3072 {
3073 if ( params->haveTrig[ifoNumber] )
3074 {
3075 strncpy( thisEvent->channel, (params->channel[ifoNumber]) + 3,
3076 (LALNameLength - 3) * sizeof(CHAR) );
3077 }
3078 }
3079 /* FIXME: NOt sure about this one either, inspiral just copies end_time */
3080 thisEvent->impulse_time = thisEvent->end;
3081
3082 /* copy the template into the event */
3083 thisEvent->mass1 = (REAL4) PTFTemplate.mass1;
3084 thisEvent->mass2 = (REAL4) PTFTemplate.mass2;
3085 thisEvent->mtotal = (REAL4) PTFTemplate.totalMass;
3086 thisEvent->mchirp = (REAL4) PTFTemplate.chirpMass;
3087 thisEvent->eta = (REAL4) PTFTemplate.eta;
3088 thisEvent->kappa = (REAL4) PTFTemplate.kappa;
3089 thisEvent->chi = (REAL4) PTFTemplate.chi;
3090 thisEvent->tau0 = (REAL4) PTFTemplate.t0;
3091 thisEvent->tau2 = (REAL4) PTFTemplate.t2;
3092 thisEvent->tau3 = (REAL4) PTFTemplate.t3;
3093 thisEvent->tau4 = (REAL4) PTFTemplate.t4;
3094 thisEvent->tau5 = (REAL4) PTFTemplate.t5;
3095 thisEvent->ttotal = (REAL4) PTFTemplate.tC;
3096 thisEvent->f_final = (REAL4) PTFTemplate.fFinal;
3097 thisEvent->spin1z = (REAL4) PTFTemplate.spin1[2];
3098 thisEvent->spin2z = (REAL4) PTFTemplate.spin2[2];
3099
3100 /* We can now memcpy the 10 metric co-efficients */
3101 memcpy (thisEvent->Gamma, PTFTemplate.Gamma, 10*sizeof(REAL4));
3102
3103 /* Store the approximant */
3105 params->approximant, params->order );
3106 memcpy( thisEvent->search, searchName,
3107 LIGOMETA_SEARCH_MAX * sizeof(CHAR) );
3108
3109 return thisEvent;
3110}
3111
3113 struct coh_PTF_params *params,
3114 SnglInspiralTable **eventList,
3115 SnglInspiralTable thisEvent
3116)
3117{
3118 SnglInspiralTable *currEvent = *eventList;
3119 LIGOTimeGPS time1,time2;
3120 UINT4 loudTrigBefore=0,loudTrigAfter=0;
3121
3122 currEvent = *eventList;
3123
3124 /* for each trigger, find out whether a louder trigger is within the
3125 * * clustering time */
3126 time1.gpsSeconds=thisEvent.end.gpsSeconds;
3127 time1.gpsNanoSeconds = thisEvent.end.gpsNanoSeconds;
3128 while (currEvent)
3129 {
3130 time2.gpsSeconds=currEvent->end.gpsSeconds;
3131 time2.gpsNanoSeconds=currEvent->end.gpsNanoSeconds;
3132 if (fabs(XLALGPSDiff(&time1,&time2)) < params->clusterWindow)
3133 {
3134 if (thisEvent.snr < currEvent->snr\
3135 && (thisEvent.event_id != currEvent->event_id))
3136 {
3137 if ( XLALGPSDiff(&time1,&time2) < 0 )
3138 loudTrigBefore = 1;
3139 else
3140 loudTrigAfter = 1;
3141 if (loudTrigBefore && loudTrigAfter)
3142 {
3143 return 0;
3144 }
3145 }
3146 }
3147 currEvent = currEvent->next;
3148 }
3149
3150 return 1;
3151}
3152
3154 struct coh_PTF_params *params,
3155 SnglInspiralTable **eventList,
3156 SnglInspiralTable **thisEvent
3157)
3158{
3159
3160 SnglInspiralTable *currEvent = *eventList;
3161 SnglInspiralTable *currEvent2 = NULL;
3162 SnglInspiralTable *newEvent = NULL;
3163 SnglInspiralTable *newEventHead = NULL;
3164 UINT4 triggerNum = 0;
3165 UINT4 lenTriggers = 0;
3166
3167 /* find number of triggers */
3168 while (currEvent)
3169 {
3170 lenTriggers+=1;
3171 currEvent = currEvent->next;
3172 }
3173
3174 currEvent = *eventList;
3175 UINT4 rejectTriggers[lenTriggers];
3176
3177 /* for each trigger, find out whether a louder trigger is within the
3178 * * clustering time */
3179 while (currEvent)
3180 {
3181 if (coh_PTF_accept_sngl_trig_check(params,eventList,*currEvent) )
3182 {
3183 rejectTriggers[triggerNum] = 0;
3184 triggerNum += 1;
3185 }
3186 else
3187 {
3188 rejectTriggers[triggerNum] = 1;
3189 triggerNum += 1;
3190 }
3191 currEvent = currEvent->next;
3192 }
3193
3194 currEvent = *eventList;
3195 triggerNum = 0;
3196
3197 /* construct new event table with triggers to keep */
3198 while (currEvent)
3199 {
3200 if (! rejectTriggers[triggerNum])
3201 {
3202 if (! newEventHead)
3203 {
3204 newEventHead = currEvent;
3205 newEvent = currEvent;
3206 }
3207 else
3208 {
3209 newEvent->next = currEvent;
3210 newEvent = currEvent;
3211 }
3212 currEvent = currEvent->next;
3213 }
3214 else
3215 {
3216 currEvent2 = currEvent->next;
3218 currEvent = currEvent2;
3219 }
3220 triggerNum+=1;
3221 }
3222
3223 /* write new table over old one */
3224 if (newEvent)
3225 {
3226 newEvent->next = NULL;
3227 *eventList = newEventHead;
3228 *thisEvent = newEvent;
3229 }
3230}
3231
3233 struct coh_PTF_params *params,
3234 ProcessParamsTable *procpar,
3235 REAL4FFTPlan *fwdplan,
3236 REAL4FFTPlan *psdplan,
3237 REAL4FFTPlan *revplan,
3238 COMPLEX8FFTPlan *invPlan,
3239 REAL4TimeSeries **channel,
3240 REAL4FrequencySeries **invspec,
3241 RingDataSegments **segments,
3242 MultiInspiralTable *events,
3243 SnglInspiralTable *snglEvents,
3244 InspiralTemplate *PTFbankhead,
3245 FindChirpTemplate *fcTmplt,
3246 FindChirpTmpltParams *fcTmpltParams,
3247 REAL8Array **PTFM,
3248 REAL8Array **PTFN,
3249 COMPLEX8VectorSequence **PTFqVec,
3250 REAL4 *timeOffsets,
3251 REAL4 *slidTimeOffsets,
3252 REAL4 *Fplus,
3253 REAL4 *Fcross,
3254 REAL4 *Fplustrig,
3255 REAL4 *Fcrosstrig,
3257 TimeSlide *time_slide_head,
3258 TimeSlideVectorList *longTimeSlideList,
3259 TimeSlideVectorList *shortTimeSlideList,
3260 REAL4 *timeSlideVectors,
3261 LALDetector **detectors,
3262 INT8 *slideIDList,
3263 TimeSlideSegmentMapTable *time_slide_map_head,
3264 SegmentTable *segment_table_head
3265)
3266{
3267 if ( params->injectList )
3268 {
3269 SimInspiralTable *injectList = params->injectList;
3270 SimInspiralTable *thisInject = NULL;
3271 while (injectList)
3272 {
3273 thisInject = injectList;
3274 injectList = injectList->next;
3275 LALFree(thisInject);
3276 }
3277 }
3278
3279 /* Clean up memory usage */
3280 UINT4 ifoNumber;
3281 while ( events )
3282 {
3283 MultiInspiralTable *thisEvent;
3284 thisEvent = events;
3285 events = events->next;
3286 LALFree( thisEvent );
3287 }
3288 while ( snglEvents )
3289 {
3290 SnglInspiralTable *thisSnglEvent;
3291 thisSnglEvent = snglEvents;
3292 snglEvents = snglEvents->next;
3293 XLALDestroySnglInspiralTableRow( thisSnglEvent );
3294 }
3295
3296 while ( PTFbankhead )
3297 {
3298 InspiralTemplate *thisTmplt;
3299 thisTmplt = PTFbankhead;
3300 PTFbankhead = PTFbankhead->next;
3301 LALFree( thisTmplt );
3302 }
3303 UINT4 sgmnt;
3304 for( ifoNumber = 0; ifoNumber < (LAL_NUM_IFO+1); ifoNumber++)
3305 {
3306 if ( segments[ifoNumber] )
3307 {
3308 for ( sgmnt = 0; sgmnt < segments[ifoNumber]->numSgmnt; sgmnt++ )
3309 {
3310 if (segments[ifoNumber]->sgmnt[sgmnt].data)
3311 XLALDestroyCOMPLEX8Vector(segments[ifoNumber]->sgmnt[sgmnt].data);
3312 }
3313 LALFree( segments[ifoNumber]->sgmnt );
3314 LALFree( segments[ifoNumber] );
3315 }
3316 if ( invspec[ifoNumber] )
3317 {
3318 XLALDestroyREAL4Vector( invspec[ifoNumber]->data );
3319 LALFree( invspec[ifoNumber] );
3320 }
3321 if ( channel[ifoNumber] )
3322 {
3323 XLALDestroyREAL4Vector( channel[ifoNumber]->data );
3324 LALFree( channel[ifoNumber] );
3325 }
3326 if ( PTFM[ifoNumber] )
3327 XLALDestroyREAL8Array( PTFM[ifoNumber] );
3328 if ( PTFN[ifoNumber] )
3329 XLALDestroyREAL8Array( PTFN[ifoNumber] );
3330 if ( PTFqVec[ifoNumber] )
3331 XLALDestroyCOMPLEX8VectorSequence( PTFqVec[ifoNumber] );
3332 }
3333 if ( revplan )
3334 XLALDestroyREAL4FFTPlan( revplan );
3335 if ( fwdplan )
3336 XLALDestroyREAL4FFTPlan( fwdplan );
3337 if ( psdplan )
3338 XLALDestroyREAL4FFTPlan( psdplan );
3339 if ( invPlan )
3340 XLALDestroyCOMPLEX8FFTPlan( invPlan );
3341 while ( procpar )
3342 {
3343 ProcessParamsTable *thisParam;
3344 thisParam = procpar;
3345 procpar = procpar->next;
3346 LALFree( thisParam );
3347 }
3348 if (fcTmpltParams)
3349 {
3350 if ( fcTmpltParams->PTFe1 )
3351 XLALDestroyVectorSequence( fcTmpltParams->PTFe1 );
3352 if ( fcTmpltParams->PTFe2 )
3353 XLALDestroyVectorSequence( fcTmpltParams->PTFe2 );
3354 if ( fcTmpltParams->PTFphi )
3355 XLALDestroyVector( fcTmpltParams->PTFphi );
3356 if ( fcTmpltParams->PTFomega_2_3 )
3357 XLALDestroyVector( fcTmpltParams->PTFomega_2_3 );
3358 if ( fcTmpltParams->xfacVec )
3359 XLALDestroyVector( fcTmpltParams->xfacVec );
3360 LALFree( fcTmpltParams );
3361 }
3362 if ( fcTmplt )
3363 {
3364 if ( fcTmplt->PTFQ )
3365 XLALDestroyVectorSequence( fcTmplt->PTFQ );
3366 if ( fcTmplt->PTFQtilde )
3368 if ( fcTmplt->data )
3369 XLALDestroyCOMPLEX8Vector( fcTmplt->data );
3370 LALFree( fcTmplt );
3371 }
3372 if ( timeOffsets )
3373 LALFree( timeOffsets );
3374 if ( slidTimeOffsets)
3375 LALFree( slidTimeOffsets );
3376 if ( Fplus )
3377 LALFree( Fplus );
3378 if ( Fcross )
3379 LALFree( Fcross );
3380 if ( Fplustrig )
3381 LALFree( Fplustrig );
3382 if ( Fcrosstrig )
3383 LALFree( Fcrosstrig );
3384
3385 if (skyPoints)
3386 {
3387 if (skyPoints->data)
3388 LALFree(skyPoints->data);
3390 }
3391 if (time_slide_head)
3392 XLALDestroyTimeSlideTable(time_slide_head);
3393 if (time_slide_map_head)
3394 XLALDestroyTimeSlideSegmentMapTable(time_slide_map_head);
3395 if (segment_table_head)
3396 XLALDestroySegmentTable(segment_table_head);
3397 if (longTimeSlideList)
3398 LALFree(longTimeSlideList);
3399 if (shortTimeSlideList)
3400 LALFree(shortTimeSlideList);
3401 if (timeSlideVectors)
3402 LALFree(timeSlideVectors);
3403
3404 for(ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
3405 {
3406 if (detectors[ifoNumber])
3407 LALFree(detectors[ifoNumber]);
3408 }
3409
3410 if (slideIDList)
3411 LALFree(slideIDList);
3412
3413}
3414
3415
3416/* gets the forward fft plan */
3418{
3419 REAL4FFTPlan *plan = NULL;
3420 if ( params->segmentDuration > 0.0 )
3421 {
3422 UINT4 segmentLength;
3423 segmentLength = params->numTimePoints;
3424 plan = XLALCreateForwardREAL4FFTPlan( segmentLength, params->fftLevel );
3425 }
3426 return plan;
3427}
3428
3429/* gets the psd forward fft plan */
3431{
3432 REAL4FFTPlan *plan = NULL;
3433 if ( params->psdSegmentDuration > 0.0 )
3434 {
3435 UINT4 segmentLength;
3436 segmentLength = floor( params->psdSegmentDuration * params->sampleRate
3437 + 0.5 );
3438 plan = XLALCreateForwardREAL4FFTPlan( segmentLength, params->fftLevel );
3439 }
3440 return plan;
3441}
3442
3443/* gets the reverse fft plan */
3445{
3446 REAL4FFTPlan *plan = NULL;
3447 if ( params->segmentDuration > 0.0 )
3448 {
3449 UINT4 segmentLength;
3450 segmentLength = params->numTimePoints;
3451 plan = XLALCreateReverseREAL4FFTPlan( segmentLength, params->fftLevel );
3452 }
3453 return plan;
3454}
3455
3456/* gets the inverse fft plan */
3458{
3459 COMPLEX8FFTPlan *plan = NULL;
3460 if ( params->segmentDuration > 0.0 )
3461 {
3462 UINT4 segmentLength;
3463 segmentLength = params->numTimePoints;
3464 plan = XLALCreateReverseCOMPLEX8FFTPlan( segmentLength, params->fftLevel );
3465 }
3466 return plan;
3467}
3468
3469
3470/* routine to see if integer i is in a list of integers to do */
3471/* e.g., 2, 7, and 222 are in the list "1-3,5,7-" but 4 is not */
3472int is_in_list( int i, const char *list )
3473{
3474 char buffer[BUFFER_SIZE];
3475 char *str = buffer;
3476 int ans = 0;
3477
3478 strncpy( buffer, list, sizeof( buffer ) - 1 );
3479
3480 while ( str )
3481 {
3482 char *tok; /* token in a delimited list */
3483 char *tok2; /* second part of token if it is a range */
3484 tok = str;
3485
3486 if ( ( str = strchr( str, ',' ) ) ) /* look for next delimiter */
3487 *str++ = 0; /* nul terminate current token; str is remaining string */
3488
3489 /* now see if this token is a range */
3490 if ( ( tok2 = strchr( tok, '-' ) ) )
3491 *tok2++ = 0; /* nul terminate first part of token; tok2 is second part */
3492 if ( tok2 ) /* range */
3493 {
3494 int n1, n2;
3495 if ( strcmp( tok, "^" ) == 0 )
3496 n1 = INT_MIN;
3497 else
3498 n1 = atoi( tok );
3499 if ( strcmp( tok2, "$" ) == 0 )
3500 n2 = INT_MAX;
3501 else
3502 n2 = atoi( tok2 );
3503 if ( i >= n1 && i <= n2 ) /* see if i is in the range */
3504 ans = 1;
3505 }
3506 else if ( i == atoi( tok ) )
3507 ans = 1;
3508
3509 if ( ans ) /* i is in the list */
3510 break;
3511 }
3512
3513 return ans;
3514}
3515
3517 InspiralTemplate *template,
3518 UINT4 eventNumber
3519 )
3520{
3521 SnglInspiralTable *cnvTemplate;
3522 cnvTemplate = (SnglInspiralTable *) LALCalloc(1,sizeof(SnglInspiralTable));
3523 cnvTemplate->event_id = eventNumber;
3524 cnvTemplate->mass1 = template->mass1;
3525 cnvTemplate->mass2 = template->mass2;
3526 cnvTemplate->chi = template->chi;
3527 cnvTemplate->kappa = template->kappa;
3528 cnvTemplate->f_final = template->fCutoff;
3529 return cnvTemplate;
3530}
3531
3532/*
3533 *
3534 * construct CohPTFSkyPositions structures for the different sky patching cases:
3535 *
3536 * if all sky:
3537 * FAIL - not implemented yet
3538 * if two-detectors with patch:
3539 * generate an arc of points perpendicular to the line of constant time-delay
3540 * if multiple-detector patch or single point:
3541 * generate a grid of concentric circles around trigger point
3542 *
3543 */
3544
3546 struct coh_PTF_params *params
3547 )
3548{
3549
3551
3552 /* if given file */
3553 if ( params->skyPositionsFile != NULL )
3554 {
3555 UINT4 raColumn = 0;
3556 UINT4 decColumn = 1;
3557 skyPoints = coh_PTF_read_grid_from_file(params->skyPositionsFile,\
3558 raColumn, decColumn);
3559 }
3560
3561 /* if all sky */
3562 else if (params->skyLooping == TWO_DET_ALL_SKY)
3563 {
3564 verbose("Generating 2 detector all sky map...\n");
3566 }
3567
3568 else if ((params->skyLooping == ALL_SKY) && (params->numIFO==3))
3569 {
3570 verbose("Generating 3 detector all sky map...\n");
3572 //error("all sky mode is not implemented yet, however, you can use --sky-positions-file\n");
3573
3574 //skyPoints = coh_PTF_sky_grid()
3575 }
3576
3577 else if (params->skyLooping == ALL_SKY)
3578 {
3579 error("all sky mode is not implemented yet, however, you can use --sky-positions-file\n");
3580 }
3581
3582 /* if sky region */
3583 else if ( params->skyLooping == SKY_PATCH\
3584 || params->skyLooping == TWO_DET_SKY_PATCH\
3585 || params->skyLooping == SINGLE_SKY_POINT )
3586 {
3588 }
3589
3590 /* if two-detectors, remove time-delay degeneracy */
3591 if (params->skyLooping == TWO_DET_SKY_PATCH)
3592 {
3593 verbose("Generated full sky grid with %d points, ",
3594 skyPoints->numPoints);
3595 verbose("parsing for time-delay degeneracy\n");
3596 CohPTFSkyPositions *parsedSkyPoints = NULL;
3597 parsedSkyPoints = coh_PTF_parse_time_delays(skyPoints, params);
3598 if (skyPoints->data)
3599 LALFree(skyPoints->data);
3600 if (skyPoints)
3602 skyPoints = parsedSkyPoints;
3603 }
3604 verbose("Generated final sky grid with %d points, ",
3605 skyPoints->numPoints);
3606 return skyPoints;
3607}
3608
3609/*
3610 * Generate a grid of sky points based on the sinusoidal map method used by
3611 * the xpipeline.
3612 */
3613
3615 struct coh_PTF_params *params
3616 )
3617{
3619 UINT4 ifoNumber,i,j;
3621 REAL4 angle; /* angle between IFO baseline & sky localisation */
3622 REAL4 lambdamin,lambdamax,lambda; /* angle closest to pi/2 */
3623 REAL4 alpha=0,detalpha;
3624 REAL4 angularResolution;
3625 double baseline,lightTravelTime;
3626 REAL4 raNp = 0.; /* north */
3627 REAL4 decNp = LAL_PI_2; /* pole */
3628
3629 gsl_vector *axis; /* rotation axis vector */
3630 gsl_vector *npPos; /* north pole position */
3631 gsl_vector *trigPos; /* trigger position */
3632
3633 /* get site coordinates */
3634 for(ifoNumber=0; ifoNumber<LAL_NUM_IFO; ifoNumber++)
3635 {
3636 detectors[ifoNumber] = LALCalloc(1, sizeof(*detectors[ifoNumber]));
3637 XLALReturnDetector(detectors[ifoNumber], ifoNumber);
3638 }
3639
3640 /* find pair of detectors whose opening angle to the GRB ±error is closest */
3641 /* to 90 degrees */
3642 for (i=0; i<LAL_NUM_IFO; i++)
3643 {
3644 if (params->haveTrig[i])
3645 {
3646 for (j=i+1; j<LAL_NUM_IFO; j++)
3647 {
3648 if (params->haveTrig[j])
3649 {
3650 /* get dot product (time delay) between sites */
3651 baseline = XLALArrivalTimeDiff(detectors[i]->location,
3652 detectors[j]->location,
3653 params->rightAscension,
3654 params->declination,
3655 &params->trigTime);
3656
3657 /* get light travel time */
3658 lightTravelTime = XLALLightTravelTime(detectors[i], detectors[j]);
3659 lightTravelTime *= 1e-9;
3660
3661 /* calculate opening angle */
3662 angle = acos(baseline/lightTravelTime);
3663
3664 /* generate angular window with sky error */
3665 lambdamin = angle-params->skyError;
3666 lambdamax = angle+params->skyError;
3667
3668 /* if pi/2 is in the range, choose that,
3669 * otherwise get as close as possible */
3670 if (lambdamin < LAL_PI_2 && lambdamax > LAL_PI_2)
3671 {
3672 lambda = LAL_PI_2;
3673 }
3674 else
3675 if (fabs(LAL_PI_2-lambdamin) < fabs(LAL_PI_2-lambdamax))
3676 lambda = lambdamin;
3677 else
3678 lambda = lambdamax;
3679
3680 /* calculate alpha */
3681 detalpha = lightTravelTime * sin(lambda);
3682 if (detalpha > alpha)
3683 alpha = detalpha;
3684
3685 }
3686 }
3687 }
3688 }
3689
3690 /* calculate angular resolution */
3691 if ((! params->singlePolFlag) && (params->numIFO != 1))
3692 {
3693 angularResolution = 2. * params->timingAccuracy / alpha;
3694 }
3695 else
3696 {
3697 angularResolution = 1;
3698 params->skyError = 0;
3699 }
3700
3701 /* generate sky grid using sinusoidal map */
3702 skyPoints = coh_PTF_circular_grid(angularResolution, params->skyError);
3703
3704 /*
3705 * Rotate sky grid to centre on the given (ra,dec)
3706 */
3707
3708 /* calculate angle between north pole and (ra,dec) */
3709 raNp = 0.;
3710 decNp = LAL_PI_2;
3711
3712 angle = acos ( sin(decNp)*sin(params->declination) +
3713 cos(decNp)*cos(params->declination) *
3714 cos( raNp-params->rightAscension ) );
3715
3716 /* calculate unit vector to rotate around */
3717 npPos = gsl_vector_alloc(3);
3718 trigPos = gsl_vector_alloc(3);
3719 axis = gsl_vector_alloc(3);
3720
3721 gsl_vector_set(npPos, 0, 0.);
3722 gsl_vector_set(npPos, 1, 0.);
3723 gsl_vector_set(npPos, 2, 1.);
3724
3725 gsl_vector_set(trigPos, 0,\
3726 cos(params->declination)*cos(params->rightAscension));
3727 gsl_vector_set(trigPos, 1,\
3728 cos(params->declination)*sin(params->rightAscension));
3729 gsl_vector_set(trigPos, 2, sin(params->declination));
3730
3731 cross_product(axis, npPos, trigPos);
3732 normalise(axis);
3733
3734 /* rotate sky points */
3736
3737 /* free memory */
3738 for( ifoNumber = 0; ifoNumber < LAL_NUM_IFO; ifoNumber++)
3739 {
3740 if ( detectors[ifoNumber] )
3741 LALFree(detectors[ifoNumber]);
3742 }
3743 gsl_vector_free(npPos);
3744 gsl_vector_free(trigPos);
3745 gsl_vector_free(axis);
3746
3747 return skyPoints;
3748
3749}
3750
3751/*
3752 * generate circular map of sky points centred on north pole:
3753 * * place central point
3754 * * step out in declination by angularResolution
3755 * * place a ring of points separated by angularResolution
3756 * * repeat until maximum skyError radius passed
3757 */
3758
3760 REAL4 angularResolution,
3761 REAL4 skyError
3762 )
3763{
3764
3765 UINT4 p = 0;
3766 UINT4 i,j;
3767 UINT4 numTheta; /* number of rings */
3768 REAL4 dPhi,phi,theta; /* sky point parameters */
3769 UINT4 numSkyPoints = 0; /* total number of sky points */
3771
3772 /* set range of theta */
3773 numTheta = (int) ceil( skyError / angularResolution ) + 1;
3774
3775 /* set number of sky points */
3776 UINT4 numPhi[numTheta];
3777 for ( i=0; i < numTheta; i++ )
3778 {
3779 theta = angularResolution * i;
3780 numPhi[i] = (int) ceil( LAL_TWOPI * sin(theta) / angularResolution );
3781 if ( numPhi[i] < 1 )
3782 numPhi[i] = 1;
3783 numSkyPoints += numPhi[i];
3784 }
3785
3786 /* assign memory for sky points */
3787 skyPoints = LALCalloc(1, sizeof(*skyPoints));
3788 skyPoints->numPoints = numSkyPoints;
3789 skyPoints->data = LALCalloc(1, numSkyPoints*sizeof(SkyPosition));
3790
3791 /* loop over rings on sky, and around each ring */
3792 for ( i=0; i < numTheta; i++ )
3793 {
3794 dPhi = LAL_TWOPI / numPhi[i];
3795 theta = angularResolution * i;
3796 for ( j=0; j < numPhi[i]; j++ )
3797 {
3798 /* calculate phi */
3799 phi = ( -LAL_PI + dPhi / 2. ) + dPhi * j;
3800 /* assign sky point */
3801 skyPoints->data[p].longitude = phi;
3802 skyPoints->data[p].latitude = LAL_PI_2 - theta;
3803 skyPoints->data[p].system = COORDINATESYSTEM_EQUATORIAL;
3804 XLALNormalizeSkyPosition(&skyPoints->data[p].longitude, &skyPoints->data[p].latitude);
3805
3806 p++;
3807 }
3808
3809 }
3810
3811 return skyPoints;
3812
3813}
3814
3817 struct coh_PTF_params *params
3818)
3819{
3820
3821 CohPTFSkyPositions *parsedSkyPoints;
3822 UINT4 numSkyPoints = 0;
3823 UINT4 i, p, ifoNumber, appendPoint[skyPoints->numPoints];
3824 REAL8 timeDelay, timeDelays[skyPoints->numPoints];
3825 LALDetector *detectors[params->numIFO];
3826 REAL8 dt = params->timingAccuracy;
3827
3828 /* get site coordinates */
3829 i=0;
3830 for(ifoNumber=0; ifoNumber<LAL_NUM_IFO; ifoNumber++)
3831 {
3832 if (params->haveTrig[ifoNumber])
3833 {
3834 detectors[i] = LALCalloc(1, sizeof(*detectors[i]));
3835 XLALReturnDetector(detectors[i], ifoNumber);
3836 i++;
3837 }
3838 }
3839
3840 for (p = 0; p < skyPoints->numPoints; p++)
3841 {
3842
3843 /* set default timeDelay to zero */
3844 timeDelays[p] = 0;
3845 /* set default stance to keep point */
3846 appendPoint[p] = 0;
3847 timeDelay = XLALArrivalTimeDiff(detectors[0]->location,
3848 detectors[1]->location,
3849 skyPoints->data[p].longitude,
3850 skyPoints->data[p].latitude,
3851 &params->trigTime);
3852
3853 /* loop over timeDelays list */
3854 for (i = 0; i < p; i++)
3855 {
3856 /* if we haven't assigned this timeDelay, move on */
3857 if (timeDelays[i]==0)
3858 {
3859 continue;
3860 }
3861
3862 /* if we already have a timeDelay within the timing accuracy,
3863 * we don't want another one */
3864 if (fabs(timeDelay-timeDelays[i]) < dt)
3865 {
3866 appendPoint[p] = 1;
3867 break;
3868 }
3869 }
3870
3871 /* if we want to keep this point, save the time delay and increment the
3872 * counter */
3873 if (appendPoint[p] == 0)
3874 {
3875 numSkyPoints++;
3876 timeDelays[p] = timeDelay;
3877 }
3878 }
3879
3880 /* assign memory for sky points */
3881 parsedSkyPoints = LALCalloc(1, sizeof(*parsedSkyPoints));
3882 parsedSkyPoints->numPoints = numSkyPoints;
3883 parsedSkyPoints->data =
3884 LALCalloc(1, numSkyPoints*sizeof(*parsedSkyPoints->data));
3885
3886 /* save the new list of points */
3887 i = 0;
3888 for (p = 0; p < skyPoints->numPoints; p++)
3889 {
3890 if (appendPoint[p] == 0)
3891 {
3892 parsedSkyPoints->data[i] = skyPoints->data[p];
3893 i++;
3894 }
3895 }
3896
3897 /* free memory */
3898 for(ifoNumber = 0; ifoNumber < params->numIFO; ifoNumber++)
3899 {
3900 if (detectors[ifoNumber])
3901 LALFree(detectors[ifoNumber]);
3902 }
3903
3904 return parsedSkyPoints;
3905}
3906
3907long int timeval_subtract(struct timeval *t1)
3908{
3909 struct timeval t2;
3910 gettimeofday(&t2,NULL);
3911 long int diff = (t2.tv_usec + 1000000 * t2.tv_sec) - (t1->tv_usec + 1000000 * t1->tv_sec);
3912
3913 return diff;
3914}
3915
3916void timeval_print(struct timeval *tv)
3917{
3918 char buffer[30];
3919 time_t curtime;
3920
3921 printf("%lu.%06lu", (unsigned long)tv->tv_sec, (unsigned long)tv->tv_usec);
3922 curtime = tv->tv_sec;
3923 strftime(buffer, 30, "%m-%d-%Y %T", localtime(&curtime));
3924 printf(" = %s.%06lu\n", buffer, (unsigned long)tv->tv_usec);
3925}
3926
3927/*
3928 *
3929 * rotate a vector about a given angle in three dimensions
3930 *
3931 */
3932
3935 gsl_vector *axis,
3936 REAL8 angle
3937)
3938{
3939 /* initialise variables */
3940 UINT4 i;
3941 gsl_matrix *matrix;
3942 matrix = gsl_matrix_alloc(3, 3);
3943
3944 /* construct rotation matrix */
3945 rotation_matrix(matrix, axis, angle);
3946
3947 /* loop over points rotating by angle around axis */
3948 for ( i=0; i < skyPoints->numPoints; i++ )
3949 {
3950 coh_PTF_rotate_SkyPosition(&skyPoints->data[i], matrix);
3951 }
3952}
3953
3955 SkyPosition *skyPoint,
3956 gsl_matrix *matrix
3957)
3958{
3959 /* initialise variables */
3960 REAL4 phi,theta;
3961 gsl_vector *pos; /* original position vector */
3962 gsl_vector *rotPos; /* rotated position vector */
3963
3964
3965 phi = skyPoint->longitude;
3966 theta = LAL_PI_2 - skyPoint->latitude;
3967 /* convert to cartesian */
3968 pos = gsl_vector_alloc(3);
3969 gsl_vector_set(pos, 0, sin(theta)*cos(phi));
3970 gsl_vector_set(pos, 1, sin(theta)*sin(phi));
3971 gsl_vector_set(pos, 2, cos(theta));
3972
3973 /* rotate */
3974 rotPos = gsl_vector_alloc(3);
3975 gsl_blas_dgemv(CblasNoTrans, 1.0, matrix, pos, 0.0, rotPos);
3976
3977 /* convert back to (phi,theta) */
3978 theta = acos(gsl_vector_get(rotPos, 2));
3979 phi = atan2(gsl_vector_get(rotPos, 1), gsl_vector_get(rotPos, 0));
3980 //verbose("theta2 = %e, phi2 = %e\n", theta, phi);
3981 skyPoint->longitude = phi;
3982 skyPoint->latitude = LAL_PI_2 - theta;
3983 XLALNormalizeSkyPosition(&skyPoint->longitude, &skyPoint->latitude);
3984
3985 /* free memory */
3986 gsl_vector_free(pos);
3987 gsl_vector_free(rotPos);
3988}
3989
3991 gsl_vector *product,
3992 const gsl_vector *u,
3993 const gsl_vector *v
3994)
3995{
3996 double p1 = gsl_vector_get(u, 1)*gsl_vector_get(v, 2)
3997 - gsl_vector_get(u, 2)*gsl_vector_get(v, 1);
3998
3999 double p2 = gsl_vector_get(u, 2)*gsl_vector_get(v, 0)
4000 - gsl_vector_get(u, 0)*gsl_vector_get(v, 2);
4001
4002 double p3 = gsl_vector_get(u, 0)*gsl_vector_get(v, 1)
4003 - gsl_vector_get(u, 1)*gsl_vector_get(v, 0);
4004
4005 gsl_vector_set(product, 0, p1);
4006 gsl_vector_set(product, 1, p2);
4007 gsl_vector_set(product, 2, p3);
4008}
4009
4011 gsl_vector *vec
4012)
4013{
4014 double mag;
4015 /* calculate magnitude of vector */
4016 gsl_blas_ddot(vec, vec, &mag);
4017 mag = sqrt(mag);
4018 /* scale vector by inverse magnitude */
4019 gsl_vector_scale(vec, 1./mag);
4020}
4021
4023 gsl_matrix *matrix,
4024 gsl_vector *axis,
4025 REAL8 angle
4026)
4027{
4028
4029 gsl_matrix_set(matrix, 0, 0, cos(angle) +\
4030 pow(gsl_vector_get(axis, 0),2)*(1-cos(angle)));
4031 gsl_matrix_set(matrix, 0, 1, gsl_vector_get(axis, 0)*gsl_vector_get(axis, 1)*\
4032 (1-cos(angle)) -\
4033 gsl_vector_get(axis, 2)*sin(angle));
4034 gsl_matrix_set(matrix, 0, 2, gsl_vector_get(axis, 0)*gsl_vector_get(axis, 2)*\
4035 (1-cos(angle)) +\
4036 gsl_vector_get(axis, 1)*sin(angle));
4037
4038 gsl_matrix_set(matrix, 1, 0, gsl_vector_get(axis, 1)*gsl_vector_get(axis, 0)*\
4039 (1-cos(angle)) +\
4040 gsl_vector_get(axis, 2)*sin(angle));
4041 gsl_matrix_set(matrix, 1, 1, cos(angle) +\
4042 pow(gsl_vector_get(axis, 1),2)*(1-cos(angle)));
4043 gsl_matrix_set(matrix, 1, 2, gsl_vector_get(axis, 1)*gsl_vector_get(axis, 2)*\
4044 (1-cos(angle)) -\
4045 gsl_vector_get(axis, 0)*sin(angle));
4046
4047 gsl_matrix_set(matrix, 2, 0, gsl_vector_get(axis, 2)*gsl_vector_get(axis, 0)*\
4048 (1-cos(angle)) -\
4049 gsl_vector_get(axis, 1)*sin(angle));
4050 gsl_matrix_set(matrix, 2, 1, gsl_vector_get(axis, 2)*gsl_vector_get(axis, 1)*\
4051 (1-cos(angle)) +\
4052 gsl_vector_get(axis, 0)*sin(angle));
4053 gsl_matrix_set(matrix, 2, 2, cos(angle) +\
4054 pow(gsl_vector_get(axis, 2),2)*(1-cos(angle)));
4055
4056}
4057
4059 const char *fname,
4060 UINT4 raColumn,
4061 UINT4 decColumn
4062)
4063{
4064
4065 UINT4 j, i=0, numSkyPoints=0; /* counters */
4066 CohPTFSkyPositions *skyPoints; /* sky positions structure */
4067 char *value, line[256]; /* string holders */
4068 FILE *data; /* file object */
4069
4070 /* read file */
4071 data = fopen(fname, "r");
4072
4073 /* check file */
4074 if (data == NULL)
4075 {
4076 error("Error reading sky locations file %s. Please verify this path and try again\n", fname);
4077 }
4078
4079 /* find number of lines */
4080 while (fgets(line, sizeof(line), data))
4081 {
4082 numSkyPoints += 1;
4083 }
4084
4085 /* seek to start of file again */
4086 fseek(data, 0, SEEK_SET);
4087
4088 /* assign memory for sky points */
4089 skyPoints = LALCalloc(1, sizeof(*skyPoints));
4090 skyPoints->numPoints = numSkyPoints;
4091 skyPoints->data = LALCalloc(1, numSkyPoints*sizeof(SkyPosition));
4092
4093 /* find last column we need */
4094 UINT4 lastColumn = raColumn;
4095 if (decColumn > raColumn)
4096 lastColumn = decColumn;
4097
4098 /* read data line by line */
4099 while (fgets(line, sizeof(line), data))
4100 {
4101 /* set counter */
4102 j = 0;
4103
4104 /* extract first value */
4105 value = strtok(line, " ");
4106
4107 /* loop over the columns and extract the correct ones */
4108 while (j <= lastColumn)
4109 {
4110 if (j==raColumn)
4111 skyPoints->data[i].longitude = (REAL4) atof(value) * LAL_PI_180;
4112 else if (j==decColumn)
4113 skyPoints->data[i].latitude = (REAL4) atof(value) * LAL_PI_180;
4114
4115 /* move on to next column */
4116 value = strtok(NULL, " ");
4117 j++;
4118 }
4119
4120 i++;
4121 }
4122
4123 return skyPoints;
4124
4125}
4126
4128 struct coh_PTF_params *params
4129)
4130{
4131 /* set up variables */
4133 CohPTFSkyPositions *geoSkyPoints;
4134 LALDetector *detectors[params->numIFO];
4135 REAL8 lightTravelTime, timeDelay, angle;
4136 gsl_vector *locations[params->numIFO], *normal, *northPole, *axis;
4137 UINT4 i, ifoNumber, numSkyPoints;
4138
4139 /* get site coordinates */
4140 i=0;
4141 for(ifoNumber=0; ifoNumber<LAL_NUM_IFO; ifoNumber++)
4142 {
4143 if (params->haveTrig[ifoNumber])
4144 {
4145 detectors[i] = LALCalloc(1, sizeof(*detectors[i]));
4146 XLALReturnDetector(detectors[i], ifoNumber);
4147 locations[i] = gsl_vector_alloc(3);
4148 REALToGSLVector(detectors[i]->location, locations[i], 3);
4149 i++;
4150 }
4151 }
4152
4153 /* get light travel time */
4154 lightTravelTime = XLALLightTravelTime(detectors[0], detectors[1]);
4155 lightTravelTime *= 1e-9;
4156
4157 /* calculate number of skypoints */
4158 numSkyPoints = 2*(UINT4) floor(lightTravelTime/params->timingAccuracy) + 1;
4159
4160 /* assign memory for sky points */
4161 geoSkyPoints = LALCalloc(1, sizeof(CohPTFSkyPositions));
4162 geoSkyPoints->numPoints = numSkyPoints;
4163 geoSkyPoints->data = LALCalloc(1,geoSkyPoints->numPoints*sizeof(SkyPosition));
4164
4165 /* generate arc across equator */
4166 for (i=0; i < numSkyPoints; i++)
4167 {
4168 timeDelay = (INT4) (i - numSkyPoints/2) * params->timingAccuracy;
4169 //verbose("%f\n", timeDelay);
4170 geoSkyPoints->data[i].longitude = acos(-timeDelay/lightTravelTime);
4171 //verbose("%f\n", geoSkyPoints->data[i].longitude);
4172 geoSkyPoints->data[i].latitude = 0.;
4173 geoSkyPoints->data[i].system = COORDINATESYSTEM_GEOGRAPHIC;
4174 }
4175
4176 /* calculate normal for time delay arc */
4177 normal = gsl_vector_alloc(3);
4178 cross_product(normal, locations[0], locations[1]);
4179 normalise(normal);
4180
4181 /* calculate angle between this normal, and normal of equator */
4182 /* calculate unit vector to rotate around */
4183 northPole = gsl_vector_alloc(3);
4184 gsl_vector_set(northPole, 0, 0);
4185 gsl_vector_set(northPole, 1, 0);
4186 gsl_vector_set(northPole, 2, 1);
4187 gsl_blas_ddot(normal, northPole, &angle);
4188 angle = acos(angle);
4189
4190 /* generate rotation vector */
4191 axis = gsl_vector_alloc(3);
4192 cross_product(axis, normal, northPole);
4193
4194 /* rotate arc into plane of detectors and earth centre */
4195 coh_PTF_rotate_skyPoints(geoSkyPoints, axis, angle);
4196 //verbose("\n");
4197
4198 /* convert from earth-fixed to sky-fixed */
4200 skyPoints = LALCalloc(1, sizeof(*skyPoints));
4201 skyPoints->numPoints = geoSkyPoints->numPoints;
4202 skyPoints->data = LALCalloc(1, skyPoints->numPoints*sizeof(SkyPosition));
4203 for (i=0; i<numSkyPoints; i++)
4204 {
4205 //verbose("%f\n", XLALArrivalTimeDiff(detectors[0]->location, detectors[1]->location, geoSkyPoints->data[i].longitude, geoSkyPoints->data[i].latitude, &params->trigTime));
4207 &geoSkyPoints->data[i], &params->trigTime);
4208 XLALNormalizeSkyPosition(&skyPoints->data[i].longitude, &skyPoints->data[i].latitude);
4209 //verbose("%f\n", XLALArrivalTimeDiff(detectors[0]->location, detectors[1]->location, skyPoints->data[i].longitude, skyPoints->data[i].latitude, &params->trigTime));
4210 }
4211
4212 /* free memory */
4213 for( ifoNumber = 0; ifoNumber < params->numIFO; ifoNumber++)
4214 {
4215 if (detectors[ifoNumber] )
4216 LALFree(detectors[ifoNumber]);
4217 if (locations[ifoNumber])
4218 gsl_vector_free(locations[ifoNumber]);
4219 }
4220 gsl_vector_free(normal);
4221 gsl_vector_free(northPole);
4222 gsl_vector_free(axis);
4223
4224 return skyPoints;
4225}
4226
4227/*
4228 * Set up three detector sky grid by tiling time-delay between detector 0 and
4229 * detector 1, and for each of those values tiling time-delay between detector
4230 * 0 and detector 2
4231 */
4232
4234 struct coh_PTF_params *params
4235){
4236
4237 /* set up variables */
4239 LALDetector *detectors[params->numIFO];
4240 gsl_vector *locations[params->numIFO], *baseline[params->numIFO],\
4241 *northPole, *xaxis, *normal;
4242 gsl_matrix *matrix;
4243 REAL8 T[params->numIFO], t2, t3, A, B, angle, xangle, zangle,\
4244 condition, xphi, nphi, ntheta;
4245 UINT4 i, j, k, p, ifoNumber, numXPoints, numYPoints,\
4246 numSkyPoints, totalPoints;
4247
4248 /* get site coordinates */
4249 i=0;
4250 for(ifoNumber=0; ifoNumber<LAL_NUM_IFO; ifoNumber++)
4251 {
4252 if (params->haveTrig[ifoNumber])
4253 {
4254 detectors[i] = LALCalloc(1, sizeof(*detectors[i]));
4255 XLALReturnDetector(detectors[i], ifoNumber);
4256 locations[i] = gsl_vector_alloc(3);
4257 REALToGSLVector(detectors[i]->location, locations[i], 3);
4258 if (i>=1)
4259 {
4260 /* get light travel times relative to first detector */
4262 T[i-1] *= 1e-9;
4263 /* get detector baselines */
4264 baseline[i-1] = gsl_vector_alloc(3);
4265 gsl_vector_memcpy(baseline[i-1], locations[i]);
4266 gsl_vector_sub(baseline[i-1], locations[0]);
4267 normalise(baseline[i-1]);
4268 }
4269 i++;
4270 }
4271 }
4272
4273 /* calculate angle between baselines */
4274 gsl_blas_ddot(baseline[0], baseline[1], &angle);
4275 angle = acos(angle);
4276 verbose("angle = %e\n", angle);
4277
4278 /* calculate number of points spanning first two-detector time delay */
4279 numXPoints = 2*(UINT4) floor(T[0]/params->timingAccuracy) + 1;
4280 numYPoints = 2*(UINT4) floor(T[1]/params->timingAccuracy) + 1;
4281 numSkyPoints = 0;
4282
4283 totalPoints = numXPoints * numYPoints;
4284 REAL4 valid[totalPoints];
4285
4286 /* calculate number of points in y direction for each x */
4287 k=0;
4288 for (i=0; i<numXPoints; i++)
4289 {
4290 t2 = (INT4) (i - numXPoints/2) * params->timingAccuracy;
4291 for (j=0; j<numYPoints; j++)
4292 {
4293 t3 = (INT4) (j - numYPoints/2) * params->timingAccuracy;
4294 A = -T[1]/T[0] * t2 * cos(angle);
4295 B = pow(T[1], 2) * (pow(t2/T[0], 2) - pow(sin(angle), 2));
4296 condition = pow(t3, 2) + 2*A*t3 + B;
4297 if (condition <= 0)
4298 {
4299 valid[k] = 0;
4300 numSkyPoints++;
4301 }
4302 else
4303 {
4304 valid[k] = 1;
4305 }
4306 k++;
4307 }
4308 }
4309
4310 /* assign memory for sky points */
4311 skyPoints = LALCalloc(1, sizeof(*skyPoints));
4312 skyPoints->numPoints = numSkyPoints;
4313 skyPoints->data = LALCalloc(1, numSkyPoints*sizeof(SkyPosition));
4314
4315 /*
4316 * Construct rotations from Rabaste network coordinates to geographical
4317 * coordinates
4318 */
4319
4320 normal = gsl_vector_alloc(3);
4321 matrix = gsl_matrix_alloc(3, 3);
4322 xaxis = gsl_vector_alloc(3);
4323
4324 /* construct x-axis of network coordinates */
4325 xangle = LAL_PI_2 - angle;
4326 cross_product(normal, baseline[0], baseline[1]);
4327 rotation_matrix(matrix, normal, xangle);
4328 /* apply rotation */
4329 gsl_blas_dgemv(CblasNoTrans, 1.0, matrix, baseline[1], 0.0, xaxis);
4330
4331 /*
4332 * Rabaste network coordinate system has z-axis as the baseline between
4333 * detectors 1 and 2.
4334 * We need to rotate that onto the geographical north pole:
4335 */
4336
4337 northPole = gsl_vector_alloc(3);
4338
4339 /* construct rotation matrix */
4340 gsl_vector_set(northPole, 0, 0);
4341 gsl_vector_set(northPole, 1, 0);
4342 gsl_vector_set(northPole, 2, 1);
4343 gsl_blas_ddot(baseline[0], northPole, &zangle);
4344 zangle = acos(zangle);
4345 cross_product(normal, baseline[0], northPole);
4346 rotation_matrix(matrix, normal, zangle);
4347
4348 verbose("xangle = %e\n", xangle);
4349 verbose("zangle = %e\n", zangle);
4350
4351 /* rotate xaxis */
4352 gsl_vector *xaxis2 = gsl_vector_alloc(3);
4353 gsl_blas_dgemv(CblasNoTrans, 1.0, matrix, xaxis2, 0.0, xaxis);
4354 normalise(xaxis2);
4355 xphi = atan2(gsl_vector_get(xaxis2, 1), gsl_vector_get(xaxis2, 0));
4356
4357 verbose("xphi = %e\n", xphi);
4358
4359 /* assign sky points */
4360 /* calculate number of points in y direction for each x */
4361 k = 0;
4362 p = 0;
4363 for (i=0; i<numXPoints; i++)
4364 {
4365 t2 = (INT4) (i - numXPoints/2) * params->timingAccuracy;
4366 for (j=0; j<numYPoints; j++)
4367 {
4368 t3 = (INT4) (j - numYPoints/2) * params->timingAccuracy;
4369 if (valid[k]==0)
4370 {
4371 /* calculate (phi, theta) in network coordinates */
4372 ntheta = acos(-t2/T[0]);
4373 nphi = acos(-(T[0]*t3-T[1]*t2*cos(angle))/\
4374 (T[1]*sqrt(pow(T[0],2)-pow(t2,2))*sin(angle)));
4375 skyPoints->data[p].longitude = nphi;
4376 skyPoints->data[p].latitude = ntheta-LAL_PI_2;
4377 skyPoints->data[p].system = COORDINATESYSTEM_EQUATORIAL;
4378 XLALNormalizeSkyPosition(&skyPoints->data[p].longitude, &skyPoints->data[p].latitude);
4379 coh_PTF_rotate_SkyPosition(&skyPoints->data[i], matrix);
4380 skyPoints->data[p].longitude -= xphi;
4381
4382 p++;
4383 }
4384 k++;
4385 }
4386 }
4387
4388 return skyPoints;
4389
4390}
4391
4393 const REAL8 *input,
4394 gsl_vector *output,
4395 size_t size
4396)
4397{
4398 UINT4 i;
4399 for (i=0; i<size; i++)
4400 {
4401 gsl_vector_set(output, i, input[i]);
4402 }
4403}
4404
4406 UINT4 *start,
4407 UINT4 *end,
4408 LIGOTimeGPS *epoch,
4409 struct coh_PTF_params *params
4410 )
4411{
4412 /* WARNING: THIS FUNCTION WILL NOT WORK WITH SHORT SLIDES. DO NOT ATTEMPT
4413 * TO SLIDE INJECTION TRIGGERS WITHOUT FIXING THIS FUNCTION FIRST! */
4414
4415 /* define variables */
4416 LIGOTimeGPS injTime, segmentStart, segmentEnd;
4417 UINT4 injSamplePoint, injWindow, tmpStart, tmpEnd;
4418 REAL8 injDiff;
4419 INT8 startDiff, endDiff;
4420 SimInspiralTable *thisInject = NULL;
4421
4422 /* set variables */
4423 segmentStart = *epoch;
4424 segmentEnd = *epoch;
4425 XLALGPSAdd(&segmentEnd, params->strideDuration);
4426 thisInject = params->injectList;
4427
4428 tmpStart = tmpEnd = 0;
4429
4430 /* loop over injections */
4431 while (thisInject)
4432 {
4433 injTime = thisInject->geocent_end_time;
4434 startDiff = XLALGPSToINT8NS(&injTime) - XLALGPSToINT8NS(&segmentStart);
4435 endDiff = XLALGPSToINT8NS(&injTime) - XLALGPSToINT8NS(&segmentEnd);
4436
4437 if ((startDiff > 0) && (endDiff < 0))
4438 {
4439 verbose("Generating analysis segment for injection at %d.\n",
4440 injTime.gpsSeconds);
4441 if (tmpStart)
4442 {
4443 verbose("warning: multiple injections in this segment.\n");
4444 tmpStart = params->analStartPoint;
4445 tmpEnd = params->analEndPoint;
4446 }
4447 else
4448 {
4449 injDiff = (REAL8) ((XLALGPSToINT8NS(&injTime) - \
4450 XLALGPSToINT8NS(&segmentStart)) / 1E9);
4451 injSamplePoint = floor(injDiff * params->sampleRate + 0.5);
4452 injSamplePoint += params->analStartPoint;
4453 injWindow = floor(params->injSearchWindow * params->sampleRate
4454 + 1);
4455 tmpStart = injSamplePoint - injWindow;
4456 if (tmpStart < params->analStartPoint)
4457 tmpStart = params->analStartPoint;
4458 tmpEnd = injSamplePoint + injWindow + 1;
4459 if (tmpEnd > params->analEndPoint)
4460 tmpEnd = params->analEndPoint;
4461 verbose("Found analysis segment at [%d,%d).\n", tmpStart, tmpEnd);
4462 }
4463 }
4464 thisInject = thisInject->next;
4465 }
4466 *start = tmpStart;
4467 *end = tmpEnd;
4468}
4469
4471 struct coh_PTF_params *params,
4472 LIGOTimeGPS segStartTime,
4473 LIGOTimeGPS segEndTime)
4474{
4475 INT8 currTimeNS;
4476 /* Does the segment end before the trigStartTime */
4477 if (params->trigStartTimeNS)
4478 {
4479 currTimeNS = segEndTime.gpsSeconds * 1E9 + segEndTime.gpsNanoSeconds;
4480 if (params->trigStartTimeNS > currTimeNS)
4481 {
4482 return 1;
4483 }
4484 }
4485 /* Does the segment start before the trigEndTime */
4486 if (params->trigEndTimeNS)
4487 {
4488 currTimeNS = segStartTime.gpsSeconds * 1E9 + segStartTime.gpsNanoSeconds;
4489 if (params->trigStartTimeNS > currTimeNS)
4490 {
4491 return 1;
4492 }
4493 }
4494 /* Otherwise pass */
4495 return 0;
4496}
4497
4499 struct coh_PTF_params *params,
4500 InspiralTemplate *tmplt,
4501 LIGOTimeGPS *epoch
4502 )
4503{
4504 /* define variables */
4505 LIGOTimeGPS injTime, segmentStart, segmentEnd;
4506 REAL8 tmpltMchirp,injMchirp,mchirpDiff,mchirpWin;
4507 INT8 startDiff, endDiff;
4508 SimInspiralTable *thisInject = NULL;
4509 UINT4 passMchirpCheck;
4510
4511 /* set variables */
4512 segmentStart = *epoch;
4513 segmentEnd = *epoch;
4514 XLALGPSAdd(&segmentEnd, params->strideDuration);
4515 passMchirpCheck = 2;
4516 thisInject = params->injectList;
4517
4518 /* loop over injections */
4519 while (thisInject)
4520 {
4521 injTime = thisInject->geocent_end_time;
4522 startDiff = XLALGPSToINT8NS(&injTime) - XLALGPSToINT8NS(&segmentStart);
4523 endDiff = XLALGPSToINT8NS(&injTime) - XLALGPSToINT8NS(&segmentEnd);
4524 if ((startDiff > 0) && (endDiff < 0))
4525 {
4526 verbose("Generating analysis segment for injection at %d.\n",
4527 injTime.gpsSeconds);
4528 if (passMchirpCheck != 2)
4529 {
4530 verbose("warning: multiple injections in this segment.\n");
4531 passMchirpCheck = 1;
4532 break;
4533 }
4534 injMchirp = thisInject->mchirp;
4535 tmpltMchirp = tmplt->chirpMass;
4536 mchirpDiff = (injMchirp - tmpltMchirp)/tmpltMchirp;
4537 /* The mchirp window is increased with mchirp */
4538 if (injMchirp < 2)
4539 mchirpWin = params->injMchirpWindow;
4540 else if (injMchirp < 3)
4541 mchirpWin = params->injMchirpWindow * 2.5;
4542 else if (injMchirp < 4)
4543 mchirpWin = params->injMchirpWindow * 5;
4544 else
4545 // Note that I haven't tuned this above Mchirp = 6
4546 mchirpWin = params->injMchirpWindow * 10;
4547
4548 if (fabs(mchirpDiff) > mchirpWin)
4549 passMchirpCheck = 0;
4550 else
4551 passMchirpCheck = 1;
4552 }
4553 thisInject = thisInject->next;
4554 }
4555
4556 if (passMchirpCheck == 2)
4557 {
4558 verbose("WARNING: No injections found in this segment!? Not analysing\n");
4559 passMchirpCheck = 0;
4560 }
4561 return passMchirpCheck;
4562}
4563
4565 REAL4TimeSeries** timeSeries,
4566 UINT4 length
4567)
4568{
4569 UINT4 i;
4570 for (i = 0 ; i < length ; i++)
4571 {
4572 timeSeries[i] = NULL;
4573 }
4574}
4575
4577 REAL4FrequencySeries** freqSeries,
4578 UINT4 length
4579)
4580{
4581 UINT4 i;
4582 for (i = 0 ; i < length ; i++)
4583 {
4584 freqSeries[i] = NULL;
4585 }
4586}
4587
4589 RingDataSegments** segment,
4590 UINT4 length
4591)
4592{
4593 UINT4 i;
4594 for (i = 0 ; i < length ; i++)
4595 {
4596 segment[i] = NULL;
4597 }
4598}
4599
4601 REAL8Array** array,
4602 UINT4 length
4603)
4604{
4605 UINT4 i;
4606 for (i = 0 ; i < length ; i++)
4607 {
4608 array[i] = NULL;
4609 }
4610}
4611
4613 COMPLEX8VectorSequence** vecSeq,
4614 UINT4 length
4615)
4616{
4617 UINT4 i;
4618 for (i = 0 ; i < length ; i++)
4619 {
4620 vecSeq[i] = NULL;
4621 }
4622}
4623
4625 REAL4** array,
4626 UINT4 length
4627)
4628{
4629 UINT4 i;
4630 for (i = 0 ; i < length ; i++)
4631 {
4632 array[i] = NULL;
4633 }
4634}
4635
4637 UINT4** array,
4638 UINT4 length
4639)
4640{
4641 UINT4 i;
4642 for (i = 0 ; i < length ; i++)
4643 {
4644 array[i] = NULL;
4645 }
4646}
4647
4649 LALDetector** detector,
4650 UINT4 length
4651)
4652{
4653 UINT4 i;
4654 for (i = 0 ; i < length ; i++)
4655 {
4656 detector[i] = NULL;
4657 }
4658}
int j
int k
int XLALInspiralGetApproximantString(CHAR *output, UINT4 length, Approximant approx, LALPNOrder order)
#define LALCalloc(m, n)
#define LALFree(p)
SimInspiralTable * XLALSimInspiralTableFromLIGOLw(const char *fileName)
LALRINGDOWN_EOBNR_INJECT
LALRINGDOWN_SPECTRUM_MEDIAN_MEAN
LALRINGDOWN_DATATYPE_HT_REAL4
LALRINGDOWN_DATATYPE_ZERO
LALRINGDOWN_DATATYPE_HT_REAL8
#define LIGOMETA_IFOS_MAX
#define LIGOMETA_SEARCH_MAX
#define LIGOMETA_IFO_MAX
InterferometerNumber
LAL_IFO_G1
LAL_NUM_IFO
LAL_IFO_H1
LAL_IFO_H2
LAL_IFO_T1
LAL_IFO_V1
LAL_IFO_L1
void XLALReturnDetector(LALDetector *det, InterferometerNumber IFONumber)
void XLALReturnIFO(char *ifo, InterferometerNumber IFONumber)
SnglInspiralTable * XLALDestroySnglInspiralTableRow(SnglInspiralTable *row)
TimeSlide * XLALCreateTimeSlide(void)
SegmentTable * XLALCreateSegmentTableRow(const ProcessTable *process)
void XLALDestroyTimeSlideTable(TimeSlide *)
void XLALDestroySegmentTable(SegmentTable *head)
UINT2 A
#define fprintf
double e
double theta
REAL4 fLower
Definition: blindinj.c:127
int verbose
Definition: chirplen.c:77
@ ALL_SKY
Definition: coh_PTF.h:290
@ SINGLE_SKY_POINT
Definition: coh_PTF.h:287
@ TWO_DET_ALL_SKY
Definition: coh_PTF.h:291
@ TWO_DET_SKY_PATCH
Definition: coh_PTF.h:288
@ SKY_PATCH
Definition: coh_PTF.h:289
int write_COMPLEX8FrequencySeries(COMPLEX8FrequencySeries *series)
#define BUFFER_SIZE
Definition: coh_PTF.h:80
int write_REAL4FrequencySeries(REAL4FrequencySeries *series)
#define sanity_check(condition)
Definition: coh_PTF.h:85
void coh_PTF_normalize(struct coh_PTF_params *params, FindChirpTemplate *fcTmplt, REAL4FrequencySeries *invspec, REAL8Array *PTFM, REAL8Array *PTFN, COMPLEX8VectorSequence *PTFqVec, COMPLEX8FrequencySeries *sgmnt, COMPLEX8FFTPlan *invPlan, UINT4 spinTemplate)
int write_REAL4TimeSeries(REAL4TimeSeries *series)
CohPTFSkyPositions * coh_PTF_read_grid_from_file(const char *fname, UINT4 raColumn, UINT4 decColumn)
void coh_PTF_initialize_time_series(struct coh_PTF_params *params, LIGOTimeGPS segStartTime, REAL8 fLower, REAL4TimeSeries **cohSNRP, REAL4TimeSeries **nullSNRP, REAL4TimeSeries **traceSNRP, REAL4TimeSeries **bankVeto, REAL4TimeSeries **autoVeto, REAL4TimeSeries **chiSquare, REAL4TimeSeries **snrComps, REAL4TimeSeries **pValues, REAL4TimeSeries **gammaBeta, UINT4 spinTemplates)
SnglInspiralTable * conv_insp_tmpl_to_sngl_table(InspiralTemplate *template, UINT4 eventNumber)
void coh_PTF_set_null_input_REAL4(REAL4 **array, UINT4 length)
REAL4FFTPlan * coh_PTF_get_fft_revplan(struct coh_PTF_params *params)
void coh_PTF_create_time_slide_table(struct coh_PTF_params *params, INT8 *slideIDList, RingDataSegments **segments, TimeSlide **time_slide_headP, TimeSlideSegmentMapTable **time_slide_map_headP, SegmentTable **segment_table_headP, TimeSlideVectorList **longTimeSlideListP, TimeSlideVectorList **shortTimeSlideListP, REAL4 *timeSlideVectors, INT4 numSegments)
void coh_PTF_rotate_SkyPosition(SkyPosition *skyPoint, gsl_matrix *matrix)
void coh_PTF_convert_time_offsets_to_points(struct coh_PTF_params *params, REAL4 *timeOffsets, INT4 *timeOffsetPoints)
void coh_PTF_rotate_skyPoints(CohPTFSkyPositions *skyPoints, gsl_vector *axis, REAL8 angle)
void coh_PTF_setup_null_stream(struct coh_PTF_params *params, REAL4TimeSeries **channel, REAL4FrequencySeries **invspec, RingDataSegments **segments, REAL4 *Fplustrig, REAL4 *Fcrosstrig, REAL4 *timeOffsets, REAL4FFTPlan *fwdplan, REAL4FFTPlan *revplan, REAL4FFTPlan *psdplan, REAL4 *timeSlideVectors, struct timeval startTime)
void coh_PTF_calculate_single_detector_filters(struct coh_PTF_params *params, FindChirpTemplate *fcTmplt, REAL4FrequencySeries **invspec, REAL8Array **PTFM, COMPLEX8VectorSequence **PTFqVec, REAL4TimeSeries **snrComps, UINT4 **snglAcceptPoints, UINT4 *snglAcceptCount, RingDataSegments **segments, COMPLEX8FFTPlan *invPlan, UINT4 spinTemplate, UINT4 segNum)
void normalise(gsl_vector *vec)
UINT4 coh_PTF_trig_time_check(struct coh_PTF_params *params, LIGOTimeGPS segStartTime, LIGOTimeGPS segEndTime)
void coh_PTF_calculate_null_stream_snr(struct coh_PTF_params *params, REAL4TimeSeries *nullSNR, COMPLEX8VectorSequence **PTFqVec, gsl_matrix *eigenvecsNull, gsl_vector *eigenvalsNull, UINT4 spinTemplate, UINT4 vecLength, UINT4 vecLoc, UINT4 snrLoc)
void coh_PTF_set_null_input_COMPLEX8VectorSequence(COMPLEX8VectorSequence **vecSeq, UINT4 length)
int coh_PTF_get_null_stream(struct coh_PTF_params *params, REAL4TimeSeries *channel[LAL_NUM_IFO+1], REAL4 *Fplus, REAL4 *Fcross, REAL4 *timeOffsets)
UINT4 coh_PTF_calculate_single_det_spin_snr(struct coh_PTF_params *params, REAL8Array **PTFM, COMPLEX8VectorSequence **PTFqVec, REAL4TimeSeries **snrComps, UINT4 ifoNumber, UINT4 *localAcceptPoints)
static void XLALDestroyTimeSlideSegmentMapTable(TimeSlideSegmentMapTable *head)
void coh_PTF_destroy_time_series(REAL4TimeSeries *cohSNR, REAL4TimeSeries *nullSNR, REAL4TimeSeries *traceSNR, REAL4TimeSeries **bankVeto, REAL4TimeSeries **autoVeto, REAL4TimeSeries **chiSquare, REAL4TimeSeries **pValues, REAL4TimeSeries **gammaBeta, REAL4TimeSeries **snrComps)
UINT8 coh_PTF_add_sngl_triggers(struct coh_PTF_params *params, SnglInspiralTable **eventList, SnglInspiralTable **thisEvent, REAL4TimeSeries *cohSNR, FindChirpTemplate *fcTmplt, InspiralTemplate PTFTemplate, UINT8 eventId, REAL4TimeSeries **pValues, REAL4TimeSeries **bankVeto, REAL4TimeSeries **autoVeto, REAL4TimeSeries **chiSquare, REAL8Array **PTFM, UINT4 startPoint, UINT4 endPoint)
REAL4 coh_PTF_get_spin_SNR(REAL4 *v1p, REAL4 *v2p, UINT4 vecLengthTwo)
CohPTFSkyPositions * coh_PTF_two_det_sky_grid(struct coh_PTF_params *params)
void coh_PTF_calculate_rotated_vectors(struct coh_PTF_params *params, COMPLEX8VectorSequence **PTFqVec, REAL4 *u1, REAL4 *u2, REAL4 *Fplus, REAL4 *Fcross, INT4 *timeOffsetPoints, gsl_matrix *eigenvecs, gsl_vector *eigenvals, UINT4 numPoints, UINT4 position, UINT4 vecLength, UINT4 vecLengthTwo, UINT4 detectorNum)
void coh_PTF_set_null_input_RingDataSegments(RingDataSegments **segment, UINT4 length)
void REALToGSLVector(const REAL8 *input, gsl_vector *output, size_t size)
CohPTFSkyPositions * coh_PTF_generate_sky_points(struct coh_PTF_params *params)
CohPTFSkyPositions * coh_PTF_parse_time_delays(CohPTFSkyPositions *skyPoints, struct coh_PTF_params *params)
void coh_PTF_initialize_structures(struct coh_PTF_params *params, FindChirpTemplate **fcTmpltP, FindChirpTmpltParams **fcTmpltParamsP, REAL8Array **PTFM, REAL8Array **PTFN, COMPLEX8VectorSequence **PTFqVec, REAL4FFTPlan *fwdplan)
RingDataSegments * coh_PTF_get_segments(REAL4TimeSeries *channel, REAL4FrequencySeries *invspec, REAL4FFTPlan *fwdplan, InterferometerNumber NumberIFO, REAL4 *timeSlideVectors, struct coh_PTF_params *params)
REAL4FFTPlan * coh_PTF_get_fft_fwdplan(struct coh_PTF_params *params)
void coh_PTF_cleanup(struct coh_PTF_params *params, ProcessParamsTable *procpar, REAL4FFTPlan *fwdplan, REAL4FFTPlan *psdplan, REAL4FFTPlan *revplan, COMPLEX8FFTPlan *invPlan, REAL4TimeSeries **channel, REAL4FrequencySeries **invspec, RingDataSegments **segments, MultiInspiralTable *events, SnglInspiralTable *snglEvents, InspiralTemplate *PTFbankhead, FindChirpTemplate *fcTmplt, FindChirpTmpltParams *fcTmpltParams, REAL8Array **PTFM, REAL8Array **PTFN, COMPLEX8VectorSequence **PTFqVec, REAL4 *timeOffsets, REAL4 *slidTimeOffsets, REAL4 *Fplus, REAL4 *Fcross, REAL4 *Fplustrig, REAL4 *Fcrosstrig, CohPTFSkyPositions *skyPoints, TimeSlide *time_slide_head, TimeSlideVectorList *longTimeSlideList, TimeSlideVectorList *shortTimeSlideList, REAL4 *timeSlideVectors, LALDetector **detectors, INT8 *slideIDList, TimeSlideSegmentMapTable *time_slide_map_head, SegmentTable *segment_table_head)
void coh_PTF_calculate_trace_snr(struct coh_PTF_params *params, REAL4TimeSeries *traceSNR, COMPLEX8VectorSequence **PTFqVec, gsl_matrix *eigenvecs, gsl_vector *eigenvals, REAL4 *Fplus, REAL4 *Fcross, INT4 *timeOffsetPoints, UINT4 spinTemplate, UINT4 vecLength, UINT4 vecLengthTwo, UINT4 vecLoc, UINT4 snrLoc)
void cross_product(gsl_vector *product, const gsl_vector *u, const gsl_vector *v)
CohPTFSkyPositions * coh_PTF_generate_sky_grid(struct coh_PTF_params *params)
UINT4 checkInjectionMchirp(struct coh_PTF_params *params, InspiralTemplate *tmplt, LIGOTimeGPS *epoch)
void timeval_print(struct timeval *tv)
static TimeSlideSegmentMapTable * XLALCreateTimeSlideSegmentMapTableRow(void)
void coh_PTF_set_null_input_REAL8Array(REAL8Array **array, UINT4 length)
void coh_PTF_calculate_det_stuff(struct coh_PTF_params *params, LALDetector **detectors, REAL4 *timeOffsets, REAL4 *Fplustrig, REAL4 *Fcrosstrig, CohPTFSkyPositions *skyPoints, UINT4 skyPointNum)
SnglInspiralTable * coh_PTF_create_sngl_event(struct coh_PTF_params *params, REAL4TimeSeries *cohSNR, FindChirpTemplate *fcTmplt, InspiralTemplate PTFTemplate, UINT8 *eventId, REAL4TimeSeries **pValues, REAL4TimeSeries **bankVeto, REAL4TimeSeries **autoVeto, REAL4TimeSeries **chiSquare, REAL8Array **PTFM, UINT4 currPos)
static void XLALDestroyTimeSlideSegmentMapTableRow(TimeSlideSegmentMapTable *row)
UINT4 coh_PTF_accept_sngl_trig_check(struct coh_PTF_params *params, SnglInspiralTable **eventList, SnglInspiralTable thisEvent)
CohPTFSkyPositions * coh_PTF_three_det_sky_grid(struct coh_PTF_params *params)
void rotation_matrix(gsl_matrix *matrix, gsl_vector *axis, REAL8 angle)
REAL4FFTPlan * coh_PTF_get_fft_psdplan(struct coh_PTF_params *params)
void coh_PTF_rescale_data(REAL4TimeSeries *channel, REAL8 rescaleFactor)
void coh_PTF_set_null_input_UINT4(UINT4 **array, UINT4 length)
REAL4TimeSeries * coh_PTF_get_data(struct coh_PTF_params *params, const char *ifoChannel, const char *dataCache, UINT4 ifoNumber)
Definition: coh_PTF_utils.c:86
void coh_PTF_set_null_input_REAL4FrequencySeries(REAL4FrequencySeries **freqSeries, UINT4 length)
void coh_PTF_cluster_sngl_triggers(struct coh_PTF_params *params, SnglInspiralTable **eventList, SnglInspiralTable **thisEvent)
void coh_PTF_calculate_bmatrix(struct coh_PTF_params *params, gsl_matrix *eigenvecs, gsl_vector *eigenvals, REAL4 Fplus[LAL_NUM_IFO], REAL4 Fcross[LAL_NUM_IFO], REAL8Array *PTFM[LAL_NUM_IFO+1], UINT4 vecLength, UINT4 vecLengthTwo, UINT4 PTFMlen)
void coh_PTF_calculate_null_stream_norms(UINT4 vecLength, gsl_matrix *eigenvecsNull, gsl_vector *eigenvalsNull, REAL8Array *PTFM[LAL_NUM_IFO+1])
UINT4 coh_PTF_template_time_series_cluster(struct coh_PTF_params *params, REAL4TimeSeries *cohSNR, UINT4 *acceptPoints, INT4 *timeOffsetPoints, INT4 numPointCheck, UINT4 startPoint, UINT4 endPoint, UINT4 **snglAcceptPoints, UINT4 *snglAcceptCount)
COMPLEX8FFTPlan * coh_PTF_get_fft_invplan(struct coh_PTF_params *params)
void findInjectionSegment(UINT4 *start, UINT4 *end, LIGOTimeGPS *epoch, struct coh_PTF_params *params)
void coh_PTF_set_null_input_LALDetector(LALDetector **detector, UINT4 length)
long int timeval_subtract(struct timeval *t1)
CohPTFSkyPositions * coh_PTF_circular_grid(REAL4 angularResolution, REAL4 skyError)
REAL4FrequencySeries * coh_PTF_get_invspec(REAL4TimeSeries *channel, REAL4FFTPlan *fwdplan, REAL4FFTPlan *revplan, REAL4FFTPlan *psdplan, struct coh_PTF_params *params)
INT4 coh_PTF_data_condition(struct coh_PTF_params *params, REAL4TimeSeries **channel, REAL4FrequencySeries **invspec, RingDataSegments **segments, REAL4FFTPlan *fwdplan, REAL4FFTPlan *psdplan, REAL4FFTPlan *revplan, REAL4 **timeSlideVectorsP, struct timeval startTime)
Definition: coh_PTF_utils.c:4
void coh_PTF_reset_time_series(struct coh_PTF_params *params, LIGOTimeGPS segStartTime, REAL4TimeSeries *cohSNR, REAL4TimeSeries *nullSNR, REAL4TimeSeries *traceSNR, REAL4TimeSeries **bankVeto, REAL4TimeSeries **autoVeto, REAL4TimeSeries **chiSquare, REAL4TimeSeries **snrComps, REAL4TimeSeries **pValues, REAL4TimeSeries **gammaBeta, UINT4 spinTemplates)
void coh_PTF_calculate_coherent_SNR(struct coh_PTF_params *params, REAL4 *snrData, REAL4TimeSeries **pValues, REAL4TimeSeries **snrComps, INT4 *timeOffsetPoints, COMPLEX8VectorSequence **PTFqVec, REAL4 *Fplus, REAL4 *Fcross, gsl_matrix *eigenvecs, gsl_vector *eigenvals, UINT4 segStartPoint, UINT4 segEndPoint, UINT4 vecLength, UINT4 vecLengthTwo, UINT4 spinTemplate, UINT4 **snglAcceptPoints, UINT4 *snglAcceptCount)
int is_in_list(int i, const char *list)
MultiInspiralTable * coh_PTF_create_multi_event(struct coh_PTF_params *params, REAL4TimeSeries *cohSNR, FindChirpTemplate *fcTmplt, InspiralTemplate PTFTemplate, UINT8 *eventId, UINT4 spinTrigger, REAL4TimeSeries **pValues, REAL4TimeSeries **gammaBeta, REAL4TimeSeries **snrComps, REAL4TimeSeries *nullSNR, REAL4TimeSeries *traceSNR, REAL4TimeSeries **bankVeto, REAL4TimeSeries **autoVeto, REAL4TimeSeries **chiSquare, REAL8Array **PTFM, REAL4 rightAscension, REAL4 declination, INT8 slideId, INT4 *timeOffsetPoints, UINT4 currPos)
void coh_PTF_set_null_input_REAL4TimeSeries(REAL4TimeSeries **timeSeries, UINT4 length)
UINT4 coh_PTF_test_veto_vals(struct coh_PTF_params *params, REAL4TimeSeries *cohSNR, REAL4TimeSeries *nullSNR, REAL4TimeSeries **bankVeto, REAL4TimeSeries **autoVeto, UINT4 currPointLoc)
void coh_PTF_calculate_null_stream_filters(struct coh_PTF_params *params, FindChirpTemplate *fcTmplt, REAL4FrequencySeries **invspec, REAL8Array **PTFM, COMPLEX8VectorSequence **PTFqVec, RingDataSegments **segments, COMPLEX8FFTPlan *invPlan, UINT4 spinTemplate, UINT4 segNum)
const char * detector
int error(const char *fmt,...)
Definition: errutil.c:37
const double u
sigmaKerr data[0]
const double u2
const double B
REAL4TimeSeries * ring_get_frame_data(const char *cacheName, const char *channelName, LIGOTimeGPS *epoch, REAL8 duration, int dataType)
Definition: getdata.c:171
REAL4TimeSeries * get_zero_data(const char *channelName, LIGOTimeGPS *epoch, REAL8 duration, int dataType, REAL8 sampleRate)
Definition: getdata.c:130
int highpass_REAL4TimeSeries(REAL4TimeSeries *series, REAL8 frequency)
Definition: getdata.c:380
REAL4TimeSeries * get_simulated_data_new(const char *channelName, LIGOTimeGPS *epoch, REAL8 duration, REAL8 sampleRate, UINT4 simSeed, REAL8FrequencySeries *psd)
Definition: getdata.c:88
int resample_REAL4TimeSeries(REAL4TimeSeries *series, REAL8 sampleRate)
Definition: getdata.c:357
REAL4TimeSeries * get_frame_data_dbl_convert(const char *cacheName, const char *channelName, LIGOTimeGPS *epoch, REAL8 duration, int dataType, REAL8 dblHighPassFreq)
Definition: getdata.c:209
int trimpad_REAL4TimeSeries(REAL4TimeSeries *series, REAL8 padData)
Definition: getdata.c:430
void XLALDestroyREAL8Array(REAL8Array *)
REAL8Array * XLALCreateREAL8ArrayL(UINT4,...)
void XLALDestroyVectorSequence(REAL4VectorSequence *vecseq)
COMPLEX8VectorSequence * XLALCreateCOMPLEX8VectorSequence(UINT4 length, UINT4 veclen)
void XLALDestroyCOMPLEX8VectorSequence(COMPLEX8VectorSequence *vecseq)
REAL4VectorSequence * XLALCreateVectorSequence(UINT4 length, UINT4 veclen)
COMPLEX8FFTPlan * XLALCreateReverseCOMPLEX8FFTPlan(UINT4 size, int measurelvl)
void XLALDestroyCOMPLEX8FFTPlan(COMPLEX8FFTPlan *plan)
void XLALComputeDetAMResponse(double *fplus, double *fcross, const REAL4 D[3][3], const double ra, const double dec, const double psi, const double gmst)
REAL4FrequencySeries * XLALCreateREAL4FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL8FrequencySeries(REAL8FrequencySeries *series)
#define LAL_PI_2
#define LAL_PI_180
#define LAL_PI
#define LAL_TWOPI
uint64_t UINT8
double REAL8
#define XLAL_INIT_DECL(var,...)
int64_t INT8
#define crectf(re, im)
char CHAR
uint32_t UINT4
float complex COMPLEX8
int32_t INT4
float REAL4
LALNameLength
void * XLALMalloc(size_t n)
void XLALFree(void *p)
FindChirpSP
FindChirpPTF
#define LAL_INT8_FORMAT
int XLALStringPrint(char *s, size_t n, const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(3
static const INT4 m
REAL4FFTPlan * XLALCreateReverseREAL4FFTPlan(UINT4 size, int measurelvl)
REAL4FFTPlan * XLALCreateForwardREAL4FFTPlan(UINT4 size, int measurelvl)
void XLALDestroyREAL4FFTPlan(REAL4FFTPlan *plan)
void XLALNormalizeSkyPosition(double *restrict longitude, double *restrict latitude)
COORDINATESYSTEM_GEOGRAPHIC
COORDINATESYSTEM_EQUATORIAL
void LALGeographicToEquatorial(LALStatus *stat, SkyPosition *output, SkyPosition *input, LIGOTimeGPS *gpsTime)
REAL8 XLALTimeDelayFromEarthCenter(const double detector_earthfixed_xyz_metres[3], double source_right_ascension_radians, double source_declination_radians, const LIGOTimeGPS *gpstime)
double XLALArrivalTimeDiff(const double detector1_earthfixed_xyz_metres[3], const double detector2_earthfixed_xyz_metres[3], const double source_right_ascension_radians, const double source_declination_radians, const LIGOTimeGPS *gpstime)
INT8 XLALLightTravelTime(const LALDetector *aDet, const LALDetector *bDet)
REAL4TimeSeries * XLALCreateREAL4TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL4TimeSeries(REAL4TimeSeries *series)
const LALUnit lalStrainUnit
const LALUnit lalDimensionlessUnit
REAL4Vector * XLALCreateREAL4Vector(UINT4 length)
void XLALDestroyVector(REAL4Vector *vector)
void XLALDestroyREAL4Vector(REAL4Vector *vector)
COMPLEX8Vector * XLALCreateCOMPLEX8Vector(UINT4 length)
REAL4Vector * XLALCreateVector(UINT4 length)
void XLALDestroyCOMPLEX8Vector(COMPLEX8Vector *vector)
#define XLAL_ERROR_NULL(...)
XLAL_EFUNC
XLAL_FAILURE
REAL8 XLALGreenwichMeanSiderealTime(const LIGOTimeGPS *gpstime)
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
int XLALGPSCmp(const LIGOTimeGPS *t0, const LIGOTimeGPS *t1)
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
INT8 XLALGPSToINT8NS(const LIGOTimeGPS *epoch)
long long count
int ring_inject_signal(REAL4TimeSeries *series, int injectSignalType, const char *injectFile, const char *calCacheFile, REAL4 responseScale, const char *channel_name)
Definition: injsgnl.c:77
char name[LIGOMETA_SOURCE_MAX]
Definition: inspinj.c:561
static LALStatus status
Definition: inspinj.c:552
int i
Definition: inspinj.c:596
struct @3 * skyPoints
int numSkyPoints
Definition: inspinj.c:558
T
head
pos
size
row
int
str
segStartTime
segEndTime
string line
t2
t1
start
axis
int t
int startTime
int compute_data_segment(COMPLEX8FrequencySeries *segment, UINT4 segmentNumber, REAL4TimeSeries *series, REAL4FrequencySeries *invspec, COMPLEX8FrequencySeries *response, REAL8 segmentDuration, REAL8 strideDuration, REAL4FFTPlan *fwdPlan)
Definition: segment.c:38
LALDetector detectors[LAL_NUM_DETECTORS]
REAL4FrequencySeries * resample_psd(REAL4FrequencySeries *origspectrum, REAL8 sampleRate, REAL8 segmentDuration)
Definition: spectrm.c:105
REAL8FrequencySeries * generate_theoretical_psd(REAL4 deltaT, REAL8 segmentDuration, UINT4 spectrumNumber, REAL8 simScale)
Definition: spectrm.c:174
int invert_spectrum(REAL4FrequencySeries *spectrum, REAL8 dataSampleRate, REAL8 UNUSED strideDuration, REAL8 truncateDuration, REAL8 lowCutoffFrequency, REAL4FFTPlan *fwdPlan, REAL4FFTPlan *revPlan)
Definition: spectrm.c:237
REAL4FrequencySeries * compute_average_spectrum(REAL4TimeSeries *series, int spectrumAlgthm, REAL8 segmentDuration, REAL8 strideDuration, REAL4FFTPlan *fwdPlan, int whiteSpectrum)
Definition: spectrm.c:44
CHAR fname[256]
Definition: spininj.c:211
char * channel
SkyPosition * data
Definition: coh_PTF.h:270
This structure contains a frequency domain template used as input to the FindChirpFilter() routine.
COMPLEX8Vector * data
Vector of length containing the frequency template data ; For a template generated in the frequency ...
COMPLEX8VectorSequence * PTFQtilde
UNDOCUMENTED.
REAL4 tmpltNorm
The template dependent normalisation constant ; For the stationary phase template FindChirpSP this is...
REAL4VectorSequence * PTFQ
UNDOCUMENTED.
This structure contains the parameters for generation of templates by the various template generation...
RealFFTPlan * fwdPlan
For time domain templates, an FFTW plan used to transform the time domain data stored in xfacVec into...
REAL4Vector * PTFphi
UNDOCUMENTED.
REAL4Vector * PTFomega_2_3
UNDOCUMENTED.
UINT4 invSpecTrunc
The length to which to truncate the inverse power spectral density of the data in the time domain; If...
REAL4 maxTempLength
This can be used to store the maximum allowed template length, given the pad length and spectrum trun...
REAL4 fLow
The frequency domain low frequency cutoff ; All frequency domain data is zero below this frequency.
REAL4VectorSequence * PTFe1
UNDOCUMENTED.
LALPNOrder order
Specifies the post-Newtonian order of the templates; Valid pN orders are LAL_PNORDER_TWO,...
REAL4Vector * xfacVec
For frequency domain templates, this is a vector of length which contains the quantity ; For time do...
Approximant approximant
Generate templates of type approximant; Valid approximants are TaylorT1, TaylorT2,...
REAL4 dynRange
A dynamic range factor which cancels from the filter output; This allows quantities to be stored in ...
REAL4VectorSequence * PTFe2
UNDOCUMENTED.
INT4 dynamicTmpltFlow
Use longest template that will fit in pad length.
REAL8 deltaT
The sampling interval of the input data channel.
struct tagInspiralTemplate * next
INT4 gpsNanoSeconds
struct tagMultiInspiralTable * next
LIGOTimeGPS end_time
CHAR ifos[LIGOMETA_IFOS_MAX]
struct tagProcessParamsTable * next
REAL4Sequence * data
CHAR name[LALNameLength]
REAL4Sequence * data
LIGOTimeGPS epoch
REAL4 * data
REAL8 * data
REAL8Sequence * data
REAL8 * data
COMPLEX8FrequencySeries * sgmnt
Definition: coh_PTF.h:263
UINT4 numSgmnt
Definition: coh_PTF.h:262
LIGOTimeGPS end_time
LIGOTimeGPS start_time
long segment_def_id
struct tagSegmentTable * next
LIGOTimeGPS geocent_end_time
struct tagSimInspiralTable * next
REAL8 longitude
REAL8 latitude
CoordinateSystem system
LIGOTimeGPS impulse_time
CHAR ifo[LIGOMETA_IFO_MAX]
LIGOTimeGPS end
struct tagSnglInspiralTable * next
CHAR channel[LIGOMETA_CHANNEL_MAX]
CHAR search[LIGOMETA_SEARCH_MAX]
CHAR instrument[LIGOMETA_STRING_MAX]
long time_slide_id
struct tagTimeSlide * next
long process_id
REAL8 offset
struct tagTimeSlideSegmentMapTable * next
REAL4 timeSlideVectors[LAL_NUM_IFO]
Definition: coh_PTF.h:276
UINT4 analStartPoint
Definition: coh_PTF.h:278
double duration
Definition: series.h:36
char * name
Definition: series.h:37
float * data
Definition: series.h:46
enum @1 epoch
REAL4 alpha
Definition: tmpltbank.c:432
INT4 numSegments
Definition: tmpltbank.c:400
INT4 numPoints
Definition: tmpltbank.c:399
double deltaT
int output(const char *outfile, int outtype, REAL4TimeSeries *series)
Definition: view.c:603