Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
DopplerScan.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004, 2005, 2006 Reinhard Prix
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19
20/**
21 * \author Reinhard Prix
22 * \date 2004, 2005, 2006
23 * \file
24 * \brief Functions for generating search-grids for CFS.
25 */
26
27/*---------- INCLUDES ----------*/
28#include <math.h>
29#include <ctype.h>
30
31#include <lal/LALStdlib.h>
32#include <lal/DetectorSite.h>
33#include <lal/AVFactories.h>
34#include <lal/LALError.h>
35#include <lal/LALString.h>
36#include <lal/StringInput.h>
37#include <lal/UserInputParse.h>
38#include <lal/Velocity.h>
39#include <lal/TwoDMesh.h>
40
41#include <lal/LogPrintf.h>
42
43#include <lal/DopplerScan.h>
44
45
46/*---------- DEFINES ----------*/
47#ifdef __GNUC__
48#define UNUSED __attribute__ ((unused))
49#else
50#define UNUSED
51#endif
52
53/* Metric indexing scheme: if g_ij for i<=j: index = i + j*(j+1)/2 */
54/* the variable-order of PulsarMetric is {f, alpha, delta, f1, f2, ... } */
55
56#define INDEX_f0_f0 PMETRIC_INDEX(0,0)
57#define INDEX_f0_A PMETRIC_INDEX(0,1)
58#define INDEX_f0_D PMETRIC_INDEX(0,2)
59#define INDEX_f0_f1 PMETRIC_INDEX(0,3)
60
61#define INDEX_A_A PMETRIC_INDEX(1,1)
62#define INDEX_D_D PMETRIC_INDEX(2,2)
63#define INDEX_A_D PMETRIC_INDEX(1,2)
64#define INDEX_A_f1 PMETRIC_INDEX(1,3)
65
66#define INDEX_D_f1 PMETRIC_INDEX(2,3)
67
68#define INDEX_f1_f1 PMETRIC_INDEX(3,3)
69
70/* all-sky skyregion string, with exact boundaries */
71#define DELTA_0 "-1.570796"
72#define DELTA_1 "1.570796"
73#define ALPHA_0 "1e-6"
74#define ALPHA_1 "6.283185"
75
76#define SKYREGION_ALLSKY "(" ALPHA_0 ", " DELTA_0 "),(" ALPHA_1 ", " DELTA_0 "),(" ALPHA_1 ", " DELTA_1 "),(" ALPHA_0 ", " DELTA_1 ")"
77
78/* the amount by which we push-in the encosing rectangle to avoid spurious polygon-clipping
79 * of boundary-points due to numerical fluctuations in TwoDMesh().
80 */
81#define EPS4 1e-6
82
83/*---------- internal types ----------*/
84/** TwoDMesh() can have either of two preferred directions of meshing: */
85enum {
88};
89
91
95
96/*---------- internal prototypes ----------*/
97void getRange( LALStatus *, meshREAL y[2], meshREAL x, void *params );
98void getMetric( LALStatus *, meshREAL g[3], meshREAL skypos[2], void *params );
100
101DopplerSkyGrid *ConvertTwoDMesh2SkyGrid( const meshNODE *mesh2d, const SkyRegion *region );
102
103BOOLEAN pointInPolygon( const SkyPosition *point, const SkyRegion *polygon );
104
106
107DopplerSkyGrid *buildFlatSkyGrid( const SkyRegion *region, REAL8 dAlpha, REAL8 dDelta );
108DopplerSkyGrid *buildIsotropicSkyGrid( const SkyRegion *skyRegion, REAL8 dAlpha, REAL8 dDelta );
110DopplerSkyGrid *loadSkyGridFile( const CHAR *fname );
111
112void plotSkyGrid( LALStatus *, DopplerSkyGrid *skygrid, const SkyRegion *region, const DopplerSkyScanInit *init );
113void freeSkyGrid( DopplerSkyGrid *skygrid );
115
116void printFrequencyShifts( LALStatus *, const DopplerSkyScanState *skyScan, const DopplerSkyScanInit *init );
117
118const char *va( const char *format, ... ); /* little var-arg string helper function */
119
120/*==================== FUNCTION DEFINITIONS ====================*/
121
122/**
123 * NextDopplerSkyPos(): step through sky-grid
124 * return 0 = OK, -1 = ERROR
125 */
126int
128{
129
130 /* This traps coding errors in the calling routine. */
131 if ( pos == NULL || skyScan == NULL ) {
133 return -1;
134 }
135
136 switch ( skyScan->state ) {
137 case STATE_IDLE:
138 case STATE_FINISHED:
140 return -1;
141 break;
142
143 case STATE_READY:
144 if ( skyScan->skyNode == NULL ) { /* we're done */
145 skyScan->state = STATE_FINISHED;
146 } else {
147 pos->Alpha = skyScan->skyNode->Alpha;
148 pos->Delta = skyScan->skyNode->Delta;
149
150 skyScan->skyNode = skyScan->skyNode->next; /* step forward */
151 }
152 break;
153
154 case STATE_LAST:
155 default:
156 return -1;
157 break;
158
159 } /* switch skyScan->stat */
160
161 return 0;
162
163} /* XLALNextDopplerSkyPos() */
164
165
166/**
167 * Initialize the Doppler sky-scanner
168 */
169int
170XLALInitDopplerSkyScan( DopplerSkyScanState *skyScan, /**< [out] the initialized scan-structure */
171 const DopplerSkyScanInit *init ) /**< [in] init-params */
172{
173 XLAL_CHECK( skyScan != NULL, XLAL_EINVAL );
174 XLAL_CHECK( skyScan->state == STATE_IDLE, XLAL_EINVAL );
176
177 /* trap some abnormal input */
178 if ( ( init->gridType != GRID_FILE_SKYGRID ) && ( init->gridType != GRID_METRIC_SKYFILE ) && ( init->skyRegionString == NULL ) ) {
179 XLAL_ERROR( XLAL_EINVAL, "ERROR: No sky-region was specified!\n\n" );
180 }
181 if ( ( init->gridType == GRID_FILE_SKYGRID ) && ( init->skyGridFile == NULL ) ) {
182 XLAL_ERROR( XLAL_EINVAL, "ERROR: no skyGridFile has been specified!\n\n" );
183 }
184
185 DopplerSkyGrid *node;
186 /* general initializations */
187 skyScan->skyGrid = NULL;
188 skyScan->skyNode = NULL;
189
191
192 XLAL_CHECK( skyScan->skyRegion.numVertices != 2, XLAL_EFAILED, "Anomalous sky region with 2 vertices: allowed are 1 or >= 3\n" );
193
194 switch ( init->gridType ) {
195 case GRID_FLAT: /* flat-grid: constant dAlpha, dDelta */
196 XLAL_CHECK( ( skyScan->skyGrid = buildFlatSkyGrid( &( skyScan->skyRegion ), init->dAlpha, init->dDelta ) ) != NULL, XLAL_EFUNC );
197 break;
198
199 case GRID_ISOTROPIC: /* variant of manual stepping: try to produce an isotropic mesh */
200 XLAL_CHECK( ( skyScan->skyGrid = buildIsotropicSkyGrid( &( skyScan->skyRegion ), init->dAlpha, init->dDelta ) ) != NULL, XLAL_EFUNC );
201 break;
202
203 case GRID_METRIC:
204 XLAL_CHECK( ( skyScan->skyGrid = buildMetricSkyGrid( &( skyScan->skyRegion ), init ) ) != NULL, XLAL_EFUNC );
205 break;
206
209 XLAL_CHECK( ( skyScan->skyGrid = loadSkyGridFile( init->skyGridFile ) ) != NULL, XLAL_EFUNC );
210 break;
211
212 default:
213 XLAL_ERROR( XLAL_EINVAL, "Unknown grid-type `%d`\n\n", init->gridType );
214 break;
215
216 } /* switch (metric) */
217
218 /* extract sky-grid partition 'partitionIndex' if requested */
219 if ( init->numSkyPartitions > 0 ) {
220 DopplerSkyGrid *tmp;
221
222 XLAL_CHECK( ( tmp = XLALEquiPartitionSkygrid( skyScan->skyGrid, init->partitionIndex, init->numSkyPartitions ) ) != NULL, XLAL_EFUNC );
223 freeSkyGrid( skyScan->skyGrid );
224 skyScan->skyGrid = tmp;
225 } /* if numPartitions > 0 */
226
227 /* initialize skygrid-pointer to first node in list */
228 skyScan->skyNode = skyScan->skyGrid;
229
230 /* count number of nodes in our sky-grid */
231 skyScan->numSkyGridPoints = 0;
232 node = skyScan->skyGrid;
233 while ( node ) {
234 skyScan->numSkyGridPoints ++;
235 node = node->next;
236 }
237
238 /* ----------
239 * determine spacings in frequency and spindowns
240 * NOTE: this is only meaningful if these spacings
241 * are sufficiently independent of the phase-parameters
242 * ----------*/
243 {
245 PulsarDopplerParams XLAL_INIT_DECL( gridSpacings );
246
247 gridpoint.Alpha = skyScan->skyGrid->Alpha;
248 gridpoint.Delta = skyScan->skyGrid->Delta;
249
250 XLAL_INIT_MEM( gridpoint.fkdot );
251 gridpoint.fkdot[0] = init->Freq;
252
253 XLAL_CHECK( getGridSpacings( &gridSpacings, gridpoint, init ) == XLAL_SUCCESS, XLAL_EFUNC );
254
255 XLALPrintInfo( "'theoretical' spacings in frequency and spindown: \n" );
256 XLALPrintInfo( "dFreq = %g, df1dot = %g, df2dot = %g, df3dot = %g\n",
257 gridSpacings.fkdot[0], gridSpacings.fkdot[1], gridSpacings.fkdot[2], gridSpacings.fkdot[3] );
258
259 memcpy( skyScan->dfkdot, gridSpacings.fkdot, sizeof( PulsarSpins ) );
260 }
261
262 skyScan->state = STATE_READY;
263
264 /* clean up */
265 return XLAL_SUCCESS;
266
267} // XLALInitDopplerSkyScan()
268
269
270/** \deprecated Use XLALInitDopplerSkyScan() instead.
271 */
272void
273InitDopplerSkyScan( LALStatus *status, /**< pointer to LALStatus structure */
274 DopplerSkyScanState *skyScan, /**< [out] the initialized scan-structure */
275 const DopplerSkyScanInit *init ) /**< [in] init-params */
276{
278
279 XLAL_PRINT_DEPRECATION_WARNING( "XLALInitDopplerSkyScan" );
280
281 if ( XLALInitDopplerSkyScan( skyScan, init ) != XLAL_SUCCESS ) {
283 }
284
285 RETURN( status );
286
287} /* InitDopplerSkyScan() */
288
289
290/**
291 * Destroy the DopplerSkyScanState structure
292 */
293void
295{
296 if ( skyScan == NULL ) {
297 return;
298 }
299
300 if ( skyScan->state == STATE_IDLE ) {
301 return;
302 }
303
304 freeSkyGrid( skyScan->skyGrid );
305
306 skyScan->skyGrid = skyScan->skyNode = NULL;
307
308 if ( skyScan->skyRegion.vertices ) {
309 XLALFree( skyScan->skyRegion.vertices );
310 }
311 skyScan->skyRegion.vertices = NULL;
312
313 skyScan->state = STATE_IDLE;
314
315 return;
316
317} // XLALDestroyDopplerSkyScan()
318
319
320/**
321 * \deprecated Use XLALDestroyDopplerSkyScan() instead.
322 */
323void
325{
327
328 XLAL_PRINT_DEPRECATION_WARNING( "XLALDestroyDopplerSkyScan" );
329
330 XLALDestroyDopplerSkyScan( skyScan );
331
332 RETURN( status );
333
334} /* FreeDopplerSkyScan() */
335
336/*----------------------------------------------------------------------
337 * helper-function: free the linked list containing the grid
338 *----------------------------------------------------------------------*/
339void
341{
342 DopplerSkyGrid *node, *next;
343
344 if ( skygrid == NULL ) {
345 return;
346 }
347
348 node = skygrid;
349
350 while ( node ) {
351 next = node->next;
352 LALFree( node );
353 node = next;
354 } /* while node */
355
356 return;
357} /* freeSkyGrid() */
358
359
360/* **********************************************************************
361 The following 2 helper-functions for TwoDMesh() have been adapted
362 from Ben's PtoleMeshTest.
363
364 NOTE: Currently we are very expicitly restricted to 2D searches!!
365 FIXME: generalize to N-dimensional parameter-searches
366********************************************************************** */
367
368/**
369 * This is the parameter range function as required by TwoDMesh().
370 *
371 * NOTE: for the moment we only provide a trival range as defined by the
372 * rectangular parameter-area [ a1, a2 ] x [ d1, d2 ]
373 *
374 * In order to avoid later cliping of boundary-points only due to numerical
375 * fluctuations, we push the enclosing rectangle boundaries inside
376 * by about EPS~1e-6 [as REAL4-arithmetic is used in TwoDMesh()].
377 *
378 */
379void getRange( LALStatus *status, meshREAL y[2], meshREAL UNUSED x, void *params )
380{
381 SkyRegion *region = ( SkyRegion * )params;
382
383 /* Set up shop. */
385 /* ATTATCHSTATUSPTR( status ); */
386
387 /* for now: we return the fixed y-range, indendent of x */
388 if ( meshOrder == ORDER_ALPHA_DELTA ) {
389 y[0] = region->lowerLeft.latitude + EPS4;
390 y[1] = region->upperRight.latitude - EPS4;
391 } else {
392 y[0] = region->lowerLeft.longitude + EPS4;
393 y[1] = region->upperRight.longitude - EPS4;
394 }
395
396
397 /* Clean up and leave. */
398 /* DETATCHSTATUSPTR( status ); */
399
400 RETURN( status );
401} /* getRange() */
402
403
404/* ----------------------------------------------------------------------
405 * This is a wrapper for the metric function as required by TwoDMesh.
406 *
407 *
408 * NOTE: this will be called by TwoDMesh(), therefore
409 * skypos is in internalOrder, which is not necessarily ORDER_ALPHA_DELTA!!
410 *
411 * NOTE2: this is only using the 2D projected sky-metric !
412 *
413 *----------------------------------------------------------------------*/
414void getMetric( LALStatus *status, meshREAL g[3], meshREAL skypos[2], void *params )
415{
416 REAL8Vector *metric = NULL; /* for output of metric */
418 PtoleMetricIn XLAL_INIT_DECL( metricpar );
419
420 /* Set up shop. */
423
424 /* set up the metric parameters proper (using PtoleMetricIn as container-type) */
425 metricpar.metricType = par->metricType;
426 metricpar.position.system = COORDINATESYSTEM_EQUATORIAL;
427 /* theoretically and empirically it seems that the spindowns
428 * do not influence the sky-metric to a good approximation,
429 * at least for 'physical' values of spindown.
430 * We take this 0 therefore
431 */
432 metricpar.spindown = NULL;
433
434 metricpar.epoch = par->obsBegin;
435 metricpar.duration = par->obsDuration;
436 metricpar.maxFreq = par->Freq;
437 metricpar.site = par->Detector;
438 metricpar.ephemeris = par->ephemeris;
439
440 /* Call the metric function. (Ptole or Coherent, which is handled by wrapper) */
441 if ( meshOrder == ORDER_ALPHA_DELTA ) {
442 metricpar.position.longitude = skypos[0];
443 metricpar.position.latitude = skypos[1];
444 } else {
445 metricpar.position.longitude = skypos[1];
446 metricpar.position.latitude = skypos[0];
447 }
448
449 /* before we call the metric: make sure the sky-position is "normalized" */
450 TRY( LALNormalizeSkyPosition( status->statusPtr, &( metricpar.position ), &( metricpar.position ) ), status );
451
452 TRY( LALPulsarMetric( status->statusPtr, &metric, &metricpar ), status );
453
454 /* project metric if requested */
455 if ( par->projectMetric ) {
456 LALProjectMetric( status->statusPtr, metric, 0 );
457
459 TRY( LALDDestroyVector( status->statusPtr, &metric ), status );
460 ENDFAIL( status );
461 }
462
463 /* Translate output. Careful about the coordinate-order here!! */
464 if ( meshOrder == ORDER_ALPHA_DELTA ) {
465 g[0] = metric->data[INDEX_A_A]; /* gxx */
466 g[1] = metric->data[INDEX_D_D]; /* gyy */
467 } else {
468 g[0] = metric->data[INDEX_D_D]; /* gxx */
469 g[1] = metric->data[INDEX_A_A]; /* gyy */
470 }
471
472 g[2] = metric->data[INDEX_A_D]; /* g12: 1 + 2*(2+1)/2 = 4; */
473
474 /* check positivity */
475 if ( lalDebugLevel ) {
476 REAL8 det = g[0] * g[1] - g[2] * g[2];
477 if ( ( g[0] <= 0 ) || ( g[1] <= 0 ) || ( det <= 0 ) ) {
478 LogPrintf( LOG_CRITICAL, "Negative sky-metric found!\n" );
479 LogPrintf( LOG_CRITICAL, "Skypos = [%16g, %16g],\n\n"
480 "metric = [ %16g, %16g ;\n"
481 " %16g, %16g ],\n\n"
482 "det = %16g\n\n",
483 metricpar.position.longitude, metricpar.position.latitude,
484 metric->data[INDEX_A_A], metric->data[INDEX_A_D],
485 metric->data[INDEX_A_D], metric->data[INDEX_D_D],
486 det );
488 } /* if negative metric */
489 } /* if lalDebugLevel() */
490
491
492 /* Clean up and leave. */
493 TRY( LALDDestroyVector( status->statusPtr, &metric ), status );
494
496 RETURN( status );
497} /* getMetric() */
498
499
500/*----------------------------------------------------------------------
501 * Debug helper for mesh and metric stuff
502 *----------------------------------------------------------------------*/
503#define SPOKES 60 /* spokes for ellipse-plots */
504#define NUM_SPINDOWN 0 /* Number of spindown parameters */
505
506void
508 DopplerSkyGrid *skyGrid,
509 const SkyRegion *region,
510 const DopplerSkyScanInit *init )
511{
512 FILE *fp = NULL; /* output xmgrace-file */
513 FILE *fp1 = NULL; /* output pure data */
514 DopplerSkyGrid *node;
516 UINT4 set, i;
517
518 const CHAR *xmgrHeader =
519 "@version 50103\n"
520 "@title \"Sky-grid\"\n"
521 "@world xmin -0.1\n"
522 "@world xmax 6.4\n"
523 "@world ymin -1.58\n"
524 "@world ymax 1.58\n"
525 "@xaxis label \"Alpha\"\n"
526 "@yaxis label \"Delta\"\n";
527
528 /* Set up shop. */
531
532 fp = fopen( "mesh_debug.agr", "w" );
533 fp1 = fopen( "mesh_debug.dat", "w" );
534
535 if ( !fp ) {
537 }
538
539 fprintf( fp, "%s", xmgrHeader );
540
541 set = 0;
542
543 /* Plot boundary. (if given) */
544 if ( region->vertices ) {
545 fprintf( fp, "@target s%d\n@type xy\n", set );
546
547 for ( i = 0; i < region->numVertices; i++ ) {
548 fprintf( fp, "%e %e\n", region->vertices[i].longitude, region->vertices[i].latitude );
549 fprintf( fp1, "%e %e\n", region->vertices[i].longitude, region->vertices[i].latitude );
550 }
551 /* close contour */
552 fprintf( fp, "%e %e\n", region->vertices[0].longitude, region->vertices[0].latitude );
553 fprintf( fp1, "%e %e\n\n", region->vertices[0].longitude, region->vertices[0].latitude );
554
555 set ++;
556 }
557
558 /* Plot mesh points. */
559 fprintf( fp, "@s%d symbol 9\n@s%d symbol size 0.33\n", set, set );
560 fprintf( fp, "@s%d line type 0\n", set );
561 fprintf( fp, "@target s%d\n@type xy\n", set );
562
563 for ( node = skyGrid; node; node = node->next ) {
564 fprintf( fp, "%e %e\n", node->Alpha, node->Delta );
565 fprintf( fp1, "%e %e\n", node->Alpha, node->Delta );
566 }
567 fprintf( fp1, "\n\n" );
568
569 /* if metric is given: plot ellipses */
570 if ( ( lalDebugLevel >= 5 ) && ( init->metricType > LAL_PMETRIC_NONE ) && ( init->metricType < LAL_PMETRIC_LAST ) ) {
571 REAL8Vector *metric = NULL; /* Parameter-space metric: for plotting ellipses */
572 MetricEllipse ellipse;
574 PtoleMetricIn metricPar;
575
576 set++;
577
578 /* set up the metric parameters common to all sky-points */
580 metricPar.spindown = LALCalloc( 1, sizeof( REAL4Vector ) );
581 metricPar.spindown->length = 0;
582 metricPar.spindown->data = NULL;
583 metricPar.epoch = init->obsBegin;
584 metricPar.duration = init->obsDuration;
585 metricPar.maxFreq = init->Freq;
586 metricPar.site = init->Detector;
587 metricPar.ephemeris = init->ephemeris;
588 metricPar.metricType = init->metricType;
589
590 node = skyGrid;
591 while ( node ) {
592 Alpha = node->Alpha;
593 Delta = node->Delta;
594
595 /* Get the metric at this skypos */
596 /* only need the update the position, the other
597 * parameter have been set already ! */
598 metricPar.position.longitude = Alpha;
599 metricPar.position.latitude = Delta;
600
601 /* make sure we "normalize" point before calling metric */
602 TRY( LALNormalizeSkyPosition( status->statusPtr, &( metricPar.position ),
603 &( metricPar.position ) ), status );
604
605 TRY( LALPulsarMetric( status->statusPtr, &metric, &metricPar ), status );
606
607 if ( init->projectMetric ) {
608 TRY( LALProjectMetric( status->statusPtr, metric, 0 ), status );
609 }
610
611 TRY( getMetricEllipse( status->statusPtr, &ellipse, mismatch, metric, 1 ), status );
612
613 /*
614 printf ("Alpha=%f Delta=%f\ngaa=%f gdd=%f gad=%f\n", Alpha, Delta, gaa, gdd, gad);
615 printf ("smaj = %f, smin = %f angle=%f\n", smaj, smin, angle);
616 */
617 set ++;
618 /* Print set header. */
619 fprintf( fp, "@target G0.S%d\n@type xy\n", set );
620 fprintf( fp, "@s%d color (0,0,0)\n", set );
621
622 /* Loop around patch ellipse. */
623 for ( i = 0; i <= SPOKES; i++ ) {
624 float c, r, b, x, y;
625
626 c = LAL_TWOPI * i / SPOKES;
627 x = ellipse.smajor * cos( c );
628 y = ellipse.sminor * sin( c );
629 r = sqrt( x * x + y * y );
630 b = atan2( y, x );
631 fprintf( fp, "%e %e\n",
632 Alpha + r * cos( ellipse.angle + b ), Delta + r * sin( ellipse.angle + b ) );
633
634 fprintf( fp1, "%e %e\n",
635 Alpha + r * cos( ellipse.angle + b ), Delta + r * sin( ellipse.angle + b ) );
636 }
637 fprintf( fp1, "\n\n" );
638
639 node = node -> next;
640
641 TRY( LALDDestroyVector( status->statusPtr, &metric ), status );
642 metric = NULL;
643
644 } /* while node */
645
646 LALFree( metricPar.spindown );
647
648 } /* if plotEllipses */
649
650 fclose( fp );
651
653 RETURN( status );
654
655} /* plotSkyGrid */
656
657/**
658 * Function for checking if a given point lies inside or outside a given
659 * polygon, which is specified by a list of points in a SkyPositionVector.
660 *
661 * ### Note1: ###
662 *
663 * The list of polygon-points must not close on itself, the last point
664 * is automatically assumed to be connected to the first
665 *
666 * ### Algorithm: ###
667 *
668 * Count the number of intersections of rays emanating to the right
669 * from the point with the lines of the polygon: even => outside, odd => inside
670 *
671 * ### Note2: ###
672 *
673 * we try to get this algorith to count all boundary-points as 'inside'
674 * we do this by counting intersection to the left _AND_ to the right
675 * and consider the point inside if either of those says its inside...
676 *
677 * \return TRUE or FALSE
678 */
680pointInPolygon( const SkyPosition *point, const SkyRegion *polygon )
681{
682 UINT4 i;
683 UINT4 N;
684 UINT4 insideLeft, insideRight;
685 BOOLEAN inside = 0;
686 SkyPosition *vertex;
687 REAL8 xinter, v1x, v1y, v2x, v2y, px, py;
688
689 if ( !point || !polygon || !polygon->vertices || ( polygon->numVertices < 3 ) ) {
690 return 0;
691 }
692
693 vertex = polygon->vertices;
694 N = polygon->numVertices; /* num of vertices = num of edges */
695
696 insideLeft = insideRight = 0;
697
698 px = point->longitude;
699 py = point->latitude;
700
701 for ( i = 0; i < N; i++ ) {
702 v1x = vertex[i].longitude;
703 v1y = vertex[i].latitude;
704 v2x = vertex[( i + 1 ) % N].longitude;
705 v2y = vertex[( i + 1 ) % N].latitude;
706
707 /* pre-select candidate edges */
708 if ( ( py < fmin( v1y, v2y ) ) || ( py >= fmax( v1y, v2y ) ) || ( v1y == v2y ) ) {
709 continue;
710 }
711
712 /* now calculate the actual intersection point of the horizontal ray with the edge in question*/
713 xinter = v1x + ( py - v1y ) * ( v2x - v1x ) / ( v2y - v1y );
714
715 if ( xinter > px ) { /* intersection lies to the right of point */
716 insideLeft ++;
717 }
718
719 if ( xinter < px ) { /* intersection lies to the left of point */
720 insideRight ++;
721 }
722
723 } /* for sides of polygon */
724
725 inside = ( ( ( insideLeft % 2 ) == 1 ) || ( insideRight % 2 ) == 1 );
726 return inside;
727
728} /* pointInPolygon() */
729
730/*----------------------------------------------------------------------
731 * Translate a TwoDMesh into a DopplerSkyGrid using a SkyRegion for clipping
732 *
733 * NOTE: the returned grid will be NULL if there are no points inside the sky-region
734 *----------------------------------------------------------------------*/
736ConvertTwoDMesh2SkyGrid( const meshNODE *mesh2d, /* input: a 2Dmesh */
737 const SkyRegion *region ) /* a sky-region for clipping */
738{
739 const meshNODE *meshpoint;
741 DopplerSkyGrid *node = NULL;
742 SkyPosition point;
743
744 XLAL_CHECK_NULL( region, XLAL_EINVAL );
745 XLAL_CHECK_NULL( mesh2d, XLAL_EINVAL );
746
747 meshpoint = mesh2d; /* this is the 2-d mesh from LALTwoDMesh() */
748
749 node = &head; /* this is our Doppler-grid (empty for now) */
750
751 while ( meshpoint ) {
752 if ( meshOrder == ORDER_ALPHA_DELTA ) {
753 point.longitude = meshpoint->x;
754 point.latitude = meshpoint->y;
755 } else {
756 point.longitude = meshpoint->y;
757 point.latitude = meshpoint->x;
758 }
759
760 if ( pointInPolygon( &point, region ) ) {
761 /* prepare a new node for this point */
762 XLAL_CHECK_NULL( ( node->next = LALCalloc( 1, sizeof( DopplerSkyGrid ) ) ) != NULL, XLAL_ENOMEM );
763 node = node->next;
764
765 node->Alpha = point.longitude;
766 node->Delta = point.latitude;
767
768 } /* if point in polygon */
769 else {
770 XLALPrintInfo( "Point [%g, %g] has been discarded by polygon-clipping!\n", point.longitude, point.latitude );
771 }
772
773 meshpoint = meshpoint->next;
774
775 } /* while meshpoint */
776
777
778 return head.next; /* return the final skygrid (excluding static head) */
779
780} /* ConvertTwoDMesh2SkyGrid() */
781
782
783/*----------------------------------------------------------------------
784 *
785 * make a "flat" grid, i.e. a grid with fixed mesh-sizes dAlpha, dDelta
786 *
787 *----------------------------------------------------------------------*/
789buildFlatSkyGrid( const SkyRegion *skyRegion,
790 REAL8 dAlpha,
791 REAL8 dDelta )
792{
793 XLAL_CHECK_NULL( skyRegion, XLAL_EINVAL );
794 XLAL_CHECK_NULL( ( dAlpha > 0 ) && ( dDelta > 0 ), XLAL_EINVAL );
795
797 DopplerSkyGrid *node = &head;
798
799 BOOLEAN singlePoint = 0;
800 if ( skyRegion->numVertices < 3 ) { /* got no area to cover */
801 singlePoint = 1;
802 }
803
804 SkyPosition thisPoint = skyRegion->lowerLeft; /* start from lower-left corner */
805
806 while ( 1 ) {
807 if ( singlePoint || pointInPolygon( &thisPoint, skyRegion ) ) {
808 /* prepare this node */
809 XLAL_CHECK_NULL( ( node->next = LALCalloc( 1, sizeof( DopplerSkyGrid ) ) ) != NULL, XLAL_ENOMEM );
810 node = node->next;
811
812 node->Alpha = thisPoint.longitude;
813 node->Delta = thisPoint.latitude;
814 } /* if pointInPolygon() */
815
816 thisPoint.latitude += dDelta;
817
818 if ( thisPoint.latitude > skyRegion->upperRight.latitude ) {
819 thisPoint.latitude = skyRegion->lowerLeft.latitude;
820 thisPoint.longitude += dAlpha;
821 }
822
823 /* this it the break-condition: are we done yet? */
824 if ( thisPoint.longitude >= skyRegion->upperRight.longitude + dAlpha ) {
825 break;
826 }
827
828 } /* while(1) */
829
830 return head.next;
831
832} /* buildFlatSkyGrid */
833
834
835/*----------------------------------------------------------------------
836 *
837 * (approx.) isotropic grid with cells of fixed solid-angle dAlpha x dDelta
838 *
839 *----------------------------------------------------------------------*/
841buildIsotropicSkyGrid( const SkyRegion *skyRegion, REAL8 dAlpha, REAL8 dDelta )
842{
843 XLAL_CHECK_NULL( skyRegion != NULL, XLAL_EINVAL );
844
845 SkyPosition thisPoint;
847 DopplerSkyGrid *node = NULL;
848 REAL8 step_Alpha, step_Delta, cos_Delta;
849
850 BOOLEAN singlePoint = 0;
851 if ( skyRegion->numVertices < 3 ) { /* got no area to cover */
852 singlePoint = 1;
853 }
854
855 thisPoint = skyRegion->lowerLeft; /* start from lower-left corner */
856
857 step_Delta = dDelta; /* Delta step-size is fixed */
858 cos_Delta = fabs( cos( thisPoint.latitude ) );
859
860 node = &head; /* start our grid with an empty head */
861
862 while ( 1 ) {
863 if ( singlePoint || pointInPolygon( &thisPoint, skyRegion ) ) {
864 /* prepare this node */
865 XLAL_CHECK_NULL( ( node->next = LALCalloc( 1, sizeof( DopplerSkyGrid ) ) ) != NULL, XLAL_ENOMEM );
866 node = node->next;
867
868 node->Alpha = thisPoint.longitude;
869 node->Delta = thisPoint.latitude;
870 } /* if pointInPolygon() */
871
872 step_Alpha = dAlpha / cos_Delta; /* Alpha stepsize depends on Delta */
873
874 thisPoint.longitude += step_Alpha;
875 if ( thisPoint.longitude > skyRegion->upperRight.longitude ) {
876 thisPoint.longitude = skyRegion->lowerLeft.longitude;
877 thisPoint.latitude += step_Delta;
878 cos_Delta = fabs( cos( thisPoint.latitude ) );
879 }
880
881 /* this it the break-condition: are we done yet? */
882 if ( thisPoint.latitude > skyRegion->upperRight.latitude ) {
883 break;
884 }
885
886 } /* while(1) */
887
888 return head.next;
889
890} /* buildIsotropicSkyGrid() */
891
892/**
893 * Build the skygrid using a specified metric.
894 *
895 * \note: first we cover the enclosing rectange of the skyRegion
896 * using the metric-covering code, then we clip out the actual
897 * polygon-skyRegion using pointInPolygon().
898 *
899 * In order for this not to clip boundary-points only due to numerical
900 * fluctuations, we push the enclosing rectangle boundaries inside
901 * by about EPS~1e-6 [as REAL4-arithmetic is used in TwoDMesh()].
902 *
903 */
906 const DopplerSkyScanInit *init )
907{
908 XLAL_CHECK_NULL( skyRegion, XLAL_EINVAL );
910
911 meshNODE *mesh2d = NULL;
912 meshPARAMS XLAL_INIT_DECL( meshpar );
913 PtoleMetricIn XLAL_INIT_DECL( metricpar );
914 DopplerSkyScanInit params = ( *init );
915 DopplerSkyGrid *skyGrid = NULL;
916
917 if ( skyRegion->numVertices < 3 ) { /* got no surface to cover */
918 XLAL_CHECK_NULL( ( skyGrid = LALCalloc( 1, sizeof( DopplerSkyGrid ) ) ) != NULL, XLAL_ENOMEM );
919 skyGrid->Alpha = skyRegion->lowerLeft.longitude;
920 skyGrid->Delta = skyRegion->lowerLeft.latitude;
921 goto done;
922 }
923
924 /* some general mesh-settings are needed in metric case */
925 meshpar.getRange = getRange;
926
927 if ( meshOrder == ORDER_ALPHA_DELTA ) {
928 meshpar.domain[0] = skyRegion->lowerLeft.longitude + EPS4;
929 meshpar.domain[1] = skyRegion->upperRight.longitude - EPS4;
930 } else {
931 meshpar.domain[0] = skyRegion->lowerLeft.latitude + EPS4;
932 meshpar.domain[1] = skyRegion->upperRight.latitude - EPS4;
933 }
934
935 meshpar.rangeParams = ( void * ) skyRegion;
936
937 /* Prepare call of TwoDMesh(): the mesh-parameters */
938 meshpar.mThresh = init->metricMismatch;
939 meshpar.nIn = 1e8; /* maximum nodes in mesh */ /* FIXME: hardcoded */
940
941 /* helper-function: range and metric */
942 meshpar.getMetric = getMetric;
943 /* and its parameters: simply pass the whole DopplerSkyScanInit struct, which
944 * contains all the required information
945 */
946 meshpar.metricParams = ( void * )( &params );
947
948 /* finally: create the mesh! (ONLY 2D for now!) */
950 LALCreateTwoDMesh( &status, &mesh2d, &meshpar );
951 XLAL_CHECK_NULL( status.statusCode == 0, XLAL_EFAILED, "LAL function LALCreateTwoDMesh() failed with statusCode = %d\n", status.statusCode );
952
953 if ( metricpar.spindown ) {
954 /* FIXME: this is currently broken in LAL, as length=0 is not allowed */
955 /* TRY (LALSDestroyVector ( status->statusPtr, &(skyScan->MetricPar.spindown) ), status); */
956 XLALFree( metricpar.spindown );
957 metricpar.spindown = NULL;
958 }
959
960 /* convert this 2D-mesh into our skygrid-structure, including clipping to the skyRegion */
961 if ( mesh2d ) {
962 XLAL_CHECK_NULL( ( skyGrid = ConvertTwoDMesh2SkyGrid( mesh2d, skyRegion ) ) != NULL, XLAL_EFUNC );
963 }
964
965 /* get rid of 2D-mesh */
966 LALDestroyTwoDMesh( &status, &mesh2d, 0 );
967 XLAL_CHECK_NULL( status.statusCode == 0, XLAL_EFAILED, "LAL function LALDestroyTwoDMesh() failed with statusCode = %d\n", status.statusCode );
968
969done:
970 return skyGrid;
971
972} /* buildMetricSkyGrid() */
973
974
975/**
976 * Load skygrid from file, clipped to searchRegion.
977 */
980 )
981{
983
984 LALParsedDataFile *data = NULL;
985 DopplerSkyGrid *node;
987 UINT4 i;
988 SkyPosition XLAL_INIT_DECL( thisPoint );
989
991
992 thisPoint.system = COORDINATESYSTEM_EQUATORIAL;
993
994 /* parse this list of lines into a sky-grid */
995 node = &head; /* head will remain empty! */
996 for ( i = 0; i < data->lines->nTokens; i++ ) {
997 if ( 2 != sscanf( data->lines->tokens[i], "%" LAL_REAL8_FORMAT "%" LAL_REAL8_FORMAT,
998 &( thisPoint.longitude ), &( thisPoint.latitude ) ) ) {
999 XLAL_ERROR_NULL( XLAL_EINVAL, "ERROR: could not parse line %d in skyGrid-file '%s'\n\n", i, fname );
1000 }
1001 /* if (pointInPolygon (&thisPoint, region) ) { */
1002 /* prepare new list-entry */
1003 XLAL_CHECK_NULL( ( node->next = LALCalloc( 1, sizeof( DopplerSkyGrid ) ) ) != NULL, XLAL_ENOMEM );
1004 node = node->next;
1005 node->Alpha = thisPoint.longitude;
1006 node->Delta = thisPoint.latitude;
1007 /* } */ /* if pointInPolygon() */
1008
1009 } /* for i < nLines */
1010
1012
1013 return head.next;
1014
1015} /* loadSkyGridFile() */
1016
1017/**
1018 * Write the given sky-grid to a file.
1019 * Possibly including some comments containing the parameters of the grid (?).
1020 *
1021 */
1022void
1024 const DopplerSkyGrid *skyGrid,
1025 const CHAR *fname )
1026{
1027 FILE *fp;
1028 const DopplerSkyGrid *node;
1029
1030 INITSTATUS( status );
1032
1035
1036 if ( ( fp = fopen( fname, "w" ) ) == NULL ) {
1037 LogPrintf( LOG_CRITICAL, "ERROR: could not open %s for writing!\n", fname );
1039 }
1040
1041 node = skyGrid;
1042 while ( node ) {
1043 fprintf( fp, "%15.9f %+15.9f \n", node->Alpha, node->Delta );
1044 node = node->next;
1045 }
1046
1047 fclose( fp );
1048
1050 RETURN( status );
1051
1052} /* writeSkyGridFile() */
1053
1054/*----------------------------------------------------------------------
1055 *
1056 * write predicted frequency-shift of Fmax as function of sky-position
1057 *
1058 *----------------------------------------------------------------------*/
1059void
1061{
1062 FILE *fp;
1063 const CHAR *fname = "dFreq.pred";
1064 const DopplerSkyGrid *node = NULL;
1065
1066 REAL8 v[3], a[3];
1067 REAL8 np[3];
1068 REAL8 fact;
1069 REAL8 *vel;
1070 REAL8 *acc;
1071 REAL8 t0e; /*time since first entry in Earth ephem. table */
1072 INT4 ientryE; /*entry in look-up table closest to current time, tGPS */
1073
1074 REAL8 tinitE; /*time (GPS) of first entry in Earth ephem table*/
1075 REAL8 tdiffE; /*current time tGPS minus time of nearest entry
1076 in Earth ephem look-up table */
1077 REAL8 tgps[2];
1078 const EphemerisData *edat = init->ephemeris;
1079 UINT4 j;
1080 REAL8 accDot[3];
1081 REAL8 Tobs, dT;
1082 REAL8 V0[3], V1[3], V2[3];
1083
1084 INITSTATUS( status );
1086
1087 if ( ( fp = fopen( fname, "w" ) ) == NULL ) {
1088 LogPrintf( LOG_CRITICAL, "ERROR: could not open %s for writing!\n", fname );
1090 }
1091
1092 /* get detector velocity */
1093 Tobs = init->obsDuration;
1094
1095 tgps[0] = ( REAL8 )( init->obsBegin.gpsSeconds );
1096 tgps[1] = ( REAL8 )( init->obsBegin.gpsNanoSeconds );
1097
1098 tinitE = edat->ephemE[0].gps;
1099 dT = edat->dtEtable;
1100 t0e = tgps[0] - tinitE;
1101 ientryE = floor( ( t0e / dT ) + 0.5e0 ); /*finding Earth table entry closest to arrival time*/
1102
1103 /* tdiff is arrival time minus closest Earth table entry; tdiff can be pos. or neg. */
1104 tdiffE = t0e - edat->dtEtable * ientryE + tgps[1] * 1.e-9;
1105
1106
1107 vel = edat->ephemE[ientryE].vel;
1108 acc = edat->ephemE[ientryE].acc;
1109
1110 /* interpolate v, a to the actual start-time */
1111 for ( j = 0; j < 3; j++ ) {
1112 accDot[j] = ( edat->ephemE[ientryE + 1].acc[j] - edat->ephemE[ientryE].acc[j] ) / dT;
1113 v[j] = vel[j] + acc[j] * tdiffE + 0.5 * accDot[j] * tdiffE * tdiffE;
1114 a[j] = acc[j] + accDot[j] * tdiffE;
1115 }
1116
1117
1118 /* calculate successively higher order-expressions for V */
1119 for ( j = 0; j < 3; j++ ) {
1120 V0[j] = v[j]; /* 0th order */
1121 V1[j] = v[j] + 0.5 * a[j] * Tobs; /* 1st order */
1122 V2[j] = v[j] + 0.5 * a[j] * Tobs + ( 2.0 / 5.0 ) * accDot[j] * Tobs * Tobs; /* 2nd order */
1123 }
1124
1125 XLALPrintError( "dT = %f, tdiffE = %f, Tobs = %f\n", dT, tdiffE, Tobs );
1126 XLALPrintError( " vel = [ %g, %g, %g ]\n", vel[0], vel[1], vel[2] );
1127 XLALPrintError( " acc = [ %g, %g, %g ]\n", acc[0], acc[1], acc[2] );
1128 XLALPrintError( " accDot = [ %g, %g, %g ]\n\n", accDot[0], accDot[1], accDot[2] );
1129
1130 XLALPrintError( " v = [ %g, %g, %g ]\n", v[0], v[1], v[2] );
1131 XLALPrintError( " a = [ %g, %g, %g ]\n", a[0], a[1], a[2] );
1132
1133 XLALPrintError( "\nVelocity-expression in circle-equation: \n" );
1134 XLALPrintError( " V0 = [ %g, %g, %g ]\n", V0[0], V0[1], V0[2] );
1135 XLALPrintError( " V1 = [ %g, %g, %g ]\n", V1[0], V1[1], V1[2] );
1136 XLALPrintError( " V2 = [ %g, %g, %g ]\n", V2[0], V2[1], V2[2] );
1137
1138 node = skyScan->skyGrid;
1139
1140 while ( node ) {
1141 np[0] = cos( node->Delta ) * cos( node->Alpha );
1142 np[1] = cos( node->Delta ) * sin( node->Alpha );
1143 np[2] = sin( node->Delta );
1144
1145 fact = 1.0 / ( 1.0 + np[0] * v[0] + np[1] * v[1] + np[2] * v[2] );
1146
1147 fprintf( fp, "%.7f %.7f %.7f\n", node->Alpha, node->Delta, fact );
1148
1149 node = node->next;
1150 } /* while grid-points */
1151
1152
1153
1154 fclose( fp );
1155
1157 RETURN( status );
1158
1159} /* printFrequencyShifts() */
1160
1161
1162/**
1163 * some temp test-code outputting the maximal possible dopper-shift
1164 * |vE| + |vS| over the ephemeris
1165 */
1166REAL8
1168{
1169#define mymax(a,b) ((a) > (b) ? (a) : (b))
1170 UINT4 i;
1171 REAL8 maxvE, maxvS;
1172 REAL8 *vel, beta;
1173
1174 maxvE = 0;
1175 for ( i = 0; i < ( UINT4 )edat->nentriesE; i++ ) {
1176 vel = edat->ephemE[i].vel;
1177 beta = sqrt( vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] );
1178 maxvE = mymax( maxvE, beta );
1179 }
1180
1181 maxvS = 0;
1182 for ( i = 0; i < ( UINT4 )edat->nentriesS; i++ ) {
1183 vel = edat->ephemS[i].vel;
1184 beta = sqrt( vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] );
1185 maxvS = mymax( maxvS, beta );
1186 }
1187
1188 XLALPrintError( "Maximal Doppler-shift to be expected from ephemeris: %e", maxvE + maxvS );
1189
1190 return ( maxvE + maxvS );
1191
1192} /* getDopplermax() */
1193
1194
1195/**
1196 * parse a skyRegion-string into a SkyRegion structure: the expected string-format is
1197 * " (longitude1, latitude1), (longitude2, latitude2), (longitude3, latitude3), ... "
1198 *
1199 * If input == NULL or input == "allsky":==> sky-region covering the whole sky.
1200 *
1201 */
1202int
1204{
1205 XLAL_CHECK( region != NULL, XLAL_EINVAL );
1206 XLAL_CHECK( region->vertices == NULL, XLAL_EINVAL );
1207
1208 const CHAR *skyRegion = NULL;
1209
1210 if ( input == NULL ) { // default is 'allsky'
1211 skyRegion = SKYREGION_ALLSKY;
1212 } else if ( !strcmp( input, "allsky" ) || !strcmp( input, "ALLSKY" ) || !strcmp( input, "Allsky" ) ) {
1213 skyRegion = SKYREGION_ALLSKY;
1214 } else {
1215 skyRegion = input;
1216 }
1217
1218 /* count number of entries (by # of opening parantheses) */
1219 region->numVertices = 0;
1220 const CHAR *pos = skyRegion;
1221 while ( ( pos = strchr( pos, '(' ) ) != NULL ) {
1222 region->numVertices ++;
1223 pos ++;
1224 }
1225
1226 XLAL_CHECK( region->numVertices != 0, XLAL_EINVAL, "Failed to parse sky-region: '%s'\n", skyRegion );
1227
1228 /* allocate list of vertices */
1229 XLAL_CHECK( ( region->vertices = XLALMalloc( region->numVertices * sizeof( SkyPosition ) ) ) != NULL, XLAL_ENOMEM );
1230
1231 region->lowerLeft.longitude = LAL_TWOPI;
1232 region->lowerLeft.latitude = LAL_PI / 2.0;
1233
1234 region->upperRight.longitude = 0;
1235 region->upperRight.latitude = -LAL_PI / 2;
1237
1238 char buf[256];
1239 /* and parse list of vertices from input-string */
1240 pos = skyRegion;
1241 for ( UINT4 i = 0; i < region->numVertices; i++ ) {
1243 const char *startLong, *comma, *startLat, *end;
1244 XLAL_CHECK( ( startLong = strchr( pos, '(' ) ) != NULL, XLAL_EINVAL, "Invalid skyregion format at '%s': no opening '('\n", pos );
1245 XLAL_CHECK( ( comma = strchr( pos, ',' ) ) != NULL, XLAL_EINVAL, "Invalid skyregion format at '%s': no comma separator ','\n", pos );
1246 XLAL_CHECK( ( end = strchr( pos, ')' ) ) != NULL, XLAL_EINVAL, "Invalid skyregion format at '%s': no closing ')'\n", pos );
1247
1248 startLong ++;
1249 startLat = comma + 1;
1250
1251 while ( isspace( startLong[0] ) ) {
1252 startLong ++; // skip initial whitespace in longitude string
1253 }
1254 while ( isspace( startLat[0] ) ) {
1255 startLat ++; // skip initial whitespace in latitude string
1256 }
1257
1258 size_t lenLong = comma - startLong;
1259 size_t lenLat = end - startLat;
1260
1261 XLAL_CHECK( lenLong < sizeof( buf ), XLAL_EINVAL, "Element at '%s' exceeds buffer length %zd\n", startLong, sizeof( buf ) );
1262 XLAL_CHECK( lenLat < sizeof( buf ), XLAL_EINVAL, "Element at '%s' exceeds buffer length %zd\n", startLat, sizeof( buf ) );
1263
1264 // parse longitude
1265 memcpy( buf, startLong, lenLong );
1266 buf[lenLong] = 0;
1268
1269 // parse latitude
1270 memcpy( buf, startLat, lenLat );
1271 buf[lenLat] = 0;
1273
1274 /* keep track of min's and max's to get the bounding square */
1275 region->lowerLeft.longitude = fmin( region->lowerLeft.longitude, region->vertices[i].longitude );
1276 region->lowerLeft.latitude = fmin( region->lowerLeft.latitude, region->vertices[i].latitude );
1277
1278 region->upperRight.longitude = fmax( region->upperRight.longitude, region->vertices[i].longitude );
1279 region->upperRight.latitude = fmax( region->upperRight.latitude, region->vertices[i].latitude );
1280
1281 pos = strchr( pos + 1, '(' );
1282
1283 } /* for numVertices */
1284
1285 return XLAL_SUCCESS;
1286
1287} /* XLALParseSkyRegionString() */
1288
1289/*----------------------------------------------------------------------*/
1290/**
1291 * parse a 'classical' sky-square (Alpha, Delta, AlphaBand, DeltaBand) into a
1292 * "SkyRegion"-string of the form '(a1,d1), (a2,d2),...'
1293 */
1294CHAR *
1295XLALSkySquare2String( REAL8 Alpha, /**< [in] longitude of first point */
1296 REAL8 Delta, /**< [in] latitude of first point */
1297 REAL8 AlphaBand, /**< [in] longitude-interval */
1298 REAL8 DeltaBand /**< [in] latitude-interval */
1299 )
1300{
1301 /* consistency check either one single point or a real 2D region! */
1302 BOOLEAN onePoint = ( AlphaBand == 0 ) && ( DeltaBand == 0 );
1303 BOOLEAN region2D = ( AlphaBand != 0 ) && ( DeltaBand != 0 );
1304
1305 XLAL_CHECK_NULL( ( onePoint || region2D ), XLAL_EINVAL, "Need either single point or real 2D region\n" );
1306
1307 REAL8 Da = AlphaBand;
1308 REAL8 Dd = DeltaBand;
1309
1310 /* enough memory for max 4 points... */
1311 CHAR buf[256];
1312
1313 if ( onePoint ) {
1314 sprintf( buf, "(%.16g, %.16g)", Alpha, Delta );
1315 } else { /* or a 2D rectangle */
1316 sprintf( buf,
1317 "(%.16g, %.16g), (%.16g, %.16g), (%.16g, %.16g), (%.16g, %.16g)",
1318 Alpha, Delta,
1319 Alpha + Da, Delta,
1320 Alpha + Da, Delta + Dd,
1321 Alpha, Delta + Dd );
1322 }
1323
1324 /* make tight-fitting string */
1325 CHAR *ret;
1326 XLAL_CHECK_NULL( ( ret = XLALStringDuplicate( buf ) ) != NULL, XLAL_EFUNC );
1327
1328 return ret;
1329
1330} // XLALSkySquare2String()
1331
1332/*----------------------------------------------------------------------*/
1333/**
1334 * determine the 'canonical' stepsizes in all parameter-space directions,
1335 * either from the metric (if --gridType==GRID_METRIC) or using {dAlpha,dDelta}
1336 * and rough guesses dfkdot=1/T^{k+1} otherwise
1337 *
1338 * In the metric case, the metric is evaluated at the given gridpoint.
1339 *
1340 * NOTE: currently only 1 spindown is supported!
1341 */
1342int
1343getGridSpacings( PulsarDopplerParams *spacings, /**< OUT: grid-spacings in gridpoint */
1344 PulsarDopplerParams gridpoint, /**< IN: gridpoint to get spacings for*/
1345 const DopplerSkyScanInit *params ) /**< IN: Doppler-scan parameters */
1346{
1347 XLAL_CHECK( params != NULL, XLAL_EINVAL );
1348 XLAL_CHECK( spacings != NULL, XLAL_EINVAL );
1349
1350 REAL8Vector *metric = NULL;
1351 REAL8 g_f0_f0 = 0, gamma_f1_f1 = 0, gamma_a_a, gamma_d_d;
1352 PtoleMetricIn XLAL_INIT_DECL( metricpar );
1353 UINT4 s;
1354
1355 if ( ( params->gridType == GRID_METRIC ) || ( params->gridType == GRID_METRIC_SKYFILE ) ) { /* use the metric to fix f0/fdot stepsizes */
1356 /* setup metric parameters */
1357 metricpar.position.system = COORDINATESYSTEM_EQUATORIAL;
1358 metricpar.position.longitude = gridpoint.Alpha;
1359 metricpar.position.latitude = gridpoint.Delta;
1360
1361 XLAL_CHECK( ( metricpar.spindown = XLALCreateREAL4Vector( 1 ) ) != NULL, XLAL_EFUNC );
1362 /* !!NOTE!!: in the metric-codes, the spindown f1 is defined as
1363 * f1 = f1dot / Freq, while here f1dot = d Freq/dt
1364 */
1365 metricpar.spindown->data[0] = gridpoint.fkdot[1] / gridpoint.fkdot[0];
1366
1367 metricpar.epoch = params->obsBegin;
1368 metricpar.duration = params->obsDuration;
1369 metricpar.maxFreq = gridpoint.fkdot[0];
1370 metricpar.site = params->Detector;
1371 metricpar.ephemeris = params->ephemeris; /* needed for ephemeris-metrics */
1372 metricpar.metricType = params->metricType;
1373
1374 XLALNormalizeSkyPosition( &metricpar.position.longitude, &metricpar.position.latitude );
1375
1377 LALPulsarMetric( &status, &metric, &metricpar );
1378 XLAL_CHECK( status.statusCode == 0, XLAL_EFAILED, "LAL function LALPulsarMetric() failed with lalStatusCode = %d\n", status.statusCode );
1379 XLALDestroyREAL4Vector( metricpar.spindown );
1380
1381 g_f0_f0 = metric->data[INDEX_f0_f0];
1382
1383 /* NOTE: for simplicity we use params->mismatch, instead of mismatch/D
1384 * where D is the number of parameter-space dimensions
1385 * as in the case of spindown this would require adapting the
1386 * sky-mismatch too.
1387 * Instead, the user has to adapt 'mismatch' corresponding to
1388 * the number of dimensions D in the parameter-space considered.
1389 */
1390
1391 spacings->fkdot[0] = 2.0 * sqrt( params->metricMismatch / g_f0_f0 );
1392
1393 if ( params->projectMetric ) {
1395 XLAL_CHECK( status.statusCode == 0, XLAL_EFAILED, "LAL function LALProjectMetric() failed with lalStatusCode = %d\n", status.statusCode );
1396 }
1397
1398 gamma_f1_f1 = metric->data[INDEX_f1_f1];
1399 spacings->fkdot[1] = 2.0 * gridpoint.fkdot[0] * sqrt( params->metricMismatch / gamma_f1_f1 );
1400 /* FIXME: metric spin-spacings would be better */
1401 for ( s = 2; s < PULSAR_MAX_SPINS; s++ ) {
1402 spacings->fkdot[s] = 1; /* non-zero defaults for remaining spin-steps (avoid div by 0 ) */
1403 }
1404
1405 gamma_a_a = metric->data[INDEX_A_A];
1406 gamma_d_d = metric->data[INDEX_D_D];
1407
1408 spacings->Alpha = 2.0 * sqrt( params->metricMismatch / gamma_a_a );
1409 spacings->Delta = 2.0 * sqrt( params->metricMismatch / gamma_d_d );
1410
1412 metric = NULL;
1413 } else { /* no metric: use 'naive' value of 1/(2*T^(k+1)) [previous default in CFS] */
1414 REAL8 Tobs = params->obsDuration;
1415 REAL8 Tobs_s = Tobs; /* start-value */
1416 spacings->Alpha = params->dAlpha; /* dummy */
1417 spacings->Delta = params->dDelta;
1418 for ( s = 0; s < PULSAR_MAX_SPINS; s ++ ) {
1419 spacings->fkdot[s] = 1.0 / ( 2.0 * Tobs_s );
1420 Tobs_s *= Tobs;
1421 }
1422 }
1423
1424 return XLAL_SUCCESS;
1425
1426} /* getGridSpacings() */
1427
1428/*----------------------------------------------------------------------*/
1429/**
1430 * get "metric-ellipse" for given metric.
1431 * \note This function uses only 2 dimensions starting from dim0 of the given metric!
1432 */
1433void
1435 MetricEllipse *ellipse,
1437 const REAL8Vector *metric,
1438 UINT4 dim0 )
1439{
1440
1441 REAL8 gaa, gad, gdd;
1442 REAL8 smin, smaj, angle;
1443
1444 INITSTATUS( status );
1445
1447
1448 UINT4 dim = dim0 + 2;
1449 if ( !( metric->length >= dim * ( dim + 1 ) / 2 ) ) {
1451 }
1452
1453 gaa = metric->data[ PMETRIC_INDEX( dim0 + 0, dim0 + 0 ) ];
1454 gad = metric->data[ PMETRIC_INDEX( dim0 + 0, dim0 + 1 ) ];
1455 gdd = metric->data[ PMETRIC_INDEX( dim0 + 1, dim0 + 1 ) ];
1456
1457 /* Semiminor axis from larger eigenvalue of metric. */
1458 smin = gaa + gdd + sqrt( pow( gaa - gdd, 2 ) + pow( 2 * gad, 2 ) );
1459 smin = sqrt( 2.0 * mismatch / smin );
1460
1461 /* Semimajor axis from smaller eigenvalue of metric. */
1462 smaj = gaa + gdd - sqrt( pow( gaa - gdd, 2 ) + pow( 2 * gad, 2 ) );
1463 smaj = sqrt( 2.0 * mismatch / smaj );
1464
1465 /* Angle of semimajor axis with "horizontal" (equator). */
1466 angle = atan2( gad, mismatch / smaj / smaj - gdd );
1467 if ( angle <= -LAL_PI_2 ) {
1468 angle += LAL_PI;
1469 }
1470 if ( angle > LAL_PI_2 ) {
1471 angle -= LAL_PI;
1472 }
1473
1474 ellipse->smajor = smaj;
1475 ellipse->sminor = smin;
1476 ellipse->angle = angle;
1477
1478 RETURN( status );
1479
1480} /* getMetricEllipse() */
1481
1482/** Debug-output of PulsarDopplerParams struct */
1483int
1485{
1486 UINT4 s;
1487 if ( !fp || !params ) {
1488 return -1;
1489 }
1490
1491 fprintf( fp, " sky = {%f, %f}, ", params->Alpha, params->Delta );
1492
1493 fprintf( fp, "fkdot = { %f ", params->fkdot[0] );
1494 for ( s = 1; s < PULSAR_MAX_SPINS; s ++ ) {
1495 fprintf( fp, ", %g", params->fkdot[s] );
1496 }
1497
1498 fprintf( fp, "}\n" );
1499
1500 return 0;
1501} /* printfDopplerParams() */
1502
1503/**
1504 * Equi-partition (approximately) a given skygrid into numPartitions, and return
1505 * partition 0<= partitionIndex < numPartitions
1506 */
1508XLALEquiPartitionSkygrid( const DopplerSkyGrid *skygrid, UINT4 partitionIndex, UINT4 numPartitions )
1509{
1510 UINT4 Nsky, Nt, dp;
1511 UINT4 iMin, numPoints;
1512 UINT4 counter;
1513 const DopplerSkyGrid *node;
1514 DopplerSkyGrid *newNode;
1515 DopplerSkyGrid XLAL_INIT_DECL( newGrid );
1516
1517 if ( !skygrid || ( numPartitions == 0 ) || ( partitionIndex >= numPartitions ) ) {
1519 }
1520
1521
1522 /* ----- count total sky-grid */
1523 Nsky = 1;
1524 node = skygrid;
1525 while ( ( node = node->next ) != NULL ) {
1526 Nsky ++;
1527 }
1528
1529 if ( Nsky < numPartitions ) {
1531 }
1532
1533 /* ----- determine integer equi-patitions (+/- 1) */
1534 Nt = Nsky / numPartitions; /* integer division! */
1535 dp = Nsky - numPartitions * Nt; /* dp = Nsky mod P : 0 <= dp < P */
1536
1537 /* first point in partion partitionIndex */
1538 iMin = fmin( partitionIndex, dp ) * ( Nt + 1 ) + fmax( 0, ( ( INT4 )partitionIndex - ( INT4 )dp ) ) * Nt;
1539 numPoints = ( partitionIndex < dp ) ? ( Nt + 1 ) : Nt ; /* number of points in partition partitionIndex */
1540
1541 /* ----- generate skygrid patch partitionIndex */
1542
1543 /* spool forward to sky-grid point iMin */
1544 counter = iMin;
1545 node = skygrid;
1546 while ( counter -- ) { /* test, then decrement! */
1547 node = node->next;
1548 }
1549
1550 /* create new skygrid list for partition j */
1551 newNode = &newGrid; /* head remains empty! */
1552 while ( numPoints -- ) { /* test, then decrement! */
1553 /* create next node */
1554 if ( ( newNode->next = LALCalloc( 1, sizeof( DopplerSkyGrid ) ) ) == NULL ) {
1555 freeSkyGrid( newGrid.next );
1557 }
1558 newNode = newNode->next;
1559
1560 newNode->Alpha = node->Alpha;
1561 newNode->Delta = node->Delta;
1562
1563 node = node->next;
1564
1565 } /* while numPoints */
1566
1567 /* return new skygrid-list proper [head stayed empty!] */
1568 return newGrid.next;
1569
1570
1571} /* XLALEquiPartitionSkygrid() */
BOOLEAN pointInPolygon(const SkyPosition *point, const SkyRegion *polygon)
Function for checking if a given point lies inside or outside a given polygon, which is specified by ...
Definition: DopplerScan.c:680
static int meshOrder
Definition: DopplerScan.c:90
#define INDEX_f0_f0
Definition: DopplerScan.c:56
REAL4 meshREAL
Definition: DopplerScan.c:92
int fprintfDopplerParams(FILE *fp, const PulsarDopplerParams *params)
Debug-output of PulsarDopplerParams struct.
Definition: DopplerScan.c:1484
void InitDopplerSkyScan(LALStatus *status, DopplerSkyScanState *skyScan, const DopplerSkyScanInit *init)
Definition: DopplerScan.c:273
DopplerSkyGrid * buildIsotropicSkyGrid(const SkyRegion *skyRegion, REAL8 dAlpha, REAL8 dDelta)
Definition: DopplerScan.c:841
void FreeDopplerSkyScan(LALStatus *status, DopplerSkyScanState *skyScan)
Definition: DopplerScan.c:324
REAL8 getDopplermax(EphemerisData *edat)
some temp test-code outputting the maximal possible dopper-shift |vE| + |vS| over the ephemeris
Definition: DopplerScan.c:1167
void printFrequencyShifts(LALStatus *, const DopplerSkyScanState *skyScan, const DopplerSkyScanInit *init)
Definition: DopplerScan.c:1060
void writeSkyGridFile(LALStatus *status, const DopplerSkyGrid *skyGrid, const CHAR *fname)
Write the given sky-grid to a file.
Definition: DopplerScan.c:1023
void getMetric(LALStatus *, meshREAL g[3], meshREAL skypos[2], void *params)
Definition: DopplerScan.c:414
int XLALParseSkyRegionString(SkyRegion *region, const CHAR *input)
parse a skyRegion-string into a SkyRegion structure: the expected string-format is " (longitude1,...
Definition: DopplerScan.c:1203
DopplerSkyGrid * buildFlatSkyGrid(const SkyRegion *region, REAL8 dAlpha, REAL8 dDelta)
Definition: DopplerScan.c:789
CHAR * XLALSkySquare2String(REAL8 Alpha, REAL8 Delta, REAL8 AlphaBand, REAL8 DeltaBand)
parse a 'classical' sky-square (Alpha, Delta, AlphaBand, DeltaBand) into a "SkyRegion"-string of the ...
Definition: DopplerScan.c:1295
void freeSkyGrid(DopplerSkyGrid *skygrid)
Definition: DopplerScan.c:340
TwoDMeshNode meshNODE
Definition: DopplerScan.c:93
void getMetricEllipse(LALStatus *status, MetricEllipse *ellipse, REAL8 mismatch, const REAL8Vector *metric, UINT4 dim0)
get "metric-ellipse" for given metric.
Definition: DopplerScan.c:1434
#define INDEX_A_D
Definition: DopplerScan.c:63
DopplerSkyGrid * buildMetricSkyGrid(SkyRegion *skyRegion, const DopplerSkyScanInit *init)
Build the skygrid using a specified metric.
Definition: DopplerScan.c:905
#define INDEX_f1_f1
Definition: DopplerScan.c:68
TwoDMeshParamStruc meshPARAMS
Definition: DopplerScan.c:94
DopplerSkyGrid * loadSkyGridFile(const CHAR *fname)
Load skygrid from file, clipped to searchRegion.
Definition: DopplerScan.c:979
void getRange(LALStatus *, meshREAL y[2], meshREAL x, void *params)
void plotSkyGrid(LALStatus *, DopplerSkyGrid *skygrid, const SkyRegion *region, const DopplerSkyScanInit *init)
Definition: DopplerScan.c:507
DopplerSkyGrid * ConvertTwoDMesh2SkyGrid(const meshNODE *mesh2d, const SkyRegion *region)
Definition: DopplerScan.c:736
#define EPS4
Definition: DopplerScan.c:81
@ ORDER_ALPHA_DELTA
Definition: DopplerScan.c:86
@ ORDER_DELTA_ALPHA
Definition: DopplerScan.c:87
DopplerSkyGrid * XLALEquiPartitionSkygrid(const DopplerSkyGrid *skygrid, UINT4 partitionIndex, UINT4 numPartitions)
Equi-partition (approximately) a given skygrid into numPartitions, and return partition 0<= partition...
Definition: DopplerScan.c:1508
int XLALInitDopplerSkyScan(DopplerSkyScanState *skyScan, const DopplerSkyScanInit *init)
Initialize the Doppler sky-scanner.
Definition: DopplerScan.c:170
#define INDEX_A_A
Definition: DopplerScan.c:61
int XLALNextDopplerSkyPos(PulsarDopplerParams *pos, DopplerSkyScanState *skyScan)
NextDopplerSkyPos(): step through sky-grid return 0 = OK, -1 = ERROR.
Definition: DopplerScan.c:127
#define INDEX_D_D
Definition: DopplerScan.c:62
#define mymax(a, b)
#define SKYREGION_ALLSKY
Definition: DopplerScan.c:76
void gridFlipOrder(meshNODE *grid)
void XLALDestroyDopplerSkyScan(DopplerSkyScanState *skyScan)
Destroy the DopplerSkyScanState structure.
Definition: DopplerScan.c:294
#define SPOKES
Definition: DopplerScan.c:503
int getGridSpacings(PulsarDopplerParams *spacings, PulsarDopplerParams gridpoint, const DopplerSkyScanInit *params)
determine the 'canonical' stepsizes in all parameter-space directions, either from the metric (if –gr...
Definition: DopplerScan.c:1343
const char * va(const char *format,...)
#define DOPPLERSCANH_MSGESYS
Definition: DopplerScan.h:65
#define DOPPLERSCANH_ENEGMETRIC
Definition: DopplerScan.h:59
#define DOPPLERSCANH_MSGENEGMETRIC
Definition: DopplerScan.h:75
#define DOPPLERSCANH_ESYS
Definition: DopplerScan.h:49
#define DOPPLERSCANH_MSGEXLAL
Definition: DopplerScan.h:76
#define DOPPLERSCANH_EINPUT
Definition: DopplerScan.h:58
#define DOPPLERSCANH_ENULL
Definition: DopplerScan.h:47
#define DOPPLERSCANH_MSGENULL
Definition: DopplerScan.h:63
#define DOPPLERSCANH_MSGEINPUT
Definition: DopplerScan.h:74
#define DOPPLERSCANH_EXLAL
Definition: DopplerScan.h:60
@ STATE_READY
initialized and ready
Definition: DopplerScan.h:83
@ STATE_FINISHED
all templates have been read
Definition: DopplerScan.h:84
@ STATE_IDLE
not initialized yet
Definition: DopplerScan.h:82
@ STATE_LAST
Definition: DopplerScan.h:85
@ GRID_METRIC
generate grid using a 2D sky-metric
Definition: DopplerScan.h:93
@ GRID_FLAT
"flat" sky-grid: fixed step-size (dAlpha,dDelta)
Definition: DopplerScan.h:91
@ GRID_FILE_SKYGRID
read skygrid from a file
Definition: DopplerScan.h:94
@ GRID_METRIC_SKYFILE
'hybrid' grid-construction: use skygrid from file, metric for others
Definition: DopplerScan.h:95
@ GRID_SKY_LAST
end-marker for factored grid types
Definition: DopplerScan.h:96
@ GRID_ISOTROPIC
approximately isotropic sky-grid
Definition: DopplerScan.h:92
int j
#define LALCalloc(m, n)
#define LALFree(p)
#define c
#define ABORT(statusptr, code, mesg)
#define ENDFAIL(statusptr)
#define TRY(func, statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define ASSERT(assertion, statusptr, code, mesg)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define BEGINFAIL(statusptr)
#define fprintf
int XLALParseDataFile(LALParsedDataFile **cfgdata, const CHAR *fname)
void XLALDestroyParsedDataFile(LALParsedDataFile *cfgdata)
#define LAL_PI_2
#define LAL_PI
#define LAL_TWOPI
unsigned char BOOLEAN
#define XLAL_INIT_MEM(x)
double REAL8
#define XLAL_INIT_DECL(var,...)
char CHAR
uint32_t UINT4
int32_t INT4
float REAL4
#define lalDebugLevel
void * XLALMalloc(size_t n)
void XLALFree(void *p)
#define LAL_REAL8_FORMAT
char char * XLALStringDuplicate(const char *s)
void LogPrintf(LogLevel_t, const char *format,...) _LAL_GCC_PRINTF_FORMAT_(2
LOG_CRITICAL
#define PMETRIC_INDEX(a, b)
Translate metrix matrix-indices (a,b) into vector-index l.
Definition: PtoleMetric.h:76
void LALProjectMetric(LALStatus *stat, REAL8Vector *metric, BOOLEAN errors)
Project out the zeroth dimension of a metric.
Definition: PtoleMetric.c:732
void LALPulsarMetric(LALStatus *stat, REAL8Vector **metric, PtoleMetricIn *input)
Unified "wrapper" to provide a uniform interface to LALPtoleMetric() and LALCoherentMetric().
Definition: PtoleMetric.c:625
@ LAL_PMETRIC_NONE
Definition: PtoleMetric.h:96
@ LAL_PMETRIC_LAST
Definition: PtoleMetric.h:98
REAL8 PulsarSpins[PULSAR_MAX_SPINS]
Typedef for fixed-size array holding GW frequency and derivatives fk = d^k Freq/dt^k|(tau_ref)
#define PULSAR_MAX_SPINS
maximal number of spin-parameters (Freq + spindowns) we can handle
static const INT4 r
static const INT4 a
void XLALNormalizeSkyPosition(double *restrict longitude, double *restrict latitude)
void LALNormalizeSkyPosition(LALStatus *stat, SkyPosition *posOut, const SkyPosition *posIn)
COORDINATESYSTEM_EQUATORIAL
void LALCreateTwoDMesh(LALStatus *stat, TwoDMeshNode **mesh, TwoDMeshParamStruc *params)
Definition: TwoDMesh.c:106
void LALDestroyTwoDMesh(LALStatus *stat, TwoDMeshNode **mesh, UINT4 *nFree)
Definition: TwoDMesh.c:159
int XLALParseStringValueAsDECJ(REAL8 *valDECJ, const char *valString)
int XLALParseStringValueAsRAJ(REAL8 *valRAJ, const char *valString)
REAL4Vector * XLALCreateREAL4Vector(UINT4 length)
void XLALDestroyREAL4Vector(REAL4Vector *vector)
void LALDDestroyVector(LALStatus *, REAL8Vector **)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
#define XLAL_ERROR_NULL(...)
#define xlalErrno
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_CHECK_NULL(assertion,...)
#define XLAL_PRINT_DEPRECATION_WARNING(replacement)
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EINVAL
XLAL_EFAILED
float data[BLOCKSIZE]
Definition: hwinject.c:360
list y
head
pos
end
int N
struct tagDopplerSkyGrid * next
Definition: DopplerScan.h:127
initialization-structure passed to InitDopplerSkyScan()
Definition: DopplerScan.h:134
const EphemerisData * ephemeris
ephemeris-data for "exact" metric
Definition: DopplerScan.h:145
BOOLEAN projectMetric
project the metric orthogonal to Freq?
Definition: DopplerScan.h:143
UINT4 numSkyPartitions
number of (roughly) equal partitions to split sky-grid into
Definition: DopplerScan.h:147
UINT4 partitionIndex
index of requested sky-grid partition: in [0, numPartitions - 1]
Definition: DopplerScan.h:148
const CHAR * skyGridFile
file containing a sky-grid (list of points) if GRID_FILE
Definition: DopplerScan.h:146
LIGOTimeGPS obsBegin
GPS start-time of time-series.
Definition: DopplerScan.h:141
REAL8 dDelta
sky step-sizes for GRID_FLAT and GRID_ISOTROPIC
Definition: DopplerScan.h:139
REAL8 Freq
Frequency for which to build the skyGrid.
Definition: DopplerScan.h:136
DopplerGridType gridType
which type of skygrid to generate
Definition: DopplerScan.h:137
REAL8 obsDuration
length of time-series in seconds
Definition: DopplerScan.h:142
REAL8 metricMismatch
for GRID_METRIC
Definition: DopplerScan.h:140
LALPulsarMetricType metricType
which metric to use if GRID_METRIC
Definition: DopplerScan.h:138
CHAR * skyRegionString
sky-region to search: format polygon '(a1,d1), (a2,d2), ..'
Definition: DopplerScan.h:135
const LALDetector * Detector
Current detector.
Definition: DopplerScan.h:144
this structure reflects the current state of a DopplerSkyScan
Definition: DopplerScan.h:152
UINT4 numSkyGridPoints
how many skygrid-points
Definition: DopplerScan.h:155
PulsarSpins dfkdot
fixed-size steps in spins
Definition: DopplerScan.h:156
DopplerSkyGrid * skyNode
pointer to current grid-node in skygrid
Definition: DopplerScan.h:158
scan_state_t state
idle, ready or finished
Definition: DopplerScan.h:153
DopplerSkyGrid * skyGrid
head of linked list of skygrid nodes
Definition: DopplerScan.h:157
SkyRegion skyRegion
polygon (and bounding square) defining sky-region
Definition: DopplerScan.h:154
This structure contains all information about the center-of-mass positions of the Earth and Sun,...
INT4 gpsNanoSeconds
a "sky-ellipse", described by the two major axes and it's angle wrt x-axis
Definition: DopplerScan.h:162
This structure will likely be changed to match up better with those under StackMetric....
Definition: PtoleMetric.h:110
SkyPosition position
The equatorial coordinates at which the metric components are evaluated.
Definition: PtoleMetric.h:111
REAL4Vector * spindown
The (dimensionless) spindown parameters for which the metric components are evaluated.
Definition: PtoleMetric.h:112
REAL4 maxFreq
The maximum frequency to be searched, in Hz.
Definition: PtoleMetric.h:115
LALPulsarMetricType metricType
The type of metric to use: analytic, Ptolemaic or fully ephemeris-based.
Definition: PtoleMetric.h:118
const LALDetector * site
The detector site, used only for its latitude and longitude.
Definition: PtoleMetric.h:116
REAL4 duration
Duration of integration, in seconds.
Definition: PtoleMetric.h:114
const EphemerisData * ephemeris
Not used for the Ptolemaic approximation, this is for compatibility with other metrics.
Definition: PtoleMetric.h:117
LIGOTimeGPS epoch
When the coherent integration begins.
Definition: PtoleMetric.h:113
Type containing the 'Doppler-parameters' affecting the time-evolution of the phase.
PulsarSpins fkdot
Intrinsic spins: [Freq, f1dot, f2dot, ... ] where fkdot = d^kFreq/dt^k.
REAL8 Delta
Sky position: DEC (latitude) in equatorial coords and radians.
REAL8 Alpha
Sky position: RA (longitude) in equatorial coords and radians.
REAL4 * data
REAL8 longitude
REAL8 latitude
CoordinateSystem system
structure describing a polygon-region in the sky
Definition: DopplerScan.h:108
UINT4 numVertices
number of polygon-vertices
Definition: DopplerScan.h:109
SkyPosition lowerLeft
lower-left point of bounding square
Definition: DopplerScan.h:111
SkyPosition * vertices
array of vertices
Definition: DopplerScan.h:110
SkyPosition upperRight
upper-right point of bounding square
Definition: DopplerScan.h:112
This structure represents a single node in a linked list of mesh points, specified in the coordinate ...
Definition: TwoDMesh.h:124
struct tagTwoDMeshNode * next
The next mesh point in the linked list; NULL if this is the tail.
Definition: TwoDMesh.h:128
REAL4 y
The coordinates of the mesh point.
Definition: TwoDMesh.h:125
This structure stores the parameters required by the two-dimensional mesh placement functions.
Definition: TwoDMesh.h:142
double duration