Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
SpectralInterpolation.c
Go to the documentation of this file.
1/* 2015 G.S. Davies
2
3* This program is free software; you can redistribute it and/or modify
4* it under the terms of the GNU General Public License as published by
5* the Free Software Foundation; either version 2 of the License, or
6* (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with with program; see the file COPYING. If not, write to the
15* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16* MA 02110-1301 USA
17
18
19 * \author G.S. Davies
20 * \brief
21 * code to provide B_k given SFT data for given a set of pulsar
22 * parameters. The Spectral Interpolation code is intended as a black box replacement for the existing
23 * heterodyne process.
24 */
25
27
28/* Define some commonly used macros*/
29#define ROUND(x) (floor(x+0.5))
30#define SINC(x) (sin(LAL_PI*x)/(LAL_PI*x))
31
32
35
36int main( int argc, char **argv )
37{
38
39 InputParams inputParams;
40 SplInterParams splParams;
41
42 /* Take variables as input from command line */
43 get_input_args( &inputParams, argc, argv );
44
45 fprintf( stderr, "Starting Spectral Interpolation" );
46
47 /* if timing the code, then set up structures and start the clock */
48 struct timeval timePreTot, timeEndTot;
49 if ( inputParams.Timing ) {
50 fprintf( stderr, ", outputting timing values.\n" );
51 gettimeofday( &timePreTot, NULL );
52 } else {
53 fprintf( stderr, ".\n" );
54 }
55
56 struct timeval timePreStart, timePreEnd;
57 struct timeval timePulStart, timePulEnd;
58
59 if ( inputParams.Timing ) {
60 gettimeofday( &timePreStart, NULL );
61 }
62
63 /* check input combinations and required parameters are set */
64 if ( inputParams.startF == 0. || inputParams.endF == 0. ) {
65 fprintf( stderr, "SFT start and end frequencies are required.\n" );
66 exit( 1 );
67 }
68
69 if ( inputParams.pardirflag == 0 && inputParams.parfileflag == 0 ) {
70 XLALPrintError( "No Pulsar directory or parfile specified\n" );
72 } else if ( inputParams.pardirflag == 1 && inputParams.parfileflag == 1 ) {
73 fprintf( stderr, "Pulsar directory and parfile specified. Using specified parfile.\n" );
74 inputParams.pardirflag = 0;
75 }
76
77 if ( inputParams.nameset == 1 && inputParams.pardirflag == 1 ) {
78 XLALPrintError( "WARNING: Pulsar name and directory both set, specified pulsar name is useless.\n" );
79 }
80
81 /* get data for position and orientation of interferometer */
82 splParams.detector = *XLALGetSiteInfo( inputParams.ifo );
83
84 if ( inputParams.geocentre ) { /* set site to the geocentre if geoFlag is set */
85 splParams.detector.location[0] = 0.0;
86 splParams.detector.location[1] = 0.0;
87 splParams.detector.location[2] = 0.0;
88 }
89
90 /* Initialise variables for use throughout */
91 LIGOTimeGPS minStartTimeGPS = empty_LIGOTimeGPS;
92 LIGOTimeGPS maxEndTimeGPS = empty_LIGOTimeGPS;
93 UINT4 segcount = 0;
94 CHAR outputFilename[FILENAME_MAXLEN];
95 EmissionTime emit, emitS, emitE;
96 CHAR timefileTDB[FILENAME_MAXLEN], timefileTE405[FILENAME_MAXLEN], sunfile200[FILENAME_MAXLEN],
97 earthfile200[FILENAME_MAXLEN], sunfile405[FILENAME_MAXLEN], earthfile405[FILENAME_MAXLEN],
98 sunfile414[FILENAME_MAXLEN], earthfile414[FILENAME_MAXLEN], earthfile421[FILENAME_MAXLEN], sunfile421[FILENAME_MAXLEN];
99 EphemerisData *edat200 = NULL, *edat405 = NULL, *edat414 = NULL, *edat421 = NULL;
100 TimeCorrectionData *tdatTDB = NULL, *tdatTE405 = NULL;
101
102 /* Read in pulsar data either from directory or individual file. */
103 LALStringVector *parfiles = NULL; /* return a list of pulsar parameter files in the given directory */
104 if ( inputParams.pardirflag ) {
105 CHAR *globstring = XLALStringDuplicate( inputParams.pulsarDir );
106 globstring = XLALStringAppend( globstring, "/*.par" ); /* search for files with the ".par" suffix */
107 parfiles = XLALFindFiles( globstring );
108 if ( !parfiles ) {
109 XLALPrintError( "Error... failed to find any pulsar parameter files in \"%s\"", inputParams.pulsarDir );
110 }
111 } else {
112 parfiles = XLALAppendString2Vector( NULL, inputParams.paramfile );
113 }
114
115 UINT4 numpulsars = 0, numfiles = parfiles->length;
116 UINT4 h = 0;
117
118 PulsarParameters **pulparams = ( PulsarParameters ** )XLALMalloc( sizeof( PulsarParameters * ) * 1 );
119 LALStringVector *outputfilenames = NULL;
120
121 /* count number of pulsars with valid frequencies, and read in parameters */
122 for ( h = 0; h < numfiles; h++ ) {
123 CHAR *psrname = NULL;
124 PulsarParameters *tmppar = XLALReadTEMPOParFile( parfiles->data[h] );
125
126 /* check if par file was read in successfully */
127 if ( !tmppar ) {
128 fprintf( stderr, "Warning... could not read in \"%s\". Skipping this pulsars.", parfiles->data[h] );
129 continue;
130 }
131
132 /* check that a frequency is given in the par file */
133 if ( !PulsarCheckParam( tmppar, "F" ) ) {
134 fprintf( stderr, "Warning... no frequency given in \"%s\". Skipping this pulsars.", parfiles->data[h] );
135 continue;
136 }
137
138 /* check frequency is within the range of the SFTs */
140
141 if ( f0 * inputParams.freqfactor < inputParams.startF || f0 * inputParams.freqfactor > inputParams.endF ) {
142 fprintf( stderr, "Warning... the GW frequency (%lf Hz) given in \"%s\" lies outside of SFT boundaries (%f to %f Hz).\n", f0 * inputParams.freqfactor, parfiles->data[h], inputParams.startF, inputParams.endF );
143 continue;
144 }
145
146 /* check RA and DEC are specified for pulsar */
147 if ( !PulsarCheckParam( tmppar, "RA" ) && !PulsarCheckParam( tmppar, "RAJ" ) ) {
148 fprintf( stderr, "Warning... no source right ascension specified in \"%s!\". Skipping this pulsar.", parfiles->data[h] );
149 continue;
150 }
151
152 if ( !PulsarCheckParam( tmppar, "DEC" ) && !PulsarCheckParam( tmppar, "DECJ" ) ) {
153 fprintf( stderr, "Warning... no source declination specified in \"%s!\". Skipping this pulsar.", parfiles->data[h] );
154 continue;
155 }
156
157 // free temporary read of file
158 PulsarClearParams( tmppar );
159 XLALFree( tmppar );
160
161 // allocate more memory for array holding pulsar parameters
162 if ( numpulsars > 0 ) {
163 pulparams = XLALRealloc( pulparams, sizeof( PulsarParameters * ) * ( numpulsars + 1 ) );
164 }
165
166 // re-read in file
167 pulparams[numpulsars] = XLALReadTEMPOParFile( parfiles->data[h] );
168
169 /* get pulsar name */
170 if ( inputParams.nameset ) {
171 psrname = XLALStringDuplicate( inputParams.PSRname );
172 } else if ( PulsarCheckParam( pulparams[numpulsars], "PSRJ" ) ) {
173 psrname = XLALStringDuplicate( PulsarGetStringParam( pulparams[numpulsars], "PSRJ" ) );
174 } else if ( PulsarCheckParam( pulparams[numpulsars], "PSR" ) ) {
175 psrname = XLALStringDuplicate( PulsarGetStringParam( pulparams[numpulsars], "PSR" ) );
176 } else if ( PulsarCheckParam( pulparams[numpulsars], "PSRB" ) ) {
177 psrname = XLALStringDuplicate( PulsarGetStringParam( pulparams[numpulsars], "PSRB" ) );
178 } else if ( PulsarCheckParam( pulparams[numpulsars], "NAME" ) ) {
179 psrname = XLALStringDuplicate( PulsarGetStringParam( pulparams[numpulsars], "NAME" ) );
180 }
181
182 // add "NAME" attribute
183 PulsarAddParam( pulparams[numpulsars], "NAME", psrname, PULSARTYPE_string_t );
184
185 if ( ( int )sizeof( outputFilename ) <= snprintf( outputFilename, FILENAME_MAXLEN, "%s/SplInter_%s_%s", inputParams.outputdir, psrname,
186 splParams.detector.frDetector.prefix ) ) {
187 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
188 }
189 outputfilenames = XLALAppendString2Vector( outputfilenames, outputFilename );
190
191 /* check output files can be opened/clear any previous file */
192 FILE *fp = NULL;
193 if ( ( fp = fopen( outputFilename, "w" ) ) == NULL ) {
194 fprintf( stderr, "Error... can't open output file %s!\n", outputFilename );
195 return 0;
196 }
197 fclose( fp );
198
199 /* If position epoch is not set but epoch is set position epoch to be epoch */
200 if ( !PulsarCheckParam( pulparams[numpulsars], "POSEPOCH" ) && PulsarCheckParam( pulparams[numpulsars], "PEPOCH" ) ) {
201 REAL8 pepoch = PulsarGetREAL8Param( pulparams[numpulsars], "PEPOCH" );
202 PulsarAddParam( pulparams[numpulsars], "POSEPOCH", &pepoch, PULSARTYPE_REAL8_t );
203 }
204
205 if ( !PulsarCheckParam( pulparams[numpulsars], "PEPOCH" ) && PulsarCheckParam( pulparams[numpulsars], "POSEPOCH" ) ) {
206 REAL8 posepoch = PulsarGetREAL8Param( pulparams[numpulsars], "POSEPOCH" );
207 PulsarAddParam( pulparams[numpulsars], "PEPOCH", &posepoch, PULSARTYPE_REAL8_t );
208 }
209
210 if ( PulsarCheckParam( pulparams[numpulsars], "RAJ" ) ) {
211 REAL8 ra = PulsarGetREAL8Param( pulparams[numpulsars], "RAJ" );
212 PulsarAddParam( pulparams[numpulsars], "RA", &ra, PULSARTYPE_REAL8_t ); // make sure RA is in "RA" parameter
213 }
214
215 if ( PulsarCheckParam( pulparams[numpulsars], "DECJ" ) ) {
216 REAL8 dec = PulsarGetREAL8Param( pulparams[numpulsars], "DECJ" );
217 PulsarAddParam( pulparams[numpulsars], "DEC", &dec, PULSARTYPE_REAL8_t ); // make sure DEC is in "DEC" parameter
218 }
219
220 numpulsars++;
221 }
222
223 REAL8 startF = NAN, endF = NAN; /* Set to be NaN so that the first comparison always gives the source frequency */
224 if ( inputParams.Timing ) {
225 gettimeofday( &timePulStart, NULL );
226 }
227
228 XLALDestroyStringVector( parfiles );
229
230 if ( inputParams.Timing ) {
231 gettimeofday( &timePulEnd, NULL );
232 }
233 /* if timing, then stop the clock on pulsar parameter load time. */
234
235 if ( inputParams.pardirflag == 1 && inputParams.parfileflag == 0 ) {
236 fprintf( stderr, "Number of valid Pulsars with frequencies within the SFT boundaries: %d\n", numpulsars );
237 }
238
239 /* load all types of ephemeris files, as uses little RAM/computational effort, and different parfiles may use a combination */
240 if ( ( int )sizeof( outputFilename ) <= snprintf( earthfile200, FILENAME_MAXLEN, "%s/earth00-40-DE200.dat.gz", inputParams.ephemdir ) ) {
241 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
242 }
243 if ( ( int )sizeof( outputFilename ) <= snprintf( sunfile200, FILENAME_MAXLEN, "%s/sun00-40-DE200.dat.gz", inputParams.ephemdir ) ) {
244 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
245 }
246 if ( ( int )sizeof( outputFilename ) <= snprintf( earthfile405, FILENAME_MAXLEN, "%s/earth00-40-DE405.dat.gz", inputParams.ephemdir ) ) {
247 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
248 }
249 if ( ( int )sizeof( outputFilename ) <= snprintf( sunfile405, FILENAME_MAXLEN, "%s/sun00-40-DE405.dat.gz", inputParams.ephemdir ) ) {
250 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
251 }
252 if ( ( int )sizeof( outputFilename ) <= snprintf( earthfile414, FILENAME_MAXLEN, "%s/earth00-19-DE414.dat.gz", inputParams.ephemdir ) ) {
253 XLAL_ERROR( XLAL_FAILURE, "String truncated" ); /* no earth00-40-DE414 available */
254 }
255 if ( ( int )sizeof( outputFilename ) <= snprintf( sunfile414, FILENAME_MAXLEN, "%s/sun00-19-DE414.dat.gz", inputParams.ephemdir ) ) {
256 XLAL_ERROR( XLAL_FAILURE, "String truncated" ); /* no sun00-40-DE414 available */
257 }
258 if ( ( int )sizeof( outputFilename ) <= snprintf( earthfile421, FILENAME_MAXLEN, "%s/earth00-40-DE421.dat.gz", inputParams.ephemdir ) ) {
259 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
260 }
261 if ( ( int )sizeof( outputFilename ) <= snprintf( sunfile421, FILENAME_MAXLEN, "%s/sun00-40-DE421.dat.gz", inputParams.ephemdir ) ) {
262 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
263 }
264
265 edat200 = XLALMalloc( sizeof( *edat200 ) );
266 edat405 = XLALMalloc( sizeof( *edat405 ) );
267 edat414 = XLALMalloc( sizeof( *edat414 ) );
268 edat421 = XLALMalloc( sizeof( *edat421 ) );
269
270 /* Load time correction files. */
271 if ( ( int )sizeof( outputFilename ) <= snprintf( timefileTDB, FILENAME_MAXLEN, "%s/tdb_2000-2040.dat.gz", inputParams.ephemdir ) ) {
272 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
273 }
274 if ( ( int )sizeof( outputFilename ) <= snprintf( timefileTE405, FILENAME_MAXLEN, "%s/te405_2000-2040.dat.gz", inputParams.ephemdir ) ) {
275 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
276 }
277
278 /* read in ephemeris files */
279 edat200 = XLALInitBarycenter( earthfile200, sunfile200 );
280 edat405 = XLALInitBarycenter( earthfile405, sunfile405 );
281 edat414 = XLALInitBarycenter( earthfile414, sunfile414 );
282 edat421 = XLALInitBarycenter( earthfile421, sunfile421 );
283
284 /* check it worked */
285 if ( edat200 == NULL || edat405 == NULL || edat414 == NULL || edat421 == NULL ) {
286 XLALPrintError( "Error, could not read sun and earth ephemeris files - check that the ephemeris directory is correct" );
287 exit( 1 );
288 }
289
290 /* read in time correction files */
291 tdatTDB = XLALInitTimeCorrections( timefileTDB );
292 tdatTE405 = XLALInitTimeCorrections( timefileTE405 );
293
294 /* check it worked */
295 if ( tdatTDB == NULL || tdatTE405 == NULL ) {
296 XLALPrintError( "Error, could not read time correction ephemeris file - check that the ephemeris directory is correct" );
297 exit( 1 );
298 }
299
300 /* ------ Set up Science segment list ------ */
301
302 /* Set finish time to infinity if default value is used */
303 REAL8 segmentsStart = 0., segmentsEnd = 0;
304 /* If using directory, segment start and end are either input from command line of defaulted to be or all time */
305 segmentsStart = inputParams.startTime;
306 segmentsEnd = inputParams.endTime;
307
308 /* if the length of data is not enough for minimum segment length specified then exit */
309 if ( segmentsEnd - segmentsStart < inputParams.minSegLength ) {
310 XLALPrintError( "Applicable length of segment list, %.0f to %.0f is less than specified minimum duration of data, %.0f\n", segmentsStart, segmentsEnd, inputParams.minSegLength );
311 exit( 1 );
312 }
313
314 // Read in science segment list
315 LALSegList *seglist = XLALReadSegmentsFromFile( inputParams.segfile );
316
317 /* if no segments are longer than the minimum segment time set then exit */
318 if ( seglist->length == 0 ) {
319 fprintf( stderr, "No segments found in segment file.\n" );
320 exit( 1 );
321 }
322
323 /* stop clock for pre-loop things*/
324 if ( inputParams.Timing ) {
325 gettimeofday( &timePreEnd, NULL );
326 }
327
328 UINT4 TotalNSFTs = 0;
329 REAL8 TotalInterTime = 0., TotalCatalogTime = 0., TotalLoadTime = 0.;
330
331 /* input a list of SFTs from a LALcache format file if provided */
332 LALCache *sftlalcache = NULL;
333 if ( inputParams.lalcacheFile && !inputParams.cacheFile && !inputParams.cacheDir ) {
334 sftlalcache = XLALCacheImport( inputParams.filePattern );
335 if ( sftlalcache == NULL ) {
336 XLALPrintError( "Error... there's a problem loading the SFT LALCache file" );
337 exit( 1 );
338 }
339 XLAL_CHECK( XLALCacheUniq( sftlalcache ) == 0, XLAL_EFUNC, "Error... problem getting unique values from SFT LALCache file" );
340 } else if ( !inputParams.cacheFile && !inputParams.cacheDir ) {
341 XLALPrintError( "Error... must specify either --sft-cache, --sft-lalcache, or --sft-loc" );
342 exit( 1 );
343 }
344
345 FILE *fpout[numpulsars];
346
347 /* --------------------------------------- */
348 /* --- BIT THAT DOES THE INTERPOLATION --- */
349 /* --------------------------------------- */
350 /* Loop Through each segment */
351 while ( segcount < seglist->length ) {
352
353 REAL8 startt = 0., endt = 0.;
354 REAL8 baryAlpha[numpulsars], baryDelta[numpulsars], barydInv[numpulsars];
356
357 startt = XLALGPSGetREAL8( &seglist->segs[segcount].start );
358 endt = XLALGPSGetREAL8( &seglist->segs[segcount].end );
359
360 // check whether segment is in the required time range
361 if ( startt > segmentsEnd || endt < segmentsStart ) {
362 segcount++;
363 continue; // skip segment
364 }
365
366 if ( startt < segmentsStart ) {
367 startt = segmentsStart;
368 }
369 if ( endt > segmentsEnd ) {
370 endt = segmentsEnd;
371 }
372
373 // check whether segment is long enough
374 if ( ( endt - startt ) < inputParams.minSegLength ) {
375 segcount++;
376 continue; // skip segment
377 }
378
379 // check whether segment exceeds maximum length, and if so truncate it
380 if ( ( endt - startt ) > inputParams.maxSegLength ) {
381 endt = startt + inputParams.maxSegLength;
382 XLALGPSSetREAL8( &seglist->segs[segcount].start, endt ); // update segment start time
383 segcount--; // reduce segcount, so this segment in the list gets redone with updated values
384 }
385
386 fprintf( stderr, "Segment %.0lf-%.0lf", startt, endt );
387
388 for ( h = 0; h < numpulsars; h++ ) {
389 /* for each pulsar, calculate alpha and delta as approx the same over the segment */
390 REAL8 dtpos = 0.;
391
392 dtpos = ( startt + endt ) / 2. - PulsarGetREAL8ParamOrZero( pulparams[h], "POSEPOCH" );
393 /* calculate new sky position including proper motion */
394 baryDelta[h] = PulsarGetREAL8Param( pulparams[h], "DEC" ) + dtpos * PulsarGetREAL8ParamOrZero( pulparams[h], "PMDEC" );
395 baryAlpha[h] = PulsarGetREAL8Param( pulparams[h], "RA" ) + dtpos * PulsarGetREAL8ParamOrZero( pulparams[h], "PMRA" ) / cos( baryDelta[h] );
396
397 /* Give distance to pulsar from parameter files to barycenter routine */
398 if ( PulsarGetREAL8ParamOrZero( pulparams[h], "PX" ) != 0. ) {
399 barydInv[h] = PulsarGetREAL8Param( pulparams[h], "PX" ) * ( LAL_C_SI / LAL_AU_SI );
400 } else {
401 barydInv[h] = 0.; // no parallax
402 }
403 }
404
405 struct timeval timeCatalogStart, timeCatalogEnd, timeLoadStart, timeLoadEnd, timeInterpolateStart, timeInterpolateEnd;
406 REAL8 tInterpolate = 0., tLoad = 0., tCatalog = 0.;
407
408 /* Use segment times to set up constraints of times for SFTs */
409 XLALGPSSetREAL8( &minStartTimeGPS, startt );
410 XLALGPSSetREAL8( &maxEndTimeGPS, endt );
411
412 constraints.minStartTime = &minStartTimeGPS;
413 constraints.maxStartTime = &maxEndTimeGPS;
414 constraints.detector = inputParams.ifo;
415
416 /* get full SFT-catalog of all matching SFTs within the segment */
417 SFTCatalog *catalog = NULL;
418
419 /* start catalogue load clock */
420 if ( inputParams.Timing ) {
421 gettimeofday( &timeCatalogStart, NULL );
422 }
423
424 /* Set up SFT cache filename and cache opening string */
425 if ( sftlalcache == NULL ) {
426 CHAR cacheFile[FILENAME_MAXLEN], cacheFileCheck[FILENAME_MAXLEN];
427 if ( inputParams.cacheDir ) {
428 if ( FILENAME_MAXLEN <= snprintf( cacheFile, FILENAME_MAXLEN, "list:%s/Segment_%d-%d.sftcache", inputParams.filePattern, ( INT4 )ROUND( startt ), ( INT4 )ROUND( endt ) ) ) {
429 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
430 }
431 if ( FILENAME_MAXLEN <= snprintf( cacheFileCheck, FILENAME_MAXLEN, "%s/Segment_%d-%d.sftcache", inputParams.filePattern, ( INT4 )ROUND( startt ), ( INT4 )ROUND( endt ) ) ) {
432 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
433 }
434 } else {
435 if ( FILENAME_MAXLEN <= snprintf( cacheFile, FILENAME_MAXLEN, "%s", inputParams.filePattern ) ) {
436 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
437 }
438 CHAR *rmlist = inputParams.filePattern;
439 rmlist += 5;
440 if ( FILENAME_MAXLEN <= snprintf( cacheFileCheck, FILENAME_MAXLEN, "%s", rmlist ) ) {
441 XLAL_ERROR( XLAL_FAILURE, "String truncated" );
442 }
443 }
444
445 /* Check SFT cache file exists and is not empty*/
446 struct stat fileStat;
447 if ( stat( cacheFileCheck, &fileStat ) < 0 ) {
448 segcount++;
449 fprintf( stderr, " SFT cache file %s does not exist.\n", cacheFileCheck );
450 continue;
451 }
452
453 if ( fileStat.st_size == 0 ) {
454 segcount++;
455 fprintf( stderr, " SFT cache file %s is empty.\n", cacheFileCheck );
456 continue;
457 }
458
459 catalog = XLALSFTdataFind( cacheFile, &constraints );
460 } else {
461 /* find required SFTs for the segment from the cache file and create a catalog */
462 CHAR *cacheFile = NULL;
463 LALCache *sievesfts = XLALCacheDuplicate( sftlalcache ); /* duplicate of full cache that can be sieved */
464 XLAL_CHECK( XLALCacheSieve( sievesfts, ( INT4 )startt, ( INT4 )endt, NULL, NULL, NULL ) == 0, XLAL_EFUNC, "Warning... problem sieving SFTs" );
465
466 if ( sievesfts->length == 0 ) {
467 segcount++;
468 fprintf( stderr, " no SFTs for this period.\n" );
469 XLALFree( cacheFile );
470 XLALDestroyCache( sievesfts );
471 continue;
472 }
473
474 /* make cache into a ; separated list of file */
475 for ( h = 0; h < sievesfts->length; h++ ) {
476 CHAR *sftptr = sievesfts->list[h].url;
477
478 /* remove file://localhost if present (this confused XLALFindFiles) */
479 if ( strncmp( sftptr, "file://localhost/", strlen( "file://localhost/" ) ) == 0 ) {
480 sftptr += strlen( "file://localhost/" ) - 1;
481 }
482 cacheFile = XLALStringAppend( cacheFile, sftptr );
483 if ( h < sievesfts->length - 1 ) {
484 cacheFile = XLALStringAppend( cacheFile, ";" );
485 }
486 }
487
488 catalog = XLALSFTdataFind( cacheFile, &constraints );
489
490 XLALFree( cacheFile );
491 XLALDestroyCache( sievesfts );
492 }
493
494 if ( inputParams.Timing ) {
495 gettimeofday( &timeCatalogEnd, NULL );
496 tCatalog = ( REAL8 )timeCatalogEnd.tv_usec * 1.e-6 + ( REAL8 )timeCatalogEnd.tv_sec - ( REAL8 )timeCatalogStart.tv_usec * 1.e-6 - ( REAL8 )timeCatalogStart.tv_sec;
497 TotalCatalogTime += tCatalog;
498 }
499
500 if ( !catalog ) {
501 XLALPrintError( "\nCATALOG READ ROUTINE FAILED\n" );
502 segcount++;
503 continue;
504 }
505
506 /* check if catalog is empty - i.e. there are no SFTs from this segment in the location specified */
507 if ( catalog->length == 0 ) {
508 XLALPrintError( " contains no matching SFTs\n" );
509 segcount++;
510 XLALFree( catalog );
511 continue;
512 }
513
514 /* add number of SFTs in current catalogue to total*/
515 TotalNSFTs += ( catalog->length );
516
517 SFTVector *SFTdat = NULL;
518 UINT4 sftnum = 0;
519 REAL8 deltaf = 0.;
520
521 /* Check if the input end frequency is above the maximum frequency of the SFTs minus 1.5Hz,
522 and if the input Start frequency is below the start of the SFT plus 1.5Hz*/
523
524 endF = fminf( endF + 1.5, ( REAL8 )( catalog->data->header.f0 + catalog->data->header.deltaF * catalog->data->numBins ) - 1.5 );
525 startF = fmaxf( startF - 1.5, ( REAL8 )( catalog->data->header.f0 ) + 1.5 );
526
527 if ( inputParams.Timing ) {
528 gettimeofday( &timeLoadStart, NULL );
529 }
530 /* Load the SFTs from the catalog */
531 if ( inputParams.pardirflag ) {
532 /* If taking multiple pulsars input, load the entire SFT within the input boundaries */
533 SFTdat = XLALLoadSFTs( catalog, startF, endF );
534
535 } else if ( inputParams.parfileflag ) {
536 /* If taking single pulsar input, approximate the frequency and load a 3Hz band around this*/
537
538 REAL8 tAv = 0., fAp = 0., dtpow = 1.;
539
540 /* Approximate the frequency for the time at the middle of the segment, */
541 /* this doesn't take relative motion effects into account */
542
543 tAv = ( ( REAL8 )endt + ( REAL8 )startt ) / 2. - PulsarGetREAL8ParamOrZero( pulparams[0], "PEPOCH" );
544 const REAL8Vector *freqs = PulsarGetREAL8VectorParam( pulparams[0], "F" );
545
546 for ( h = 0; h < freqs->length; h++ ) {
547 fAp += ( freqs->data[h] * dtpow ) / gsl_sf_fact( h );
548 dtpow *= tAv;
549 }
550 fAp *= inputParams.freqfactor;
551
552 /* Load the SFTs */
553 SFTdat = XLALLoadSFTs( catalog, fAp - 1.5, fAp + 1.5 );
554
555 }
556
557 /* stop sft load clock */
558 if ( inputParams.Timing ) {
559 gettimeofday( &timeLoadEnd, NULL );
560 tLoad = ( REAL8 )timeLoadEnd.tv_usec * 1.e-6 + ( REAL8 )timeLoadEnd.tv_sec - ( REAL8 )timeLoadStart.tv_usec * 1.e-6 - ( REAL8 )timeLoadStart.tv_sec;
561 }
562
563 /* check that the SFT has loaded properly */
564 if ( SFTdat == NULL ) {
565 XLALPrintError( " SFT data has not loaded properly" );
566 exit( 1 );
567 }
568
569 /* start interpolation clock */
570 if ( inputParams.Timing ) {
571 gettimeofday( &timeInterpolateStart, NULL );
572 }
573
574 /* re-open the output files */
575 for ( h = 0; h < numpulsars; h++ ) {
576 fpout[h] = NULL;
577 if ( ( fpout[h] = fopen( outputfilenames->data[h], "a" ) ) == NULL ) {
578 fprintf( stderr, "Error... can't open output file %s!\n", outputfilenames->data[h] );
579 return 0;
580 }
581
582 /* buffer the output, so that file system is not overloaded when outputing */
583 if ( setvbuf( fpout[h], NULL, _IOFBF, 0x10000 ) ) {
584 fprintf( stderr, "Warning: Unable to set output file buffer!" );
585 }
586 }
587
588 /* Loop through each SFT */
589 for ( sftnum = 0; sftnum < ( SFTdat->length ); sftnum++ ) {
590
591 /* deltaf is the frequency bin separation, this is used in a lot of the calculations as */
592 /* deltaf = 1/(SFT length)*/
593 deltaf = SFTdat->data->deltaF;
594 REAL8 timestamp = 0;
595 timestamp = XLALGPSGetREAL8( &SFTdat->data[sftnum].epoch );
596
597 for ( h = 0; h < numpulsars; h++ ) {
598 /* Initialise variables that change for each SFT */
599 REAL8 InterpolatedImagValue = 0., InterpolatedRealValue = 0.,
600 UnnormalisedInterpolatedImagValue = 0., UnnormalisedInterpolatedRealValue = 0.,
601 AbsSquaredWeightSum = 0;
602 INT4 datapoint = 0;
603 EarthState earth, earthS, earthE;
604 REAL8 phaseShift = 0., fnew = 0., f1new = 0., sqrtf1new = 0.;
605 REAL8 tdt = 0.;
606 REAL8 tdtS = 0.;
607 REAL8 tdtE = 0.;
608 EphemerisData *edat = NULL;
609 TimeCorrectionData *tdat = NULL;
610 TimeCorrectionType ttype;
611 BarycenterInput baryInput, baryInputS, baryInputE;
612
613 /* ------ Barycenter routine ------ */
614
615 /* Timestamp needed in GPS format*/
616 XLALGPSSetREAL8( &baryInput.tgps, timestamp + 1. / ( 2.*deltaf ) );
617
618 /* set up location of detector */
619 baryInput.site.location[0] = splParams.detector.location[0] / LAL_C_SI;
620 baryInput.site.location[1] = splParams.detector.location[1] / LAL_C_SI;
621 baryInput.site.location[2] = splParams.detector.location[2] / LAL_C_SI;
622
623 baryInputE.site.location[0] = splParams.detector.location[0] / LAL_C_SI;
624 baryInputE.site.location[1] = splParams.detector.location[1] / LAL_C_SI;
625 baryInputE.site.location[2] = splParams.detector.location[2] / LAL_C_SI;
626
627 baryInputS.site.location[0] = splParams.detector.location[0] / LAL_C_SI;
628 baryInputS.site.location[1] = splParams.detector.location[1] / LAL_C_SI;
629 baryInputS.site.location[2] = splParams.detector.location[2] / LAL_C_SI;
630
631 /* get sky position and inverse distance from previously calculated values */
632 baryInput.delta = baryDelta[h];
633 baryInput.alpha = baryAlpha[h];
634 baryInput.dInv = barydInv[h];
635
636 baryInputE.delta = baryDelta[h];
637 baryInputE.alpha = baryAlpha[h];
638 baryInputE.dInv = barydInv[h];
639
640 baryInputS.delta = baryDelta[h];
641 baryInputS.alpha = baryAlpha[h];
642 baryInputS.dInv = barydInv[h];
643
644 /* check the time correction and ephemeris types*/
645 if ( PulsarCheckParam( pulparams[h], "UNITS" ) ) {
646 if ( !strcmp( PulsarGetStringParam( pulparams[h], "UNITS" ), "TDB" ) ) {
647 tdat = tdatTDB;
648 ttype = TIMECORRECTION_TDB;
649 } else {
650 tdat = tdatTE405;
651 ttype = TIMECORRECTION_TCB;
652 }
653 } else {
655 tdat = NULL;
656 }
657
658 /* set up which ephemeris type is being used for this source */
659 if ( PulsarCheckParam( pulparams[h], "EPHEM" ) ) {
660 if ( !strcmp( PulsarGetStringParam( pulparams[h], "EPHEM" ), "DE405" ) ) {
661 edat = edat405;
662 } else if ( !strcmp( PulsarGetStringParam( pulparams[h], "EPHEM" ), "DE421" ) ) {
663 edat = edat421;
664 } else if ( !strcmp( PulsarGetStringParam( pulparams[h], "EPHEM" ), "DE414" ) ) {
665 edat = edat414;
666 } else if ( !strcmp( PulsarGetStringParam( pulparams[h], "EPHEM" ), "DE200" ) ) {
667 edat = edat200;
668 } else {
669 edat = edat405; // default to DE405
670 }
671 } else {
672 edat = edat405; /* default is that DE405 is used*/
673 }
674
675 /* Perform Barycentering Routine at middle of SFT, for calculation of phase shift and frequency */
676 XLALBarycenterEarthNew( &earth, &baryInput.tgps, edat, tdat, ttype );
677 XLALBarycenter( &emit, &baryInput, &earth );
678
679 /* Also perform Barycentering Routine at start and end of SFT, for calculation of frequency derivatives */
680
681 XLALGPSSetREAL8( &baryInputE.tgps, timestamp + 1. / ( deltaf ) );
682 XLALGPSSetREAL8( &baryInputS.tgps, timestamp );
683
684 XLALBarycenterEarthNew( &earthE, &baryInputE.tgps, edat, tdat, ttype );
685 XLALBarycenterEarthNew( &earthS, &baryInputS.tgps, edat, tdat, ttype );
686
687 XLALBarycenter( &emitE, &baryInputE, &earthE );
688 XLALBarycenter( &emitS, &baryInputS, &earthS );
689
690 /* If the 'detector at barycenter' flag is set, then reset emit to appropriate values */
691 if ( inputParams.baryFlag ) {
692 emit.tDot = 1.;
693 emit.deltaT = 0.;
694 emitS.tDot = 1.;
695 emitS.deltaT = 0.;
696 emitE.tDot = 1.;
697 emitE.deltaT = 0.;
698 }
699
700 REAL8 totaltDot = 0., totaltDotstart = 0., totaltDotend = 0.;
701 REAL8 totaldeltaT = 0., totaldeltaTstart = 0., totaldeltaTend = 0.;
702
703 /* Get binary pulsar corrections if source is a binary pulsar */
704 /* because XLALBinaryPulsarDeltaTNew only returns delta t, not tdot, we need to */
705 /* calculate above and below the start and end frequencies to find gradient. */
706
707 /* These are denoted for start(S)/end(E) and plus(P)/minus(M) 1 second. */
708
709 if ( PulsarCheckParam( pulparams[h], "BINARY" ) ) {
710 BinaryPulsarInput binInputS, binInputM, binInputE, binInputSP, binInputSM, binInputEP, binInputEM;
711 BinaryPulsarOutput binOutputS, binOutputM, binOutputE, binOutputSP, binOutputSM, binOutputEP, binOutputEM;
712
713 /* set up times used for binary input */
714 binInputS.tb = timestamp + emitS.deltaT;
715 binInputE.tb = timestamp + 1. / deltaf + emitE.deltaT;
716 binInputM.tb = timestamp + 1. / ( 2.*deltaf ) + emit.deltaT;
717
718 /* Make assumption that emitS, emitE earthS and earthE are constant over two seconds */
719 binInputSM.tb = timestamp + emitS.deltaT - 1;
720 binInputSP.tb = timestamp + emitS.deltaT + 1;
721 binInputEM.tb = timestamp + 1. / deltaf + emitE.deltaT - 1;
722 binInputEP.tb = timestamp + 1. / deltaf + emitE.deltaT + 1;
723
724 binInputS.earth = earthS;
725 binInputE.earth = earthE;
726 binInputM.earth = earth;
727
728 binInputSP.earth = earthS;
729 binInputEP.earth = earthE;
730 binInputSM.earth = earthS;
731 binInputEM.earth = earthE;
732
733 XLALBinaryPulsarDeltaTNew( &binOutputS, &binInputS, pulparams[h] );
734 XLALBinaryPulsarDeltaTNew( &binOutputE, &binInputE, pulparams[h] );
735 XLALBinaryPulsarDeltaTNew( &binOutputM, &binInputM, pulparams[h] );
736
737 XLALBinaryPulsarDeltaTNew( &binOutputSM, &binInputSM, pulparams[h] );
738 XLALBinaryPulsarDeltaTNew( &binOutputEM, &binInputEM, pulparams[h] );
739 XLALBinaryPulsarDeltaTNew( &binOutputSP, &binInputSP, pulparams[h] );
740 XLALBinaryPulsarDeltaTNew( &binOutputEP, &binInputEP, pulparams[h] );
741
742 /* Add the barycentering and binary terms together to get total deltat */
743 totaldeltaT = emit.deltaT + binOutputM.deltaT;
744 totaldeltaTstart = emitS.deltaT + binOutputS.deltaT;
745 totaldeltaTend = emitE.deltaT + binOutputE.deltaT;
746
747 /* Add the barycentering and binary terms together to get total tdot */
748 totaltDot = emit.tDot + ( binOutputE.deltaT - binOutputS.deltaT ) * deltaf;
749 totaltDotend = emitE.tDot + ( binOutputEP.deltaT - binOutputEM.deltaT ) / 2;
750 totaltDotstart = emitS.tDot + ( binOutputSP.deltaT - binOutputSM.deltaT ) / 2;
751 } else {
752 /* If not a binary, then relative motion effects are only due to detector motion */
753 totaldeltaT = emit.deltaT;
754 totaldeltaTend = emitE.deltaT;
755 totaldeltaTstart = emitS.deltaT;
756
757 totaltDot = emit.tDot;
758 totaltDotend = emitE.tDot;
759 totaltDotstart = emitS.tDot;
760 }
761
762 /* Calculate relevant time difference to epoch for use in calculations */
763 REAL8 pepoch = PulsarGetREAL8ParamOrZero( pulparams[h], "PEPOCH" );
764 tdt = timestamp - pepoch + 1. / ( 2.*deltaf ) + totaldeltaT;
765 tdtS = timestamp - pepoch + totaldeltaTstart;
766 tdtE = timestamp - pepoch + 1. / ( 2.*deltaf ) + totaldeltaTend;
767
768 /* SFT start time - parfile epoch + 1/2 SFT length + barycentre timeshift */
769
770 fnew = 0., phaseShift = 0.;
771 REAL8 fstart = 0., fend = 0.;
772 REAL8 dtpow = 1., dtspow = 1., dtepow = 1.;
773 const REAL8Vector *freqs = PulsarGetREAL8VectorParam( pulparams[h], "F" );
774 for ( UINT4 k = 0; k < freqs->length; k++ ) {
775 /* calculate frequency at the centre of the SFT */
776 fnew += ( freqs->data[k] * dtpow ) / gsl_sf_fact( k );
777 dtpow *= tdt;
778
779 /* calculate frequency at start of SFT */
780 fstart += ( freqs->data[k] * dtspow ) / gsl_sf_fact( k );
781 dtspow *= tdtS;
782
783 /* calculate frequency at end of SFT */
784 fend += ( freqs->data[k] * dtepow ) / gsl_sf_fact( k );
785 dtepow *= tdtE;
786
787 /* Calculate difference in phase between beginning of SFT and the epoch. */
788 phaseShift += ( freqs->data[k] * dtpow ) / gsl_sf_fact( k + 1 );
789 }
790 fnew *= ( inputParams.freqfactor * totaltDot );
791 fstart *= ( inputParams.freqfactor * totaltDotstart );
792 fend *= ( inputParams.freqfactor * totaltDotend );
793 phaseShift = LAL_TWOPI * fmod( inputParams.freqfactor * phaseShift, 1. );
794
795 if ( ( fnew < inputParams.startF ) || ( fnew > inputParams.endF ) ) {
796 fprintf( stderr, "Pulsar %s has frequency %.4f outside of the frequency range %f-%f at time %.0f\n",
797 PulsarGetStringParam( pulparams[h], "NAME" ), fnew, inputParams.startF, inputParams.endF, timestamp );
798 continue;
799 }
800
801 /* calculate effective fdot including the frequency derivative obtained from the barycentering */
802 f1new = ( fend - fstart ) * deltaf;
803
804 sqrtf1new = sqrt( fabs( f1new ) ); /* square root of the absolute value of f1 for use in calculations */
805 REAL8 signf1new = f1new / fabs( f1new ); /* sign of f1 for use in calculations */
806
807 UINT4 dataLength = 0, dpNum = 0;
808
809 /* Load data into RAM as will be reusing multiple times */
810 dataLength = ( UINT4 )( ROUND( ( fnew + inputParams.bandwidth / 2. - SFTdat->data->f0 ) / deltaf
811 - ( fnew - inputParams.bandwidth / 2. - SFTdat->data->f0 ) / deltaf ) );
812
813 /* check data load */
814 if ( dataLength < 1 ) {
815 XLALPrintError( "Error setting length of data" );
816 continue;
817 }
818
819 /* initialise and create various vectors for use in calculations */
820 REAL8Vector *dataFreqs = NULL, *ReDp = NULL, *ImDp = NULL, *ReMu = NULL, *ImMu = NULL, *MuMu = NULL;
821 UINT4Vector *dpUsed = NULL;
822
823 if ( ( ( dataFreqs = XLALCreateREAL8Vector( dataLength ) ) == NULL ) || /* datapoint frequency value*/
824 ( ( ReDp = XLALCreateREAL8Vector( dataLength ) ) == NULL ) || /* Data Real Value*/
825 ( ( ImDp = XLALCreateREAL8Vector( dataLength ) ) == NULL ) || /* Data Imag Value*/
826 ( ( ReMu = XLALCreateREAL8Vector( dataLength ) ) == NULL ) || /* Real Value of model used to calculate least squares*/
827 ( ( ImMu = XLALCreateREAL8Vector( dataLength ) ) == NULL ) || /* Imag Value of model used to calculate least squares*/
828 ( ( MuMu = XLALCreateREAL8Vector( dataLength ) ) == NULL ) || /* Normalisation factor - sum of squares of model , with some constants that can be cancelled*/
829 ( ( dpUsed = XLALCreateUINT4Vector( dataLength ) ) == NULL ) ) { /* Whether the datapoint is used or not - residual removal etc */
830 XLALPrintError( "Error, allocating data memory.\n" );
831 exit( 1 );
832 }
833
834 REAL8 ReStdDev = 0., ImStdDev = 0., StdDev = 0., ReStdDevSum = 0., ImStdDevSum = 0.;
835
836 /* Load the data into the ReDp, ImDp vectors and set dataFreqs */
837 /* While doing this, add the square of each in order to obtain the std deviation of the data */
838 for ( datapoint = ROUND( ( fnew - inputParams.bandwidth / 2. - SFTdat->data->f0 ) / deltaf );
839 datapoint <= ROUND( ( fnew + inputParams.bandwidth / 2. - SFTdat->data->f0 ) / deltaf ); datapoint++ ) {
840 dpNum = ( UINT4 )( datapoint - ROUND( ( fnew - inputParams.bandwidth / 2. - SFTdat->data->f0 ) / deltaf ) );
841
842 ReDp->data[dpNum] = creal( SFTdat->data[sftnum].data->data[datapoint] );
843
844 ImDp->data[dpNum] = cimag( SFTdat->data[sftnum].data->data[datapoint] );
845
846 dataFreqs->data[dpNum] = SFTdat->data->f0 + datapoint * deltaf;
847
848 ReStdDevSum += ( ReDp->data[dpNum] ) * ( ReDp->data[dpNum] );
849
850 ImStdDevSum += ( ImDp->data[dpNum] ) * ( ImDp->data[dpNum] );
851
852 } /* close datapoint loop*/
853
854 /* Obtain the std deviation combined from Real and Imaginary parts of SFT */
855
856 ReStdDev = sqrt( ReStdDevSum / ( dataLength - 1 ) );
857 ImStdDev = sqrt( ImStdDevSum / ( dataLength - 1 ) );
858
859 StdDev = sqrt( ReStdDev * ReStdDev + ImStdDev * ImStdDev ) / 2;
860
861 /* if removing outliers, remove any data point whihc is outside of closest 10 datapoints with real or */
862 /* imaginary parts above threshold number of standard deviations. */
863 for ( dpNum = 0; dpNum < dataFreqs->length; dpNum++ ) {
864 if ( ( ( fabs( ReDp->data[dpNum] ) < 2 * inputParams.stddevthresh * StdDev &&
865 fabs( ImDp->data[dpNum] ) < 2 * inputParams.stddevthresh * StdDev ) || /* Keep if datapoint is within 4 std devs */
866 inputParams.stddevthresh == 0 ) || /* keep if threshold not set */
867 ( fabs( dataFreqs->data[dpNum] - fnew ) < 5 * deltaf ) ) { /* ensure keeping closest 10 points to fnew to keep signals */
868 dpUsed->data[dpNum] = 1;
869 } else {
870 /* If not within these limits, set datapoint as not used. */
871 dpUsed->data[dpNum] = 0;
872 }
873 } /* close datapoint loop*/
874
875 /* Data has now been loaded into ReDp/ImDp and dpUsed set to remove initial outliers */
876
877 /* Set values of Model used for interpolation */
878 /* Check if there is a significant signal spread over frequencies over the course of the SFT */
879 if ( fabs( f1new ) / ( deltaf * deltaf ) > 0.1 ) { /*i.e. if signal is spread more than 0.1 bins over the course of the SFT */
880 for ( dpNum = 0; dpNum < dataLength; dpNum++ ) {
881
882 if ( dpUsed->data[dpNum] == 1 ) {
883 REAL8 FresPlusC = 0., FresMinC = 0., FresPlusS = 0., FresMinS = 0., delPhase = 0.;
884
885 delPhase = phaseShift - LAL_PI * ( fnew - dataFreqs->data[dpNum] ) * ( fnew - dataFreqs->data[dpNum] ) / f1new
886 - LAL_PI * ( dataFreqs->data[dpNum] ) / deltaf;
887
888 /* calculate fresnel integrals for start and end of SFT */
889 XLALFresnel( &FresPlusC, &FresPlusS, ( ( fnew - dataFreqs->data[dpNum] )*LAL_SQRT2 * sqrtf1new / f1new + sqrtf1new / LAL_SQRT2 / deltaf ) );
890 XLALFresnel( &FresMinC, &FresMinS, ( ( fnew - dataFreqs->data[dpNum] )*LAL_SQRT2 * sqrtf1new / f1new - sqrtf1new / LAL_SQRT2 / deltaf ) );
891
892 ReMu->data[dpNum] = 1 / ( LAL_SQRT2 * sqrtf1new ) * ( cos( delPhase ) * ( FresPlusC - FresMinC )
893 - signf1new * sin( delPhase ) * ( FresPlusS - FresMinS ) );
894
895 ImMu->data[dpNum] = 1 / ( LAL_SQRT2 * sqrtf1new ) * ( sin( delPhase ) * ( FresPlusC - FresMinC )
896 + signf1new * cos( delPhase ) * ( FresPlusS - FresMinS ) );
897
898 MuMu->data[dpNum] = 1 / ( 2 * fabs( f1new ) ) * ( ( FresPlusC - FresMinC ) * ( FresPlusC - FresMinC )
899 + ( FresPlusS - FresMinS ) * ( FresPlusS - FresMinS ) );
900 } /* close if datapoint used statement */
901
902 } /* close datapoint loop */
903
904 } else { /* signal is not spread */
905
906 /* Check if calculated pulsar frequency lies on an bin or within 0.1% (SFT bin value is 99.9998% of true value) */
907 /* of the SFT to a frequency bin.*/
908 /* If it does, just perform the phaseshift, including phase shift from change in frequency. */
909 /* (This is essentially to avoid any "divide by zero" problems) */
910
911 if ( fmod( ( fnew - SFTdat->data->f0 ), deltaf ) < ( 0.01 * deltaf ) ||
912 fmod( ( fnew - SFTdat->data->f0 ), deltaf ) > ( 0.99 * deltaf ) ) {
913 for ( dpNum = 0; dpNum < dataLength; dpNum++ ) {
914
915 if ( dpNum == ( UINT4 )( ROUND( inputParams.bandwidth / ( 2.*deltaf ) ) ) ) {
916 ReMu->data[dpNum] = cos( phaseShift - LAL_PI * dataFreqs->data[dpNum] / deltaf ) / deltaf;
917 ImMu->data[dpNum] = sin( phaseShift - LAL_PI * dataFreqs->data[dpNum] / deltaf ) / deltaf;
918 MuMu->data[dpNum] = 1 / ( deltaf * deltaf );
919 }/* close 'if on signal frequency bin' statement */
920 else {
921 ReMu->data[dpNum] = 0;
922 ImMu->data[dpNum] = 0;
923 MuMu->data[dpNum] = 0;
924 } /* close 'else a different bin' statement */
925
926 } /* close 'for each datapoint' loop*/
927
928 } /* close 'if on a bin' statement */
929 else { /* signal is not on a bin - interpolate with a sinc*/
930
931 for ( dpNum = 0; dpNum < dataLength; dpNum++ ) {
932
933 if ( dpUsed->data[dpNum] == 1 ) { /* if the datapoint is not an outlier */
934
935 ReMu->data[dpNum] = 1 / ( deltaf ) * SINC( ( dataFreqs->data[dpNum] - fnew ) / deltaf )
936 * cos( phaseShift - LAL_PI * dataFreqs->data[dpNum] / deltaf );
937
938 ImMu->data[dpNum] = 1 / ( deltaf ) * SINC( ( dataFreqs->data[dpNum] - fnew ) / deltaf )
939 * sin( phaseShift - LAL_PI * dataFreqs->data[dpNum] / deltaf );
940
941 MuMu->data[dpNum] = 1. / ( deltaf * deltaf ) * SINC( ( dataFreqs->data[dpNum] - fnew ) / deltaf )
942 * SINC( ( dataFreqs->data[dpNum] - fnew ) / deltaf );
943
944 } /* close 'if the datapoint is not an outlier' statement */
945
946 } /* close datapoint loop */
947
948 } /* close 'else interpolate with a sinc' statement */
949
950 } /* close 'else is not spread' statement */
951
952 /* At this point we have now loaded the data, set the model and performed the first outlier removal */
953 /* now we calculate Bk and sigmak, and perform residual outlier removal */
954
955 /* initialise and create residual and signal best estimate vectors*/
956 REAL8Vector *ReResiduals = NULL, *ImResiduals = NULL, *ReHf = NULL, *ImHf = NULL;
957
958 if ( ( ( ReResiduals = XLALCreateREAL8Vector( dataLength ) ) == NULL ) || /* Value of residuals in Real part of SFT */
959 ( ( ImResiduals = XLALCreateREAL8Vector( dataLength ) ) == NULL ) || /* Value of residuals in Imag part of SFT **/
960 ( ( ReHf = XLALCreateREAL8Vector( dataLength ) ) == NULL ) || /* Expected Value in Real part of SFT given interpolated Bk */
961 ( ( ImHf = XLALCreateREAL8Vector( dataLength ) ) == NULL ) ) { /* Expected Value in Imag part of SFT given interpolated Bk */
962 XLALPrintError( "Error, allocating residuals memory.\n" );
963 exit( 1 );
964 }
965
966 /* Residual noise value needs to be initialised outside the while loop as it will be outputted */
967 REAL8 ResStdDev = 0.;
968
969 /* repeat the following section until all outliers have been removed */
970 UINT4 numReduced = 1; /* i.e. flag to say that the number of datapoints has been reduced */
971
972 /* Iterate through Bk and sigmak calculation, and residual outlier removal so that */
973 /* Bk and sigmak are recalculated if any of the datapoints have been removed. */
974 while ( numReduced ) {
975 UINT4 dpCountStart = 0, dpCountEnd = 0;
976 /* count the number of datapoints being used to begin with */
977 for ( dpNum = 0; dpNum < dataLength; dpNum++ ) {
978 dpCountStart += dpUsed->data[dpNum];
979 }
980
981 /* Perform least squares fit*/
982 for ( dpNum = 0; dpNum < dataLength; dpNum++ ) {
983
984 if ( dpUsed->data[dpNum] == 1 ) { /* use only datapoints which have not been removed */
985
986 REAL8 ReVal = 0., ImVal = 0;
987
988 ReVal = ReDp->data[dpNum] * ReMu->data[dpNum] + ImDp->data[dpNum] * ImMu->data[dpNum];
989 ImVal = ImDp->data[dpNum] * ReMu->data[dpNum] - ReDp->data[dpNum] * ImMu->data[dpNum];
990 AbsSquaredWeightSum += MuMu->data[dpNum];
991
992 UnnormalisedInterpolatedRealValue += ReVal;
993 UnnormalisedInterpolatedImagValue += ImVal;
994
995 } /* close if datapoint is used statement */
996
997 }/* close datapoint loop*/
998
999 /* Combine sums to find interpolated values*/
1000 InterpolatedRealValue = UnnormalisedInterpolatedRealValue / AbsSquaredWeightSum;
1001 InterpolatedImagValue = UnnormalisedInterpolatedImagValue / AbsSquaredWeightSum;
1002
1003 /* Reset the following to zero in case this is the (>1)th loop through the while statement */
1004 REAL8 ResReStdDev = 0., ResImStdDev = 0., ResReStdDevSum = 0., ResImStdDevSum = 0.;
1005
1006 /* Residual cleaning */
1007 for ( dpNum = 0; dpNum < dataLength; dpNum++ ) {
1008
1009 if ( dpUsed->data[dpNum] == 1 ) {
1010
1011 /* calculate estimated signal in SFT from B_k and model */
1012 ReHf->data[dpNum] = InterpolatedRealValue * ReMu->data[dpNum] - InterpolatedImagValue * ImMu->data[dpNum];
1013 ImHf->data[dpNum] = InterpolatedImagValue * ReMu->data[dpNum] + InterpolatedRealValue * ImMu->data[dpNum];
1014
1015 /* take this from the atual SFT to obtain residuals */
1016 ReResiduals->data[dpNum] = ReDp->data[dpNum] - ReHf->data[dpNum];
1017 ImResiduals->data[dpNum] = ImDp->data[dpNum] - ImHf->data[dpNum];
1018
1019 ResReStdDevSum += ReResiduals->data[dpNum] * ReResiduals->data[dpNum];
1020 ResImStdDevSum += ImResiduals->data[dpNum] * ImResiduals->data[dpNum];
1021
1022 } /* close if datapoint is used statement */
1023
1024 }/* close datapoint loop*/
1025
1026 /* calculate standard deviation of the residuals - average or real and imag parts */
1027 ResReStdDev = sqrt( ResReStdDevSum / ( dpCountStart - 1 ) );
1028 ResImStdDev = sqrt( ResImStdDevSum / ( dpCountStart - 1 ) );
1029
1030 /* calculate combined standard deviation */
1031 ResStdDev = sqrt( ResReStdDev * ResReStdDev + ResImStdDev * ResImStdDev ) / 2;
1032
1033 /* Use residual standard deviation to remove datapoints - always keep closest 4 datapoints */
1034 for ( dpNum = 0; dpNum < dataFreqs->length; dpNum++ ) {
1035
1036 if ( dpUsed->data[dpNum] == 1 ) { /* dont change currently unused points */
1037
1038 if ( ( fabs( ReResiduals->data[dpNum] ) < inputParams.stddevthresh * ( ResStdDev ) &&
1039 fabs( ImResiduals->data[dpNum] ) < inputParams.stddevthresh * ( ResStdDev ) ) || /* Keep if datapoint is within std devs */
1040 inputParams.stddevthresh == 0 || /* keep if threshold not set */
1041 ( fabs( dataFreqs->data[dpNum] - fnew ) < 2 * deltaf ) ) { /* ensure keeping closest 4 points to fnew to keep signals */
1042 dpUsed->data[dpNum] = 1;
1043 } else {
1044 dpUsed->data[dpNum] = 0;
1045 }
1046 }/* close if datapoint is used loop*/
1047
1048 } /* close datapoint loop*/
1049
1050 /* count the number of datapoints being used after cleaning */
1051 for ( dpNum = 0; dpNum < dataLength; dpNum++ ) {
1052 dpCountEnd += dpUsed->data[dpNum];
1053 }
1054
1055
1056 if ( dpCountStart == dpCountEnd ) {
1057 numReduced = 0; /* if no data points have been removed, exit the while loop */
1058 }
1059
1060 } /* Close outlier removal while loop */
1061
1062 /* Destroy data and model structures to prevent memory leak */
1063 XLALDestroyREAL8Vector( ReResiduals );
1064 XLALDestroyREAL8Vector( ImResiduals );
1065 XLALDestroyREAL8Vector( dataFreqs );
1066 XLALDestroyREAL8Vector( ReDp );
1067 XLALDestroyREAL8Vector( ImDp );
1068 XLALDestroyREAL8Vector( ReMu );
1069 XLALDestroyREAL8Vector( ImMu );
1070 XLALDestroyREAL8Vector( MuMu );
1071 XLALDestroyREAL8Vector( ReHf );
1072 XLALDestroyREAL8Vector( ImHf );
1073 XLALDestroyUINT4Vector( dpUsed );
1074
1075 /* print time, ReBk, ImBk and noise estimate to output file*/
1076 fprintf( fpout[h], "%.0f\t%.6e\t%.6e\t%.6e\n", timestamp + 1. / ( 2.*deltaf ), InterpolatedRealValue
1077 , InterpolatedImagValue, ResStdDev * deltaf * LAL_SQRT2 );
1078
1079 } /* close pulsar loop */
1080
1081 }/* close SFTnum loop */
1082 if ( inputParams.Timing ) {
1083 gettimeofday( &timeInterpolateEnd, NULL );
1084 tInterpolate = ( REAL8 )timeInterpolateEnd.tv_usec * 1.e-6 + ( REAL8 )timeInterpolateEnd.tv_sec - ( REAL8 )timeInterpolateStart.tv_usec * 1.e-6 - ( REAL8 )timeInterpolateStart.tv_sec;
1085 }
1086 /* destroy SFT catalogue to prevent memory leak*/
1087 XLALDestroySFTCatalog( catalog );
1088 /* print timing information to stderr */
1089 if ( inputParams.Timing ) {
1090 fprintf( stderr, " done. Number of SFTs = %d. Obtaining Catalog took %.5fs, SFT Load took %.5fs, Interpolation took %.5fs.\n",
1091 ( INT4 )( SFTdat->length ), tCatalog, tLoad, tInterpolate );
1092 TotalInterTime += tInterpolate;
1093 TotalLoadTime += tLoad;
1094 } else {
1095 fprintf( stderr, " done.\n" );
1096 }
1097
1098 /* close all the output files */
1099 for ( h = 0; h < numpulsars; h++ ) {
1100 fclose( fpout[h] );
1101 }
1102
1103 XLALDestroySFTVector( SFTdat );
1104 segcount++; /* move to next segment */
1105 }/* close segment loop */
1106
1107 XLALSegListFree( seglist );
1108
1109 if ( sftlalcache != NULL ) {
1110 XLALDestroyCache( sftlalcache ); // destroy lalcache of SFTs
1111 }
1112
1113 REAL8 tPre = 0., tPul = 0.;
1114 if ( inputParams.Timing ) {
1115 tPre = ( REAL8 )timePreEnd.tv_usec * 1.e-6 + ( REAL8 )timePreEnd.tv_sec - ( REAL8 )timePreStart.tv_usec * 1.e-6 - ( REAL8 )timePreStart.tv_sec;
1116 tPul = ( REAL8 )timePulEnd.tv_usec * 1.e-6 + ( REAL8 )timePulEnd.tv_sec - ( REAL8 )timePulStart.tv_usec * 1.e-6 - ( REAL8 )timePulStart.tv_sec;
1117 }
1118
1119 fprintf( stderr, "Spectral Interpolation Complete.\n" );
1120
1121 /* print timing information */
1122 if ( inputParams.Timing ) {
1123 fprintf( stderr, ":\nPre-Interpolation things took %.5fs, of which source parameter load time was %.5fs\nTotal Number of SFTs = %d\nTotal catalog time %.5fs\nTotal SFT Load time %.5fs\nTotal Interpolation time %.5fs.\n", tPre, tPul, TotalNSFTs, TotalCatalogTime, TotalLoadTime, TotalInterTime );
1124 }
1125
1126 if ( inputParams.stddevthresh != 0 ) { /* do the Bk outlier removal routine if the threshold has been set */
1127 fprintf( stderr, "\nPerforming Outlier Removal routine with noise threshold of %.5f", inputParams.stddevthresh );
1128 struct timeval timeORStart, timeOREnd;
1129 if ( inputParams.Timing ) {
1130 gettimeofday( &timeORStart, NULL );
1131 }
1132
1133 for ( h = 0; h < numpulsars; h++ ) {
1134 FILE *BkFile = NULL;
1135 BkFile = fopen( outputfilenames->data[h], "r" );
1136 if ( BkFile == NULL ) {
1137 XLALPrintError( "Error opening file" );
1138 }
1139
1140 long offset;
1141 CHAR jnkstr[FILENAME_MAXLEN]; /* junk string to contain comment lines */
1142
1143 INT4Vector *timeStamp = NULL;
1144 REAL8Vector *ReData = NULL, *ImData = NULL, *NData = NULL;
1145
1146 /* Make structures for storing data */
1147 timeStamp = XLALCreateINT4Vector( TotalNSFTs );
1148 ReData = XLALCreateREAL8Vector( TotalNSFTs );
1149 ImData = XLALCreateREAL8Vector( TotalNSFTs );
1150 NData = XLALCreateREAL8Vector( TotalNSFTs );
1151
1152 /* Read in data */
1153 UINT4 k = 0;
1154 while ( !feof( BkFile ) && k < TotalNSFTs ) {
1155 offset = ftell( BkFile ); /* get current position of file stream */
1156
1157 if ( fscanf( BkFile, "%s", jnkstr ) == EOF ) { /* scan in value and check if == to # */
1158 break;
1159 } /* break if there is an extra line at the end of file containing
1160 nothing */
1161
1162 fseek( BkFile, offset, SEEK_SET ); /* if line doesn't start with a # then it is
1163 data */
1164 if ( fscanf( BkFile, "%d%lf%lf%lf", &timeStamp->data[k], &ReData->data[k],
1165 &ImData->data[k], &NData->data[k] ) == EOF ) {
1166 break;
1167 }
1168 k++;
1169 }
1170
1171 fclose( BkFile );
1172
1173 FILE *BkFileOut = NULL;
1174 BkFileOut = fopen( outputfilenames->data[h], "w" );
1175 UINT4 p = 0;
1176 UINT4 startlen = ReData->length;
1177 REAL8 meanNoiseEst = 0, meanAbsValue = 0.;
1178
1179 /* Set up file buffer so that file system is not overloaded on output */
1180 /* buffer will be 1Mb */
1181 if ( setvbuf( BkFileOut, NULL, _IOFBF, 0x10000 ) ) {
1182 fprintf( stderr, "Warning: Unable to set output file buffer!" );
1183 }
1184
1185 for ( p = 0; p < NData->length; p++ ) {
1186 meanAbsValue += sqrt( ReData->data[p] * ReData->data[p] + ImData->data[p] * ImData->data[p] ) / NData->length;
1187 meanNoiseEst += NData->data[p] / NData->length;
1188 }
1189
1190 /* remove all datapoints with Re(Bk),Im(Bk) or SigK more than stddevthresh */
1191 UINT4 j = 0; /* to count the length of the new data, to resize later */
1192 for ( p = 0; p < startlen; p++ ) {
1193 if ( fabs( ReData->data[p] ) < meanAbsValue * inputParams.stddevthresh &&
1194 fabs( ImData->data[p] ) < meanAbsValue * inputParams.stddevthresh &&
1195 NData->data[p] < meanNoiseEst * inputParams.stddevthresh ) {
1196 ReData->data[j] = ReData->data[p];
1197 ImData->data[j] = ImData->data[p];
1198 NData->data[j] = NData->data[p];
1199 timeStamp->data[j] = timeStamp->data[p];
1200 j++;
1201 }
1202 }
1203 if ( j != startlen ) { /* if any datapoints have been removed, resize the vectors and rerun outlier removal */
1204 if ( ( ReData = XLALResizeREAL8Vector( ReData, j ) ) == NULL ||
1205 ( ImData = XLALResizeREAL8Vector( ImData, j ) ) == NULL ||
1206 ( NData = XLALResizeREAL8Vector( NData, j ) ) == NULL ||
1207 ( timeStamp = XLALResizeINT4Vector( timeStamp, j ) ) == NULL ) {
1208 XLALPrintError( "Error resizing thresholded data.\n" );
1209 }
1210 for ( p = 0; p < NData->length; p++ ) {
1211 meanNoiseEst += NData->data[p] / NData->length;
1212 meanAbsValue += sqrt( ReData->data[p] * ReData->data[p] + ImData->data[p] * ImData->data[p] ) / NData->length;
1213 }
1214
1215 j = 0; /* reset counters */
1216 for ( p = 0; p < ReData->length; p++ ) {
1217 if ( fabs( ReData->data[p] ) < meanAbsValue * inputParams.stddevthresh &&
1218 fabs( ImData->data[p] ) < meanAbsValue * inputParams.stddevthresh &&
1219 NData->data[p] < meanNoiseEst * inputParams.stddevthresh ) {
1220 ReData->data[j] = ReData->data[p];
1221 ImData->data[j] = ImData->data[p];
1222 NData->data[j] = NData->data[p];
1223 timeStamp->data[j] = timeStamp->data[p];
1224 j++;
1225 }
1226 }
1227 if ( j != ReData->length ) {
1228 if ( ( ReData = XLALResizeREAL8Vector( ReData, j ) ) == NULL ||
1229 ( ImData = XLALResizeREAL8Vector( ImData, j ) ) == NULL ||
1230 ( NData = XLALResizeREAL8Vector( NData, j ) ) == NULL ||
1231 ( timeStamp = XLALResizeINT4Vector( timeStamp, j ) ) == NULL ) {
1232 XLALPrintError( "Error resizing thresholded data.\n" );
1233 }
1234 }
1235 }
1236
1237 /* Output the t, B_k (and sigma_k) to the file */
1238 /* (no buffer needed this time as looping through pulsars rather than SFTs) */
1239 for ( p = 0; p < ReData->length; p++ ) {
1240
1241 fprintf( BkFileOut, "%d\t%.6e\t%.6e\t%.6e\n", timeStamp->data[p], ReData->data[p]
1242 , ImData->data[p], NData->data[p] );
1243 }
1244
1245 fclose( BkFileOut );
1246
1247 /* destroy vectors to prvent memory leaks */
1248 XLALDestroyINT4Vector( timeStamp );
1249 XLALDestroyREAL8Vector( ReData );
1250 XLALDestroyREAL8Vector( ImData );
1251 XLALDestroyREAL8Vector( NData );
1252
1253 }
1254 fprintf( stderr, " done.\n" );
1255 if ( inputParams.Timing ) {
1256 gettimeofday( &timeOREnd, NULL );
1257 }
1258 if ( inputParams.Timing ) {
1259 REAL8 tOR = ( REAL8 )timeOREnd.tv_usec * 1.e-6 + ( REAL8 )timeOREnd.tv_sec - ( REAL8 )timeORStart.tv_usec * 1.e-6 - ( REAL8 )timeORStart.tv_sec;
1260 fprintf( stderr, "Outlier Removal took %.5fs", tOR );
1261 }
1262 }
1263
1264 if ( inputParams.gzip ) {
1265 /* gzip the output files */
1266 for ( h = 0; h < numpulsars; h++ ) {
1267 if ( XLALGzipTextFile( outputfilenames->data[h] ) != XLAL_SUCCESS ) { // gzip it
1268 XLALPrintError( "Error... problem gzipping the output file.\n" );
1269 }
1270 }
1271 }
1272
1273 for ( h = 0; h < numpulsars; h++ ) {
1274 // free par files
1275 PulsarClearParams( pulparams[h] );
1276 }
1277 XLALFree( pulparams );
1278
1279 XLALDestroyStringVector( outputfilenames );
1280
1281 if ( inputParams.Timing ) {
1282 gettimeofday( &timeEndTot, NULL );
1283 REAL8 tTot = ( REAL8 )timeEndTot.tv_usec * 1e-6 + ( REAL8 )timeEndTot.tv_sec - ( REAL8 )timePreTot.tv_usec * 1e-6 - ( REAL8 )timePreTot.tv_sec;
1284 fprintf( stderr, "Total time taken: %.5fs\n", tTot );
1285 }
1286
1287 return 0;
1288}
1289
1290
1291void get_input_args( InputParams *inputParams, int argc, char *argv[] )
1292{
1293 struct option long_options[] = {
1294 { "help", no_argument, 0, 'h' },
1295 { "ifo", required_argument, 0, 'i' },
1296 { "sft-cache", required_argument, 0, 'F' },
1297 { "sft-lalcache", required_argument, 0, 'C' },
1298 { "sft-loc", required_argument, 0, 'L' },
1299 { "param-dir", required_argument, 0, 'd' },
1300 { "param-file", required_argument, 0, 'P' },
1301 { "psr-name", required_argument, 0, 'N' },
1302 { "output-dir", required_argument, 0, 'o' },
1303 { "ephem-dir", required_argument, 0, 'e' },
1304 { "seg-file", required_argument, 0, 'l' },
1305 { "start-freq", required_argument, 0, 'S' },
1306 { "end-freq", required_argument, 0, 'E' },
1307 { "freq-factor", required_argument, 0, 'm' },
1308 { "bandwidth", required_argument, 0, 'b' },
1309 { "min-seg-length", required_argument, 0, 'M' },
1310 { "max-seg-length", required_argument, 0, 'Z' },
1311 { "starttime", required_argument, 0, 's' },
1312 { "finishtime", required_argument, 0, 'f' },
1313 { "stddevthresh", required_argument, 0, 'T' },
1314 { "output-timing", no_argument, NULL, 't' },
1315 { "geocentreFlag", no_argument, NULL, 'g' },
1316 { "baryFlag", no_argument, NULL, 'B' },
1317 { "gzip", no_argument, NULL, 'G' },
1318 { 0, 0, 0, 0 }
1319 };
1320
1321 char args[] = "hi:F:C:L:d:P:N:o:e:l:S:E:m:b:M:Z:s:f:T:ntgBG";
1322
1323 /* set defaults */
1324 inputParams->freqfactor = 2.0; /* default is to look for gws at twice the pulsar spin frequency */
1325 inputParams->bandwidth = 0.3; /* Default is a 0.3Hz bandwidth search */
1326 inputParams->geocentre = 0; /* Default is not to look at the geocentre */
1327 inputParams->minSegLength = 1800; /* Default minimum segment length is 1800s */
1328 inputParams->maxSegLength = INFINITY; /* Default maximum segment length is INFINITY */
1329 inputParams->baryFlag = 0; /* Default is to perform barycentring routine */
1330 inputParams->endF = 0.; /* in order to check if the end frequency is set */
1331 inputParams->startF = 0.; /* in order to check if the start frequency is set*/
1332 inputParams->parfileflag = 0.; /* in order to check if the Parfile is set */
1333 inputParams->pardirflag = 0.; /* in order to check if the Parfile directory is set*/
1334 inputParams->nameset = 0; /* flag in order to check if pulsar name is set*/
1335 inputParams->startTime = 0.; /* Start time not set - use zero */
1336 inputParams->endTime = INFINITY; /* end time not set - use infinity */
1337 inputParams->Timing = 0.; /* default not to output timing info to stderr */
1338 inputParams->cacheDir = 0; /* default is that directory flag is zero */
1339 inputParams->cacheFile = 0; /* default that file flag is zero */
1340 inputParams->lalcacheFile = 0; /* default that that lalcache file flag is zero */
1341 inputParams->stddevthresh = 0.; /* default not to do outlier removal */
1342 inputParams->gzip = 0; /* default not to gzip the output files */
1343
1344 /* get input arguments */
1345 while ( 1 ) {
1346 int option_index = 0;
1347 int c;
1348
1349 c = getopt_long( argc, argv, args, long_options, &option_index );
1350 if ( c == -1 ) { /* end of options */
1351 break;
1352 }
1353
1354 switch ( c ) {
1355 case 'h': /* Help */
1356 fprintf( stderr, USAGE );
1357 exit( 1 );
1358 case 'i': /* interferometer */
1359 snprintf( inputParams->ifo, sizeof( inputParams->ifo ), "%s", optarg );
1360 break;
1361 case 'g': /* geocentre flag */
1362 inputParams->geocentre = 1;
1363 break;
1364 case 'B': /* barycentre flag */
1365 inputParams->baryFlag = 1;
1366 break;
1367 case 'm': /* frequency Factor */
1368 inputParams->freqfactor = atof( optarg );
1369 break;
1370 case 'S': /* start frequency of the SFTs */
1371 inputParams->startF = atof( optarg );
1372 break;
1373 case 'E': /* end frequency of the SFTs */
1374 inputParams->endF = atof( optarg );
1375 break;
1376 case 'd': /* pulsar par file directory */
1377 snprintf( inputParams->pulsarDir, sizeof( inputParams->pulsarDir ), "%s",
1378 optarg );
1379 inputParams->pardirflag = 1;
1380 break;
1381 case 'e': /* ephemeris directory */
1382 snprintf( inputParams->ephemdir, sizeof( inputParams->ephemdir ), "%s",
1383 optarg );
1384 break;
1385 case 'P': /* Pulsar File*/
1386 snprintf( inputParams->paramfile, sizeof( inputParams->paramfile ), "%s",
1387 optarg );
1388 inputParams->parfileflag = 1;
1389 break;
1390 case 'N': /* Pulsar name set */
1391 snprintf( inputParams->PSRname, sizeof( inputParams->PSRname ), "%s",
1392 optarg );
1393 inputParams->nameset = 1;
1394 break;
1395 case 'F': /* filepath to SFTs */
1396 snprintf( inputParams->filePattern, sizeof( inputParams->filePattern ), "%s",
1397 optarg );
1398 inputParams->cacheFile = 1;
1399 break;
1400 case 'C': /* file path to lalcache file containing SFTs */
1401 snprintf( inputParams->filePattern, sizeof( inputParams->filePattern ), "%s",
1402 optarg );
1403 inputParams->lalcacheFile = 1;
1404 break;
1405 case 'L': /* filepath to SFTcache directory */
1406 snprintf( inputParams->filePattern, sizeof( inputParams->filePattern ), "%s",
1407 optarg );
1408 inputParams->cacheDir = 1;
1409 break;
1410 case 'l': /* segment file */
1411 snprintf( inputParams->segfile, sizeof( inputParams->segfile ), "%s",
1412 optarg );
1413 break;
1414 case 'o': /* output-dir */
1415 snprintf( inputParams->outputdir, sizeof( inputParams->outputdir ), "%s",
1416 optarg );
1417 break;
1418 case 'b': /* bandwidth */
1419 inputParams->bandwidth = atof( optarg );
1420 break;
1421 case 's': /* Start time of the analysis */
1422 inputParams->startTime = atof( optarg );
1423 break;
1424 case 'f': /* finish time of the analysis */
1425 inputParams->endTime = atof( optarg );
1426 break;
1427 case 'T': /* standard deviation threshold for outlier removal */
1428 inputParams->stddevthresh = atof( optarg );
1429 break;
1430 case 'M': /* Minimum Segment Length Allowed */
1431 inputParams->minSegLength = atof( optarg );
1432 break;
1433 case 'Z': /* Maximum segment length allowed (use to stop too may SFTs being read at once) */
1434 inputParams->maxSegLength = atof( optarg );
1435 break;
1436 case 't': /* write timing values to stderr */
1437 inputParams->Timing = 1;
1438 break;
1439 case 'G': /* gzip the output files */
1440 inputParams->gzip = 1;
1441 break;
1442 case '?':
1443 fprintf( stderr, "unknown error while parsing options\n" );
1444 break;
1445 default:
1446 fprintf( stderr, "unknown error while parsing options\n" );
1447 break;
1448 }
1449 }
1450}
1451
1452
1453/* Function to compute the Fresnel Integrals, [largely from Numerical Recipes in C (1992)]*/
1455{
1456
1457 INT4 k, n, odd;
1458 REAL8 a, absx, fact, sign, sum, sumc, sums, term, test;
1459 COMPLEX16 b, cc, d, h, del, cs;
1460
1461 REAL8 FC = 0., FS = 0.;
1462
1463 absx = fabs( x );
1464
1465 if ( absx < sqrt( XLAL_FRESNEL_FPMIN ) ) { /* If x is less than the minimum floating point value */
1466 FS = 0.0; /* then approximate accordingly*/
1467 FC = absx;
1468 } else if ( absx <= XLAL_FRESNEL_XMIN ) { /* If x is less than specified value, then use the power series*/
1469 sum = sums = 0.0;
1470 sumc = absx;
1471 sign = 1.0;
1472 fact = LAL_PI_2 * absx * absx;
1473 odd = 1;
1474 term = absx;
1475 n = 3;
1476 for ( k = 1; k < XLAL_FRESNEL_MAXIT; k++ ) {
1477 term *= fact / k;
1478 sum += sign * term / n;
1479 test = fabs( sum ) * XLAL_FRESNEL_EPS;
1480 if ( odd ) {
1481 sign = -sign;
1482 sums = sum;
1483 sum = sumc;
1484 } else {
1485 sumc = sum;
1486 sum = sums;
1487 }
1488 if ( term < test ) {
1489 break;
1490 }
1491 odd = !odd;
1492 n += 2;
1493 }
1494 if ( k > XLAL_FRESNEL_MAXIT ) {
1495 XLALPrintError( "XLAL_Fresnel failed in series" );
1497 }
1498 FS = sums;
1499 FC = sumc;
1500 } else { /* If x is greater than specified value, then use the continued fraction*/
1501 b = 1.0 - I * LAL_PI * absx * absx;
1502 cc = 1.0 / XLAL_FRESNEL_FPMIN;
1503 d = h = 1. / b;
1504 n = -1;
1505 for ( k = 2; k < XLAL_FRESNEL_MAXIT; k++ ) {
1506 n += 2;
1507 a = -n * ( n + 1 );
1508 b += 4.0;
1509 d = 1. / ( a * d + b );
1510 cc = b + a / cc;
1511 del = cc * d;
1512 h = h * del;
1513 if ( fabs( creal( del ) - 1.0 ) + fabs( cimag( del ) ) < XLAL_FRESNEL_EPS ) {
1514 break;
1515 }
1516 }
1517 if ( k > XLAL_FRESNEL_MAXIT ) {
1518 XLALPrintError( "XLAL_Fresnel failed in continued fraction" );
1520 }
1521 h = ( absx - I * absx ) * h;
1522 cs = ( 0.5 + I * 0.5 ) * ( 1. - h * ( cos( LAL_PI_2 * absx * absx ) + I * sin( LAL_PI_2 * absx * absx ) ) );
1523 FC = creal( cs );
1524 FS = cimag( cs );
1525 }
1526 if ( x < 0 ) { /* Use antisymmetry if x is negative */
1527 FS = -FS;
1528 FC = -FC;
1529 }
1530 C = memcpy( C, &FC, sizeof( REAL8 ) );
1531 S = memcpy( S, &FS, sizeof( REAL8 ) );
1532 return XLAL_SUCCESS;
1533}
void XLALBinaryPulsarDeltaTNew(BinaryPulsarOutput *output, BinaryPulsarInput *input, PulsarParameters *params)
function to calculate the binary system delay using new parameter structure
#define FS
int j
int k
#define c
#define no_argument
#define required_argument
const REAL8Vector * PulsarGetREAL8VectorParam(const PulsarParameters *pars, const CHAR *name)
Return a REAL8Vector parameter.
REAL8 PulsarGetREAL8ParamOrZero(const PulsarParameters *pars, const CHAR *name)
Return a REAL8 parameter if it exists, otherwise return zero.
int PulsarCheckParam(const PulsarParameters *pars, const CHAR *name)
Check for the existence of the parameter name in the PulsarParameters structure.
PulsarParameters * XLALReadTEMPOParFile(const CHAR *pulsarAndPath)
Read in the parameters from a TEMPO(2) parameter file into a PulsarParameters structure.
void PulsarClearParams(PulsarParameters *pars)
Free all the parameters from a PulsarParameters structure.
void PulsarAddParam(PulsarParameters *pars, const CHAR *name, void *value, PulsarParamType type)
Add a parameter and value to the PulsarParameters structure.
REAL8 PulsarGetREAL8Param(const PulsarParameters *pars, const CHAR *name)
Return a REAL8 parameter.
const CHAR * PulsarGetStringParam(const PulsarParameters *pars, const CHAR *name)
Return a string parameter.
REAL8 PulsarGetREAL8VectorParamIndividual(const PulsarParameters *pars, const CHAR *name)
Return an individual REAL8 value from a REAL8Vector parameter.
@ PULSARTYPE_string_t
@ PULSARTYPE_REAL8_t
#define SINC(x)
static SFTConstraints empty_SFTConstraints
int main(int argc, char **argv)
static LIGOTimeGPS empty_LIGOTimeGPS
void get_input_args(InputParams *inputParams, int argc, char *argv[])
#define ROUND(x)
INT4 XLALFresnel(REAL8 *C, REAL8 *S, REAL8 x)
#define XLAL_FRESNEL_EPS
#define XLAL_FRESNEL_XMIN
#define XLAL_FRESNEL_MAXIT
#define FILENAME_MAXLEN
#define XLAL_FRESNEL_FPMIN
#define fscanf
#define fprintf
double e
int XLALGzipTextFile(const char *path)
TimeCorrectionData * XLALInitTimeCorrections(const CHAR *timeCorrectionFile)
An XLAL interface for reading a time correction file containing a table of values for converting betw...
EphemerisData * XLALInitBarycenter(const CHAR *earthEphemerisFile, const CHAR *sunEphemerisFile)
XLAL interface to reading ephemeris files 'earth' and 'sun', and return ephemeris-data in old backwar...
int XLALBarycenter(EmissionTime *emit, const BarycenterInput *baryinput, const EarthState *earth)
Transforms from detector arrival time in GPS (as specified in the LIGOTimeGPS structure) to pulse em...
int XLALBarycenterEarthNew(EarthState *earth, const LIGOTimeGPS *tGPS, const EphemerisData *edat, const TimeCorrectionData *tdat, TimeCorrectionType ttype)
Computes the position and orientation of the Earth, at some arrival time, but unlike XLALBarycenterEa...
TimeCorrectionType
Enumerated type denoting the time system type to be produced in the solar system barycentring routine...
Definition: LALBarycenter.h:72
@ TIMECORRECTION_ORIGINAL
Definition: LALBarycenter.h:78
@ TIMECORRECTION_TCB
Definition: LALBarycenter.h:75
@ TIMECORRECTION_TDB
Definition: LALBarycenter.h:74
void XLALDestroyCache(LALCache *cache)
int XLALCacheUniq(LALCache *cache)
LALCache * XLALCacheImport(const char *fname)
LALCache * XLALCacheDuplicate(const LALCache *cache)
int XLALCacheSieve(LALCache *cache, INT4 t0, INT4 t1, const char *srcregex, const char *dscregex, const char *urlregex)
#define LAL_PI_2
#define LAL_PI
#define LAL_TWOPI
#define LAL_SQRT2
double complex COMPLEX16
double REAL8
char CHAR
uint32_t UINT4
int32_t INT4
void * XLALMalloc(size_t n)
void * XLALRealloc(void *p, size_t n)
void XLALFree(void *p)
char char * XLALStringDuplicate(const char *s)
int char * XLALStringAppend(char *s, const char *append)
static const INT4 a
const LALDetector * XLALGetSiteInfo(const CHAR *name)
Find the site geometry-information 'LALDetector' for given a detector name (or prefix).
Definition: SFTnaming.c:218
void XLALDestroySFTVector(SFTVector *vect)
XLAL interface to destroy an SFTVector.
Definition: SFTtypes.c:300
void XLALDestroySFTCatalog(SFTCatalog *catalog)
Free an 'SFT-catalogue'.
Definition: SFTcatalog.c:329
LALSegList * XLALReadSegmentsFromFile(const char *fname)
Function to read a segment list from given filename, returns a sorted LALSegList.
LALStringVector * XLALFindFiles(const CHAR *globstring)
Returns a list of filenames matching the input argument, which may be one of the following:
Definition: FindFiles.c:61
SFTVector * XLALLoadSFTs(const SFTCatalog *catalog, REAL8 fMin, REAL8 fMax)
Load the given frequency-band [fMin, fMax) (half-open) from the SFT-files listed in the SFT-'catalogu...
Definition: SFTfileIO.c:87
SFTCatalog * XLALSFTdataFind(const CHAR *file_pattern, const SFTConstraints *constraints)
Find the list of SFTs matching the file_pattern and satisfying the given constraints,...
Definition: SFTcatalog.c:71
int XLALSegListFree(LALSegList *seglist)
void XLALDestroyStringVector(LALStringVector *vect)
LALStringVector * XLALAppendString2Vector(LALStringVector *vect, const CHAR *string)
REAL8Vector * XLALResizeREAL8Vector(REAL8Vector *vector, UINT4 length)
void XLALDestroyUINT4Vector(UINT4Vector *vector)
INT4Vector * XLALResizeINT4Vector(INT4Vector *vector, UINT4 length)
INT4Vector * XLALCreateINT4Vector(UINT4 length)
void XLALDestroyINT4Vector(INT4Vector *vector)
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
UINT4Vector * XLALCreateUINT4Vector(UINT4 length)
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EIO
XLAL_EFAILED
XLAL_FAILURE
LIGOTimeGPS * XLALGPSSetREAL8(LIGOTimeGPS *epoch, REAL8 t)
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
n
Basic input structure to LALBarycenter.c.
REAL8 alpha
Source right ascension in ICRS J2000 coords (radians).
REAL8 dInv
1/(distance to source), in 1/sec.
LIGOTimeGPS tgps
input GPS arrival time.
REAL8 delta
Source declination in ICRS J2000 coords (radians)
LALDetector site
detector site info.
structure containing the input parameters for the binary delay function
REAL8 tb
Time of arrival (TOA) at the SSB.
EarthState earth
The current Earth state (for e.g.
structure containing the output parameters for the binary delay function
REAL8 deltaT
deltaT to add to TDB in order to account for binary
COMPLEX8Sequence * data
A vector of COMPLEX8FrequencySeries.
COMPLEX8FrequencySeries * data
Pointer to the data array.
UINT4 length
Number of elements in array.
COMPLEX8 * data
Basic output structure of LALBarycenterEarth.c.
Basic output structure produced by LALBarycenter.c.
REAL8 deltaT
(TDB) - (GPS)
REAL8 tDot
d(emission time in TDB)/d(arrival time in GPS)
This structure contains all information about the center-of-mass positions of the Earth and Sun,...
INT4 * data
CHAR paramfile[256]
CHAR ephemdir[FILENAME_MAXLEN]
CHAR segfile[256]
CHAR filePattern[FILENAME_MAXLEN]
CHAR * url
UINT4 length
LALCacheEntry * list
REAL8 location[3]
LALFrDetector frDetector
CHAR prefix[3]
LIGOTimeGPS end
LIGOTimeGPS start
UINT4 length
LALSeg * segs
The PulsarParameters structure to contain a set of pulsar parameters.
REAL8 * data
An "SFT-catalogue": a vector of SFTdescriptors, as returned by XLALSFTdataFind()
Definition: SFTfileIO.h:238
SFTDescriptor * data
array of data-entries describing matched SFTs
Definition: SFTfileIO.h:243
UINT4 length
number of SFTs in catalog
Definition: SFTfileIO.h:242
'Constraints' for SFT-matching: which detector, within which time-stretch and which timestamps exactl...
Definition: SFTfileIO.h:212
CHAR * detector
2-char channel-prefix describing the detector (eg 'H1', 'H2', 'L1', 'G1' etc)
Definition: SFTfileIO.h:213
LIGOTimeGPS * maxStartTime
only include SFTs whose epoch is < maxStartTime
Definition: SFTfileIO.h:215
LIGOTimeGPS * minStartTime
only include SFTs whose epoch is >= minStartTime
Definition: SFTfileIO.h:214
SFTtype header
SFT-header info.
Definition: SFTfileIO.h:228
UINT4 numBins
number of frequency-bins in this SFT
Definition: SFTfileIO.h:232
This structure will contain a vector of time corrections used during conversion from TT to TDB/TCB/Te...
UINT4 * data