LALPulsar  6.1.0.1-c9a8ef6
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: */
85 enum {
88 };
89 
91 
92 typedef REAL4 meshREAL;
95 
96 /*---------- internal prototypes ----------*/
97 void getRange( LALStatus *, meshREAL y[2], meshREAL x, void *params );
98 void getMetric( LALStatus *, meshREAL g[3], meshREAL skypos[2], void *params );
100 
101 DopplerSkyGrid *ConvertTwoDMesh2SkyGrid( const meshNODE *mesh2d, const SkyRegion *region );
102 
103 BOOLEAN pointInPolygon( const SkyPosition *point, const SkyRegion *polygon );
104 
105 void gridFlipOrder( meshNODE *grid );
106 
107 DopplerSkyGrid *buildFlatSkyGrid( const SkyRegion *region, REAL8 dAlpha, REAL8 dDelta );
108 DopplerSkyGrid *buildIsotropicSkyGrid( const SkyRegion *skyRegion, REAL8 dAlpha, REAL8 dDelta );
110 DopplerSkyGrid *loadSkyGridFile( const CHAR *fname );
111 
112 void plotSkyGrid( LALStatus *, DopplerSkyGrid *skygrid, const SkyRegion *region, const DopplerSkyScanInit *init );
113 void freeSkyGrid( DopplerSkyGrid *skygrid );
115 
116 void printFrequencyShifts( LALStatus *, const DopplerSkyScanState *skyScan, const DopplerSkyScanInit *init );
117 
118 const 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  */
126 int
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  */
169 int
170 XLALInitDopplerSkyScan( 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 
207  case GRID_METRIC_SKYFILE:
208  case GRID_FILE_SKYGRID:
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  {
244  PulsarDopplerParams XLAL_INIT_DECL( gridpoint );
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  */
272 void
273 InitDopplerSkyScan( LALStatus *status, /**< pointer to LALStatus structure */
274  DopplerSkyScanState *skyScan, /**< [out] the initialized scan-structure */
275  const DopplerSkyScanInit *init ) /**< [in] init-params */
276 {
277  INITSTATUS( status );
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  */
293 void
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  */
323 void
325 {
326  INITSTATUS( status );
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  *----------------------------------------------------------------------*/
339 void
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  */
379 void getRange( LALStatus *status, meshREAL y[2], meshREAL UNUSED x, void *params )
380 {
381  SkyRegion *region = ( SkyRegion * )params;
382 
383  /* Set up shop. */
384  INITSTATUS( status );
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  *----------------------------------------------------------------------*/
414 void 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. */
421  INITSTATUS( status );
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 
458  BEGINFAIL( status )
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 
506 void
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;
515  REAL8 Alpha, Delta;
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. */
529  INITSTATUS( status );
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;
573  REAL8 mismatch = init->metricMismatch;
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  */
679 BOOLEAN
680 pointInPolygon( 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  *----------------------------------------------------------------------*/
736 ConvertTwoDMesh2SkyGrid( 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  *----------------------------------------------------------------------*/
789 buildFlatSkyGrid( 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  *----------------------------------------------------------------------*/
841 buildIsotropicSkyGrid( 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 
969 done:
970  return skyGrid;
971 
972 } /* buildMetricSkyGrid() */
973 
974 
975 /**
976  * Load skygrid from file, clipped to searchRegion.
977  */
979 loadSkyGridFile( const CHAR *fname
980  )
981 {
982  XLAL_CHECK_NULL( fname, XLAL_EINVAL );
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  */
1022 void
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  *----------------------------------------------------------------------*/
1059 void
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  */
1166 REAL8
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  */
1202 int
1203 XLALParseSkyRegionString( SkyRegion *region, const CHAR *input )
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  */
1294 CHAR *
1295 XLALSkySquare2String( 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  */
1342 int
1343 getGridSpacings( 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 ) {
1394  LALProjectMetric( &status, metric, 0 );
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 
1411  XLALDestroyREAL8Vector( metric );
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  */
1433 void
1435  MetricEllipse *ellipse,
1436  REAL8 mismatch,
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 */
1483 int
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  */
1508 XLALEquiPartitionSkygrid( 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
const char * va(const char *format,...)
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 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
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
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)
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
#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
#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 s
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)
void XLALDestroyREAL4Vector(REAL4Vector *vector)
REAL4Vector * XLALCreateREAL4Vector(UINT4 length)
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
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, ...
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 * 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