LALPulsar 7.1.1.1-eeff03c
GCTtoplist.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Bernd Machenschalk, Reinhard Prix, Holger Pletsch
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#include "config.h"
21
22#include <math.h>
23#include <stdio.h>
24#ifdef HAVE_UNISTD_H
25#include <unistd.h>
26#endif
27
28#include <lal/StringInput.h>
29#include <lal/AVFactories.h>
30#include <lal/LALConstants.h>
31#include <lal/LALStdio.h>
32#include <lal/LogPrintf.h>
33#include <lal/HeapToplist.h>
34#include <lal/LALPulsarVCSInfo.h>
35
36#include "GCTtoplist.h"
37
38/* Windows specifics */
39#ifdef _WIN32
40
41/* errno */
42#include <errno.h>
43#ifndef _doserrno
44extern int _doserrno;
45#endif
46
47/* snprintf */
48#define snprintf _snprintf
49
50/* fsync */
51#define fsync _commit
52#define fileno _fileno
53
54/* finite */
55#include <float.h>
56#define finite isfinite
57
58#else /* WIN32 */
59
60/* errno */
61#include <errno.h>
62
63/* this is defined in C99 and *should* be in math.h. Long term
64 protect this with a HAVE_FINITE */
65int finite( double );
66
67#endif /* WIN32 */
68
69#ifdef DEBUG_SORTING
70static FILE *debugfp = NULL;
71#endif
72
73/* define min macro if not already defined */
74#ifndef min
75#define min(a,b) ((a)<(b)?(a):(b))
76#endif
77
78/* maximum number of succesive failures before switching off syncing */
79#define SYNC_FAIL_LIMIT 5
80
81/* output file column headings string, globally defined from HSGCT program */
83
84/* local prototypes */
86static int _atomic_write_gctFstat_toplist_to_file( toplist_t *l, const char *filename, UINT4 *checksum, int write_done );
87static int print_gctFstatline_to_str( GCTtopOutputEntry fline, char *buf, int buflen );
88static int print_single_detector_quantities_to_str( char *outstr, size_t outstrlen, const REAL4 *quantities, const UINT4 numDetectors );
89static int print_single_detector_intval_to_str( char *outstr, size_t outstrlen, const INT4 *quantities, const UINT4 numDetectors );
90static int write_gctFstat_toplist_item_to_fp( GCTtopOutputEntry fline, FILE *fp, UINT4 *checksum );
91
92/* ordering function for sorting the list */
93static int gctFstat_result_order( const void *a, const void *b )
94{
95#ifdef DEBUG_SORTING
96 if ( debugfp )
97 fprintf( debugfp, "%20lf %20lf\n%20lf %20lf\n%20lf %20lf\n%20lf %20lf\n\n",
98 ( ( const GCTtopOutputEntry * )a )->Freq, ( ( const GCTtopOutputEntry * )b )->Freq,
99 ( ( const GCTtopOutputEntry * )a )->Alpha, ( ( const GCTtopOutputEntry * )b )->Alpha,
100 ( ( const GCTtopOutputEntry * )a )->Delta, ( ( const GCTtopOutputEntry * )b )->Delta,
101 ( ( const GCTtopOutputEntry * )a )->F1dot, ( ( const GCTtopOutputEntry * )b )->F1dot );
102#endif
103 if ( ( ( const GCTtopOutputEntry * )a )->Freq < ( ( const GCTtopOutputEntry * )b )->Freq ) {
104 return -1;
105 } else if ( ( ( const GCTtopOutputEntry * )a )->Freq > ( ( const GCTtopOutputEntry * )b )->Freq ) {
106 return 1;
107 } else if ( ( ( const GCTtopOutputEntry * )a )->Alpha < ( ( const GCTtopOutputEntry * )b )->Alpha ) {
108 return -1;
109 } else if ( ( ( const GCTtopOutputEntry * )a )->Alpha > ( ( const GCTtopOutputEntry * )b )->Alpha ) {
110 return 1;
111 } else if ( ( ( const GCTtopOutputEntry * )a )->Delta < ( ( const GCTtopOutputEntry * )b )->Delta ) {
112 return -1;
113 } else if ( ( ( const GCTtopOutputEntry * )a )->Delta > ( ( const GCTtopOutputEntry * )b )->Delta ) {
114 return 1;
115 } else if ( ( ( const GCTtopOutputEntry * )a )->F1dot < ( ( const GCTtopOutputEntry * )b )->F1dot ) {
116 return -1;
117 } else if ( ( ( const GCTtopOutputEntry * )a )->F1dot > ( ( const GCTtopOutputEntry * )b )->F1dot ) {
118 return 1;
119 } else {
120 return 0;
121 }
122}
123
124/* ordering function defining the toplist: SORT BY avTwoF */
125static int gctFstat_smaller( const void *a, const void *b )
126{
127#ifdef DEBUG_SORTING
128 if ( debugfp )
129 fprintf( debugfp, "%20lf %20lf\n%20u %20u\n\n",
130 ( ( const GCTtopOutputEntry * )a )->avTwoF, ( ( const GCTtopOutputEntry * )b )->avTwoF,
131 ( ( const GCTtopOutputEntry * )a )->nc, ( ( const GCTtopOutputEntry * )b )->nc );
132#endif
133 if ( ( ( const GCTtopOutputEntry * )a )->avTwoF < ( ( const GCTtopOutputEntry * )b )->avTwoF ) {
134 return 1;
135 } else if ( ( ( const GCTtopOutputEntry * )a )->avTwoF > ( ( const GCTtopOutputEntry * )b )->avTwoF ) {
136 return -1;
137 } else if ( ( ( const GCTtopOutputEntry * )a )->nc < ( ( const GCTtopOutputEntry * )b )->nc ) {
138 return 1;
139 } else if ( ( ( const GCTtopOutputEntry * )a )->nc > ( ( const GCTtopOutputEntry * )b )->nc ) {
140 return -1;
141 } else {
142 return ( gctFstat_result_order( a, b ) );
143 }
144}
145
146
147/* ordering function defining the toplist: SORT BY Numbercount */
148static int gctNC_smaller( const void *a, const void *b )
149{
150#ifdef DEBUG_SORTING
151 if ( debugfp )
152 fprintf( debugfp, "%20lf %20lf\n%20u %20u\n\n",
153 ( ( const GCTtopOutputEntry * )a )->avTwoF, ( ( const GCTtopOutputEntry * )b )->avTwoF,
154 ( ( const GCTtopOutputEntry * )a )->nc, ( ( const GCTtopOutputEntry * )b )->nc );
155#endif
156 if ( ( ( const GCTtopOutputEntry * )a )->nc < ( ( const GCTtopOutputEntry * )b )->nc ) {
157 return 1;
158 } else if ( ( ( const GCTtopOutputEntry * )a )->nc > ( ( const GCTtopOutputEntry * )b )->nc ) {
159 return -1;
160 } else if ( ( ( const GCTtopOutputEntry * )a )->avTwoF < ( ( const GCTtopOutputEntry * )b )->avTwoF ) {
161 return 1;
162 } else if ( ( ( const GCTtopOutputEntry * )a )->avTwoF > ( ( const GCTtopOutputEntry * )b )->avTwoF ) {
163 return -1;
164 } else {
165 return ( gctFstat_result_order( a, b ) );
166 }
167}
168
169
170/* ordering function defining the toplist: SORT BY BSGL */
171static int gctBSGL_smaller( const void *a, const void *b )
172{
173#ifdef DEBUG_SORTING
174 if ( debugfp )
175 fprintf( debugfp, "%20lf %20lf\n%20lf %20lf\n\n",
176 ( ( const GCTtopOutputEntry * )a )->avTwoF, ( ( const GCTtopOutputEntry * )b )->avTwoF,
177 ( ( const GCTtopOutputEntry * )a )->log10BSGL, ( ( const GCTtopOutputEntry * )b )->log10BSGL );
178#endif
179 if ( ( ( const GCTtopOutputEntry * )a )->log10BSGL < ( ( const GCTtopOutputEntry * )b )->log10BSGL ) {
180 return 1;
181 } else if ( ( ( const GCTtopOutputEntry * )a )->log10BSGL > ( ( const GCTtopOutputEntry * )b )->log10BSGL ) {
182 return -1;
183 } else if ( ( ( const GCTtopOutputEntry * )a )->avTwoF < ( ( const GCTtopOutputEntry * )b )->avTwoF ) {
184 return 1;
185 } else if ( ( ( const GCTtopOutputEntry * )a )->avTwoF > ( ( const GCTtopOutputEntry * )b )->avTwoF ) {
186 return -1;
187 } else {
188 return ( gctFstat_result_order( a, b ) );
189 }
190}
191/* ordering function defining the toplist: SORT BY BSGLtL */
192static int gctBSGLtL_smaller( const void *a, const void *b )
193{
194#ifdef DEBUG_SORTING
195 if ( debugfp )
196 fprintf( debugfp, "%20lf %20lf\n%20lf %20lf\n\n",
197 ( ( const GCTtopOutputEntry * )a )->avTwoF, ( ( const GCTtopOutputEntry * )b )->avTwoF,
198 ( ( const GCTtopOutputEntry * )a )->log10BSGLtL, ( ( const GCTtopOutputEntry * )b )->log10BSGLtL );
199#endif
200 if ( ( ( const GCTtopOutputEntry * )a )->log10BSGLtL < ( ( const GCTtopOutputEntry * )b )->log10BSGLtL ) {
201 return 1;
202 } else if ( ( ( const GCTtopOutputEntry * )a )->log10BSGLtL > ( ( const GCTtopOutputEntry * )b )->log10BSGLtL ) {
203 return -1;
204 } else if ( ( ( const GCTtopOutputEntry * )a )->avTwoF < ( ( const GCTtopOutputEntry * )b )->avTwoF ) {
205 return 1;
206 } else if ( ( ( const GCTtopOutputEntry * )a )->avTwoF > ( ( const GCTtopOutputEntry * )b )->avTwoF ) {
207 return -1;
208 } else {
209 return ( gctFstat_result_order( a, b ) );
210 }
211}
212/* ordering function defining the toplist: SORT BY BtSGLtL */
213static int gctBtSGLtL_smaller( const void *a, const void *b )
214{
215#ifdef DEBUG_SORTING
216 if ( debugfp )
217 fprintf( debugfp, "%20lf %20lf\n%20lf %20lf\n\n",
218 ( ( const GCTtopOutputEntry * )a )->avTwoF, ( ( const GCTtopOutputEntry * )b )->avTwoF,
219 ( ( const GCTtopOutputEntry * )a )->log10BtSGLtL, ( ( const GCTtopOutputEntry * )b )->log10BtSGLtL );
220#endif
221 if ( ( ( const GCTtopOutputEntry * )a )->log10BtSGLtL < ( ( const GCTtopOutputEntry * )b )->log10BtSGLtL ) {
222 return 1;
223 } else if ( ( ( const GCTtopOutputEntry * )a )->log10BtSGLtL > ( ( const GCTtopOutputEntry * )b )->log10BtSGLtL ) {
224 return -1;
225 } else if ( ( ( const GCTtopOutputEntry * )a )->avTwoF < ( ( const GCTtopOutputEntry * )b )->avTwoF ) {
226 return 1;
227 } else if ( ( ( const GCTtopOutputEntry * )a )->avTwoF > ( ( const GCTtopOutputEntry * )b )->avTwoF ) {
228 return -1;
229 } else {
230 return ( gctFstat_result_order( a, b ) );
231 }
232}
233
234
235/* functions for qsort based on the above ordering functions */
236static int gctFstat_final_qsort( const void *a, const void *b )
237{
238 void const *const *pa = ( void const * const * )a;
239 void const *const *pb = ( void const * const * )b;
240 return ( gctFstat_result_order( *pa, *pb ) );
241}
242
243
244/* creates a toplist with length elements,
245 returns -1 on error (usually out of memory), else 0 */
246int create_gctFstat_toplist( toplist_t **tl, UINT8 length, SortBy_t whatToSortBy )
247{
248#ifdef DEBUG_SORTING
249 if ( !debugfp ) {
250 debugfp = fopen( "debug_sort", "w" );
251 }
252#endif
253
254 if ( whatToSortBy == SORTBY_NC ) {
255 return ( create_toplist( tl, length, sizeof( GCTtopOutputEntry ), gctNC_smaller ) );
256 } else if ( whatToSortBy == SORTBY_BSGL ) {
257 return ( create_toplist( tl, length, sizeof( GCTtopOutputEntry ), gctBSGL_smaller ) );
258 } else if ( whatToSortBy == SORTBY_BSGLtL ) {
259 return ( create_toplist( tl, length, sizeof( GCTtopOutputEntry ), gctBSGLtL_smaller ) );
260 } else if ( whatToSortBy == SORTBY_BtSGLtL ) {
261 return ( create_toplist( tl, length, sizeof( GCTtopOutputEntry ), gctBtSGLtL_smaller ) );
262 } else {
263 return ( create_toplist( tl, length, sizeof( GCTtopOutputEntry ), gctFstat_smaller ) );
264 }
265
266}
267
268/* frees the space occupied by the toplist
269 NOTE: toplist must not contain any allocated structs */
271{
272 free_toplist( l );
273} /* free_gctFstat_toplist() */
274
275
276/* Inserts an element in to the toplist either if there is space left
277 or the element is larger than the smallest element in the toplist.
278 In the latter case, remove the smallest element from the toplist and
279 look for the now smallest one.
280 Returns 1 if the element was actually inserted, 0 if not. */
282{
283 if ( !tl ) {
284 return 0;
285 } else {
286 return ( insert_into_toplist( tl, ( void * ) elem ) );
287 }
288}
289
290/* (q)sort the toplist according to the sorting function. */
292{
293 qsort( l->heap, l->elems, sizeof( char * ), gctFstat_final_qsort );
294}
295
296/* Prints a Toplist line to a string buffer.
297 Separate function to assure consistency of output and reduced precision for sorting */
298static int print_gctFstatline_to_str( GCTtopOutputEntry fline, char *buf, int buflen )
299{
300
301 /* add extra output field for line-robust statistic BSGL */
302 char BSGLstr[256] = ""; /* defaults to empty */
303 if ( fline.log10BSGL > -LAL_REAL4_MAX * 0.2 ) { /* if --computeBSGL=FALSE, the log10BSGL field was initialised to -LAL_REAL4_MAX; if --computeBSGL=TRUE, it is at least -LAL_REAL4_MAX*0.1 */
304 snprintf( BSGLstr, sizeof( BSGLstr ), " %.6f", fline.log10BSGL );
305 print_single_detector_quantities_to_str( BSGLstr, sizeof( BSGLstr ), fline.avTwoFX, fline.numDetectors );
306 } /* if fline.log10BSGL */
307
308 /* add extra output fields for line-robust statistic BSGLtL and BtSGLtL */
309 char BSGLtLstr[256] = ""; /* defaults to empty */
310 if ( fline.log10BSGLtL > -LAL_REAL4_MAX * 0.2 ) {
311 snprintf( BSGLtLstr, sizeof( BSGLtLstr ), " %.6f", fline.log10BSGLtL );
312 }
313 char BtSGLtLstr[256] = ""; /* defaults to empty */
314 if ( fline.log10BtSGLtL > -LAL_REAL4_MAX * 0.2 ) {
315 snprintf( BtSGLtLstr, sizeof( BtSGLtLstr ), " %.6f", fline.log10BtSGLtL );
316 }
317
318 /* add extra output fields for max2F over segments */
319 char maxTwoFstr[256] = ""; /* defaults to empty */
320 if ( fline.maxTwoFl >= 0.0 ) { /* this was initialised to -1.0 and is only >= 0.0 if actually computed in inner loop */
321 snprintf( maxTwoFstr, sizeof( maxTwoFstr ), " %.6f %d", fline.maxTwoFl, fline.maxTwoFlSeg );
322 print_single_detector_quantities_to_str( maxTwoFstr, sizeof( maxTwoFstr ), fline.maxTwoFXl, fline.numDetectors );
323 print_single_detector_intval_to_str( maxTwoFstr, sizeof( maxTwoFstr ), fline.maxTwoFXlSeg, fline.numDetectors );
324 }
325
326 /* add extra output fields for recalculated statistics */
327 char recalcStr[256] = ""; /* defaults to empty */
328 if ( fline.avTwoFrecalc >= 0.0 ) { /* this was initialised to -1.0 and is only >= 0.0 if actually recomputed in recalcToplistStats step */
329 char buf0[256];
330 snprintf( recalcStr, sizeof( recalcStr ), " %.6f", fline.avTwoFrecalc );
331 if ( fline.log10BSGLrecalc > -LAL_REAL4_MAX * 0.2 ) { /* if --computeBSGL=FALSE, the log10BSGLrecalc field was initialised to -LAL_REAL4_MAX; if --computeBSGL=TRUE, it is at least -LAL_REAL4_MAX*0.1 */
332 snprintf( buf0, sizeof( buf0 ), " %.6f", fline.log10BSGLrecalc );
333 strcat( recalcStr, buf0 );
334 } /* if ( fline.log10BSGL > -LAL_REAL4_MAX*0.2 ) */
335 print_single_detector_quantities_to_str( recalcStr, sizeof( recalcStr ), fline.avTwoFXrecalc, fline.numDetectors );
336
337 if ( fline.twoFloudestSeg >= 0.0 ) { /* this was initialised to -1.0 and is only >= 0.0 if actually recomputed in recalcToplistStats step */
338 snprintf( buf0, sizeof( buf0 ), " %d %.6f", fline.loudestSeg, fline.twoFloudestSeg );
339 strcat( recalcStr, buf0 );
340 print_single_detector_quantities_to_str( recalcStr, sizeof( recalcStr ), fline.twoFXloudestSeg, fline.numDetectors );
341 } /* if ( fline.twoFloudestSeg >= 0.0 ) */
342
343 if ( fline.log10BSGLtLrecalc > -LAL_REAL4_MAX * 0.2 ) { /* if --computeBSGL=FALSE, the log10BSGLtLrecalc field was initialised to -LAL_REAL4_MAX; if --computeBSGL=TRUE, it is at least -LAL_REAL4_MAX*0.1 */
344 snprintf( buf0, sizeof( buf0 ), " %.6f", fline.log10BSGLtLrecalc );
345 strcat( recalcStr, buf0 );
346 } /* if ( fline.log10BSGLtL > -LAL_REAL4_MAX*0.2 ) */
347
348 } /* if avTwoFrecalc */
349
350 int len;
351 if ( fline.have_f3dot ) {
352 len = snprintf( buf, buflen,
353 "%.16g %.13g %.13g %.13g %.13g %.13g %d %.6f%s%s%s%s%s\n",
354 fline.Freq,
355 fline.Alpha,
356 fline.Delta,
357 fline.F1dot,
358 fline.F2dot,
359 fline.F3dot,
360 fline.nc,
361 fline.avTwoF,
362 BSGLstr,
363 BSGLtLstr,
364 BtSGLtLstr,
365 maxTwoFstr,
366 recalcStr
367 );
368 } else {
369 len = snprintf( buf, buflen,
370 "%.16g %.13g %.13g %.13g %.13g %d %.6f%s%s%s%s%s\n",
371 fline.Freq,
372 fline.Alpha,
373 fline.Delta,
374 fline.F1dot,
375 fline.F2dot,
376 fline.nc,
377 fline.avTwoF,
378 BSGLstr,
379 BSGLtLstr,
380 BtSGLtLstr,
381 maxTwoFstr,
382 recalcStr
383 );
384 }
385 return len;
386
387} /* print_gctFstatline_to_str() */
388
389static int print_single_detector_quantities_to_str( char *outstr, size_t outstrlen, const REAL4 *quantities, const UINT4 numDetectors )
390{
391 const char *fn = __func__;
392
393 UINT4 len = strlen( outstr );
394
395 char buf0[outstrlen];
396 for ( UINT4 X = 0; X < numDetectors ; X ++ ) {
397 snprintf( buf0, sizeof( buf0 ), " %.6f", quantities[X] );
398 len = strlen( outstr ) + strlen( buf0 ) + 1;
399 if ( len > outstrlen ) {
400 XLALPrintError( "%s: assembled output string too long! (%d > %zu)\n", fn, len, outstrlen );
401 break; /* we can't really terminate with error in this function, but at least we avoid crashing */
402 }
403 strcat( outstr, buf0 );
404 } /* for X < numDet */
405
406 return len;
407
408} /* print_single_detector_quantities_to_str() */
409
410
411static int print_single_detector_intval_to_str( char *outstr, size_t outstrlen, const INT4 *quantities, const UINT4 numDetectors )
412{
413 const char *fn = __func__;
414
415 UINT4 len = strlen( outstr );
416
417 char buf0[outstrlen];
418 for ( UINT4 X = 0; X < numDetectors ; X ++ ) {
419 snprintf( buf0, sizeof( buf0 ), " %d", quantities[X] );
420 len = strlen( outstr ) + strlen( buf0 ) + 1;
421 if ( len > outstrlen ) {
422 XLALPrintError( "%s: assembled output string too long! (%d > %zu)\n", fn, len, outstrlen );
423 break; /* we can't really terminate with error in this function, but at least we avoid crashing */
424 }
425 strcat( outstr, buf0 );
426 } /* for X < numDet */
427
428 return len;
429
430} /* print_single_detector_quantities_to_str() */
431
432
433
434
435
436/* writes an GCTtopOutputEntry line to an open filepointer.
437 Returns the number of chars written, -1 if in error
438 Updates checksum if given */
439static int write_gctFstat_toplist_item_to_fp( GCTtopOutputEntry fline, FILE *fp, UINT4 *checksum )
440{
441 char linebuf[512];
442 UINT4 i;
443
444 UINT4 length = print_gctFstatline_to_str( fline, linebuf, sizeof( linebuf ) - 1 );
445
446 if ( length > sizeof( linebuf ) - 1 ) {
447 return -1;
448 }
449
450 if ( checksum )
451 for ( i = 0; i < length; i++ ) {
452 *checksum += linebuf[i];
453 }
454
455 XLAL_LAST_ELEM( linebuf ) = '\0';
456
457 return ( fprintf( fp, "%s", linebuf ) );
458}
459
460
461
462/* Reduces the precision of all elements in the toplist which influence the sorting order.
463 To be called before sorting and finally writing out the list */
465{
466 char linebuf[256];
467 print_gctFstatline_to_str( ( *( GCTtopOutputEntry * )line ), linebuf, sizeof( linebuf ) );
468 sscanf( linebuf,
473 "%*s\n",
474 &( ( *( GCTtopOutputEntry * )line ).Freq ),
475 &( ( *( GCTtopOutputEntry * )line ).Alpha ),
476 &( ( *( GCTtopOutputEntry * )line ).Delta ),
477 &( ( *( GCTtopOutputEntry * )line ).F1dot ) );
478}
479
481{
483}
484
485
486/* Writes the toplist to an (already open) filepointer
487 Returns the number of written charactes
488 Returns something <0 on error */
489int write_gctFstat_toplist_to_fp( toplist_t *tl, FILE *fp, UINT4 *checksum )
490{
491 UINT8 c = 0, i;
492 INT8 r;
493 if ( checksum ) {
494 *checksum = 0;
495 }
496 for ( i = 0; i < tl->elems; i++ )
497 if ( ( r = write_gctFstat_toplist_item_to_fp( *( ( GCTtopOutputEntry * )( void * )( tl->heap[i] ) ), fp, checksum ) ) < 0 ) {
498 LogPrintf( LOG_CRITICAL, "Failed to write toplistitem to output fp: %d: %s %" LAL_UINT8_FORMAT "\n",
499 errno, strerror( errno ), i );
500#ifdef _MSC_VER
501 LogPrintf( LOG_CRITICAL, "Windows system call returned: %d\n", _doserrno );
502#endif
503 return ( r );
504 } else {
505 c += r;
506 }
507 return ( c );
508}
509
510
511/* function that does the actual work of atomic_write_gctFstat_toplist_to_file(),
512 appending a %DONE marker if specified (not when called from atomic_write_gctFstat_toplist_to_file().
513 NOTE that the checksum will be a little wrong when %DOME is appended, as this line is not counted */
514static int _atomic_write_gctFstat_toplist_to_file( toplist_t *l, const char *filename, UINT4 *checksum, int write_done )
515{
516 char *tempname;
517 INT4 length = 0;
518 FILE *fpnew;
519 UINT4 s;
520 int ret;
521
522#define TEMP_EXT ".tmp"
523 s = strlen( filename ) + strlen( TEMP_EXT ) + 1;
524 tempname = ( char * )malloc( s );
525 if ( !tempname ) {
526 LogPrintf( LOG_CRITICAL, "Could not allocate new filename\n" );
527 return ( -1 );
528 }
529 strcpy( tempname, filename );
530 strcat( tempname, TEMP_EXT );
531
532 fpnew = fopen( tempname, "wb" );
533 if ( !fpnew ) {
534 LogPrintf( LOG_CRITICAL, "Failed to open temp gctFstat file \"%s\" for writing: %d: %s\n",
535 tempname, errno, strerror( errno ) );
536#ifdef _MSC_VER
537 LogPrintf( LOG_CRITICAL, "Windows system call returned: %d\n", _doserrno );
538#endif
539 free( tempname );
540 return -1;
541 }
542
543 /* when done, write code version and command line as comment in the result file */
544 if ( write_done ) {
545 int a;
546 CHAR *VCSInfoString;
547
548 /* write the version string */
549 if ( ( VCSInfoString = XLALVCSInfoString( lalPulsarVCSInfoList, 0, "%% " ) ) == NULL ) {
550 LogPrintf( LOG_CRITICAL, "XLALVCSInfoString failed.\n" );
551 length = -1;
552 } else {
553 ret = fprintf( fpnew, "%s", VCSInfoString );
554 XLALFree( VCSInfoString );
555 if ( ret < 0 ) {
556 length = ret;
557 } else {
558 length += ret;
559 }
560 }
561
562 /* write the command-line */
563 if ( length >= 0 ) {
564 for ( a = 0; a < global_argc; a++ ) {
565 ret = fprintf( fpnew, "%%%% argv[%d]: '%s'\n", a, global_argv[a] );
566 if ( ret < 0 ) {
567 length = ret;
568 break;
569 } else {
570 length += ret;
571 }
572 }
573 }
574
575 /* write internal toplist sorting as header line
576 NOTE this does not necessarily correspond to the actual output-file row sorting, which by default is done by frequency */
577 if ( length >= 0 ) {
578 const CHAR *sortstat = NULL;
579 if ( l->smaller == gctFstat_smaller ) {
580 sortstat = "<2F>";
581 } else if ( l->smaller == gctNC_smaller ) {
582 sortstat = "nc";
583 } else if ( l->smaller == gctBSGL_smaller ) {
584 sortstat = "BSGL";
585 } else if ( l->smaller == gctBSGLtL_smaller ) {
586 sortstat = "BSGLtL";
587 } else if ( l->smaller == gctBtSGLtL_smaller ) {
588 sortstat = "BtSGLtL";
589 } else {
590 LogPrintf( LOG_CRITICAL, "Failed to write toplist sorting line, toplist is sorted by unknown statistic.\n" );
591 length = -1;
592 }
593 if ( length >= 0 ) {
594 ret = fprintf( fpnew, "%%%% candidates selected by %s as toplist statistic\n", sortstat );
595 if ( ret < 0 ) {
596 length = ret;
597 } else {
598 length += ret;
599 }
600 }
601 }
602
603 /* write column headings line */
604 if ( length >= 0 ) {
605 ret = fprintf( fpnew, "%%%% columns:\n%%%% %s\n", global_column_headings_stringp );
606 if ( ret < 0 ) {
607 length = ret;
608 } else {
609 length += ret;
610 }
611 }
612
613 }
614
615 /* write the actual toplist */
616 if ( length >= 0 ) {
617 ret = write_gctFstat_toplist_to_fp( l, fpnew, checksum );
618 if ( ret < 0 ) {
619 length = ret;
620 } else {
621 length += ret;
622 }
623 }
624
625 /* write the done marker if told to */
626 if ( ( write_done ) && ( length >= 0 ) ) {
627 ret = fprintf( fpnew, "%%DONE\n" );
628 if ( ret < 0 ) {
629 length = ret;
630 } else {
631 length += ret;
632 }
633 }
634
635 fclose( fpnew );
636
637 if ( length < 0 ) {
638 LogPrintf( LOG_CRITICAL, "Failed to write temp gctFstat file \"%s\": %d: %s\n",
639 tempname, errno, strerror( errno ) );
640#ifdef _MSC_VER
641 LogPrintf( LOG_CRITICAL, "Windows system call returned: %d\n", _doserrno );
642#endif
643 free( tempname );
644 return ( length );
645 }
646
647 if ( ( ret = rename( tempname, filename ) ) ) {
648 LogPrintf( LOG_CRITICAL, "Failed to rename gctFstat file to \"%s\": %d: %s(%d)\n",
649 filename, ret, strerror( errno ), errno );
650#ifdef _MSC_VER
651 LogPrintf( LOG_CRITICAL, "Windows system call returned: %d\n", _doserrno );
652#endif
653 free( tempname );
654 return -1;
655 }
656
657 free( tempname );
658 return length;
659}
660
661
662/* New easier checkpointing - simply dump the whole toplist (plus a counter and
663 a checksum) into a binary file.
664 The heap structure array is hard to dump because it's based on pointers, so it
665 is restored after reading the data back in by sorting the list once.
666*/
667
668/** log an I/O error, i.e. source code line no., ferror, errno and strerror, and doserrno on Windows, too */
669#ifndef __func__
670#ifdef __FUNCTION__
671#define __func__ __FUNCTION__
672#else
673#define __func__ ""
674#endif
675#endif
676
677#ifdef _WIN32
678#define LOGIOERROR(mess,filename) \
679 LogPrintf(LOG_CRITICAL, "ERROR: %s %s: %s (%s:%d): doserr:%d, errno:%d: %s\n",\
680 mess,filename,__func__,__FILE__,__LINE__,_doserrno,errno,strerror(errno))
681#else
682#define LOGIOERROR(mess,filename) \
683 LogPrintf(LOG_CRITICAL, "ERROR: %s %s: %s (%s:%d): errno:%d: %s\n",\
684 mess,filename,__func__,__FILE__,__LINE__,errno,strerror(errno))
685#endif
686
687/* dumps toplist to a temporary file, then renames the file to filename */
688int write_gct_checkpoint( const char *filename, toplist_t *tl, toplist_t *t2, toplist_t *t3, UINT4 counter, BOOLEAN do_sync )
689{
690#define TMP_EXT ".tmp"
691 char *tmpfilename;
692 FILE *fp;
693 UINT4 len;
694 UINT4 checksum = 0;
695 static UINT4 sync_fail_counter = 0;
696
697 /* do nothing with an empty filename */
698 if ( !filename ) {
699 LogPrintf( LOG_DETAIL, "%s(): checkpoint filename NULL\n", __func__ );
700 return ( 0 );
701 }
702
703 /* construct temporary filename */
704 len = strlen( filename ) + strlen( TMP_EXT ) + 1;
705 tmpfilename = LALCalloc( len, sizeof( char ) );
706 if ( !tmpfilename ) {
707 LogPrintf( LOG_CRITICAL, "Couldn't allocate tmpfilename\n" );
708 return ( -2 );
709 }
710 strcpy( tmpfilename, filename );
711 strcat( tmpfilename, TMP_EXT );
712
713 /* open tempfile */
714 fp = fopen( tmpfilename, "wb" );
715 if ( !fp ) {
716 LOGIOERROR( "Couldn't open", tmpfilename );
717 LALFree( tmpfilename );
718 return ( -1 );
719 }
720
721 /* write number of elements */
722 len = fwrite( &( tl->elems ), sizeof( tl->elems ), 1, fp );
723 if ( len != 1 ) {
724 LOGIOERROR( "Couldn't write elems to", tmpfilename );
725 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
726 if ( fclose( fp ) ) {
727 LOGIOERROR( "In addition: couldn't close", tmpfilename );
728 }
729 LALFree( tmpfilename );
730 return ( -1 );
731 }
732
733 /* write data */
734 len = fwrite( tl->data, tl->size, tl->elems, fp );
735 if ( len != tl->elems ) {
736 LOGIOERROR( "Couldn't write data to", tmpfilename );
737 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %zu\n", len, tl->elems );
738 if ( fclose( fp ) ) {
739 LOGIOERROR( "In addition: couldn't close", tmpfilename );
740 }
741 LALFree( tmpfilename );
742 return ( -1 );
743 }
744
745 /* dump heap order */
746 for ( UINT4 i = 0; i < tl->elems; i++ ) {
747 UINT4 idx = ( tl->heap[i] - tl->data ) / tl->size;
748 len = fwrite( &idx, sizeof( idx ), 1, fp );
749 if ( len != 1 ) {
750 LOGIOERROR( "Couldn't write idx to", tmpfilename );
751 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
752 if ( fclose( fp ) ) {
753 LOGIOERROR( "In addition: couldn't close", tmpfilename );
754 }
755 LALFree( tmpfilename );
756 return ( -1 );
757 }
758 for ( len = 0; len < sizeof( idx ); len++ ) {
759 checksum += *( ( ( char * )&idx ) + len );
760 }
761 }
762
763 if ( t2 ) {
764 /* write number of elements */
765 len = fwrite( &( t2->elems ), sizeof( t2->elems ), 1, fp );
766 if ( len != 1 ) {
767 LOGIOERROR( "Couldn't write elems to", tmpfilename );
768 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
769 if ( fclose( fp ) ) {
770 LOGIOERROR( "In addition: couldn't close", tmpfilename );
771 }
772 LALFree( tmpfilename );
773 return ( -1 );
774 }
775
776 /* write data */
777 len = fwrite( t2->data, t2->size, t2->elems, fp );
778 if ( len != t2->elems ) {
779 LOGIOERROR( "Couldn't write data to", tmpfilename );
780 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %zu\n", len, t2->elems );
781 if ( fclose( fp ) ) {
782 LOGIOERROR( "In addition: couldn't close", tmpfilename );
783 }
784 LALFree( tmpfilename );
785 return ( -1 );
786 }
787
788 /* dump heap order */
789 for ( UINT4 i = 0; i < t2->elems; i++ ) {
790 UINT4 idx = ( t2->heap[i] - t2->data ) / t2->size;
791 len = fwrite( &idx, sizeof( idx ), 1, fp );
792 if ( len != 1 ) {
793 LOGIOERROR( "Couldn't write idx to", tmpfilename );
794 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
795 if ( fclose( fp ) ) {
796 LOGIOERROR( "In addition: couldn't close", tmpfilename );
797 }
798 LALFree( tmpfilename );
799 return ( -1 );
800 }
801 for ( len = 0; len < sizeof( idx ); len++ ) {
802 checksum += *( ( ( char * )&idx ) + len );
803 }
804 }
805 } /* if t2 */
806
807 /* FIXME: this is getting silly, put this into a function and call it for the
808 different toplists */
809
810 if ( t3 ) {
811 /* write number of elements */
812 len = fwrite( &( t3->elems ), sizeof( t3->elems ), 1, fp );
813 if ( len != 1 ) {
814 LOGIOERROR( "Couldn't write elems to", tmpfilename );
815 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
816 if ( fclose( fp ) ) {
817 LOGIOERROR( "In addition: couldn't close", tmpfilename );
818 }
819 LALFree( tmpfilename );
820 return ( -1 );
821 }
822
823 /* write data */
824 len = fwrite( t3->data, t3->size, t3->elems, fp );
825 if ( len != t3->elems ) {
826 LOGIOERROR( "Couldn't write data to", tmpfilename );
827 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %zu\n", len, t3->elems );
828 if ( fclose( fp ) ) {
829 LOGIOERROR( "In addition: couldn't close", tmpfilename );
830 }
831 LALFree( tmpfilename );
832 return ( -1 );
833 }
834
835 /* dump heap order */
836 for ( UINT4 i = 0; i < t3->elems; i++ ) {
837 UINT4 idx = ( t3->heap[i] - t3->data ) / t3->size;
838 len = fwrite( &idx, sizeof( idx ), 1, fp );
839 if ( len != 1 ) {
840 LOGIOERROR( "Couldn't write idx to", tmpfilename );
841 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
842 if ( fclose( fp ) ) {
843 LOGIOERROR( "In addition: couldn't close", tmpfilename );
844 }
845 LALFree( tmpfilename );
846 return ( -1 );
847 }
848 for ( len = 0; len < sizeof( idx ); len++ ) {
849 checksum += *( ( ( char * )&idx ) + len );
850 }
851 }
852 } /* if t3 */
853
854
855 /* write counter */
856 len = fwrite( &counter, sizeof( counter ), 1, fp );
857 if ( len != 1 ) {
858 LOGIOERROR( "Couldn't write counter to", tmpfilename );
859 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
860 if ( fclose( fp ) ) {
861 LOGIOERROR( "In addition: couldn't close", tmpfilename );
862 }
863 LALFree( tmpfilename );
864 return ( -1 );
865 }
866
867 /* calculate checksum */
868 for ( len = 0; len < sizeof( tl->elems ); len++ ) {
869 checksum += *( ( ( char * ) & ( tl->elems ) ) + len );
870 }
871 for ( len = 0; len < ( tl->elems * tl->size ); len++ ) {
872 checksum += *( ( ( char * )tl->data ) + len );
873 }
874 if ( t2 ) {
875 for ( len = 0; len < sizeof( t2->elems ); len++ ) {
876 checksum += *( ( ( char * ) & ( t2->elems ) ) + len );
877 }
878 for ( len = 0; len < ( t2->elems * t2->size ); len++ ) {
879 checksum += *( ( ( char * )t2->data ) + len );
880 }
881 }
882
883 if ( t3 ) {
884 for ( len = 0; len < sizeof( t3->elems ); len++ ) {
885 checksum += *( ( ( char * ) & ( t3->elems ) ) + len );
886 }
887 for ( len = 0; len < ( t3->elems * t3->size ); len++ ) {
888 checksum += *( ( ( char * )t3->data ) + len );
889 }
890 }
891
892 for ( len = 0; len < sizeof( counter ); len++ ) {
893 checksum += *( ( ( char * )&counter ) + len );
894 }
895
896 /* write checksum */
897 len = fwrite( &checksum, sizeof( checksum ), 1, fp );
898 if ( len != 1 ) {
899 LOGIOERROR( "Couldn't write checksum to", tmpfilename );
900 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
901 if ( fclose( fp ) ) {
902 LOGIOERROR( "In addition: couldn't close", tmpfilename );
903 }
904 LALFree( tmpfilename );
905 return ( -1 );
906 }
907
908 if ( do_sync && ( sync_fail_counter < SYNC_FAIL_LIMIT ) ) {
909 /* make sure the data ends up on disk */
910 if ( fsync( fileno( fp ) ) ) {
911 LOGIOERROR( "Couldn't sync", tmpfilename );
912 sync_fail_counter++;
913 if ( sync_fail_counter >= SYNC_FAIL_LIMIT ) {
914 LogPrintf( LOG_NORMAL, "WARNING: syncing disabled\n" );
915 }
916 } else {
917 sync_fail_counter = 0;
918 }
919 }
920
921 /* close tempfile */
922 if ( fclose( fp ) ) {
923 LOGIOERROR( "Couldn't close", tmpfilename );
924 LALFree( tmpfilename );
925 return ( -1 );
926 }
927
928 /* rename to filename */
929 if ( rename( tmpfilename, filename ) ) {
930 LOGIOERROR( "Couldn't rename\n", tmpfilename );
931 LALFree( tmpfilename );
932 return ( -1 );
933 }
934
935 /* all went well */
936 LALFree( tmpfilename );
937 return ( 0 );
938} /* write_gct_checkpoint() */
939
940
941int read_gct_checkpoint( const char *filename, toplist_t *tl, toplist_t *t2, toplist_t *t3, UINT4 *counter )
942{
943 FILE *fp;
944 UINT4 len;
945 UINT4 checksum, indexsum = 0;
946
947 /* counter should be 0 if we couldn't read a checkpoint */
948 *counter = 0;
949
950 /* do nothing with an empty filename */
951 if ( !filename ) {
952 LogPrintf( LOG_DETAIL, "%s(): checkpoint filename NULL\n", __func__ );
953 return ( 0 );
954 }
955
956 /* try to open file */
957 fp = fopen( filename, "rb" );
958 if ( !fp ) {
959 if ( errno == ENOENT ) {
960 LogPrintf( LOG_NORMAL, "INFO: No checkpoint %s found - starting from scratch\n", filename );
961 clear_toplist( tl );
962 if ( t2 ) {
963 clear_toplist( t2 );
964 }
965 return ( 1 );
966 } else {
967 LOGIOERROR( "Checkpoint found but couldn't open", filename );
968 clear_toplist( tl );
969 if ( t2 ) {
970 clear_toplist( t2 );
971 }
972 return ( -1 );
973 }
974 }
975
976 /* read number of elements */
977 len = fread( &( tl->elems ), sizeof( tl->elems ), 1, fp );
978 if ( len != 1 ) {
979 LOGIOERROR( "Couldn't read elems from", filename );
980 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
981 if ( fclose( fp ) ) {
982 LOGIOERROR( "In addition: couldn't close", filename );
983 }
984 return ( -1 );
985 }
986 /* sanity check */
987 if ( tl->elems > tl->length ) {
989 "Number of elements read larger than length of toplist: %zu > %zu\n",
990 tl->elems, tl->length );
991 if ( fclose( fp ) ) {
992 LOGIOERROR( "In addition: couldn't close", filename );
993 }
994 return ( -2 );
995 }
996
997 /* read data */
998 len = fread( tl->data, tl->size, tl->elems, fp );
999 if ( len != tl->elems ) {
1000 LOGIOERROR( "Couldn't read data from", filename );
1001 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %zu\n", len, tl->elems );
1002 if ( fclose( fp ) ) {
1003 LOGIOERROR( "In addition: couldn't close", filename );
1004 }
1005 clear_toplist( tl );
1006 if ( t2 ) {
1007 clear_toplist( t2 );
1008 }
1009 return ( -1 );
1010 }
1011
1012 /* read heap order */
1013 for ( UINT4 i = 0; i < tl->elems; i++ ) {
1014 UINT4 idx;
1015 len = fread( &idx, sizeof( idx ), 1, fp );
1016 if ( len != 1 ) {
1017 LOGIOERROR( "Couldn't read idx from", filename );
1018 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
1019 if ( fclose( fp ) ) {
1020 LOGIOERROR( "In addition: couldn't close", filename );
1021 }
1022 return ( -1 );
1023 }
1024 tl->heap[i] = ( char * )( tl->data + idx * tl->size );
1025 for ( len = 0; len < sizeof( idx ); len++ ) {
1026 indexsum += *( ( ( char * )&idx ) + len );
1027 }
1028 }
1029
1030 if ( t2 ) {
1031 /* read number of elements */
1032 len = fread( &( t2->elems ), sizeof( t2->elems ), 1, fp );
1033 if ( len != 1 ) {
1034 LOGIOERROR( "Couldn't read elems from", filename );
1035 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
1036 if ( fclose( fp ) ) {
1037 LOGIOERROR( "In addition: couldn't close", filename );
1038 }
1039 return ( -1 );
1040 }
1041 /* sanity check */
1042 if ( t2->elems > t2->length ) {
1044 "Number of elements read larger than length of toplist: %zu > %zu\n",
1045 t2->elems, t2->length );
1046 if ( fclose( fp ) ) {
1047 LOGIOERROR( "In addition: couldn't close", filename );
1048 }
1049 return ( -2 );
1050 }
1051
1052 /* read data */
1053 len = fread( t2->data, t2->size, t2->elems, fp );
1054 if ( len != t2->elems ) {
1055 LOGIOERROR( "Couldn't read data from", filename );
1056 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %zu\n", len, t2->elems );
1057 if ( fclose( fp ) ) {
1058 LOGIOERROR( "In addition: couldn't close", filename );
1059 }
1060 clear_toplist( tl );
1061 clear_toplist( t2 );
1062 return ( -1 );
1063 }
1064
1065 /* read heap order */
1066 for ( UINT4 i = 0; i < t2->elems; i++ ) {
1067 UINT4 idx;
1068 len = fread( &idx, sizeof( idx ), 1, fp );
1069 if ( len != 1 ) {
1070 LOGIOERROR( "Couldn't read idx from", filename );
1071 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
1072 if ( fclose( fp ) ) {
1073 LOGIOERROR( "In addition: couldn't close", filename );
1074 }
1075 return ( -1 );
1076 }
1077 t2->heap[i] = ( char * )( t2->data + idx * t2->size );
1078 for ( len = 0; len < sizeof( idx ); len++ ) {
1079 indexsum += *( ( ( char * )&idx ) + len );
1080 }
1081 }
1082 } /* if (t2) */
1083
1084 if ( t3 ) {
1085 /* read number of elements */
1086 len = fread( &( t3->elems ), sizeof( t3->elems ), 1, fp );
1087 if ( len != 1 ) {
1088 LOGIOERROR( "Couldn't read elems from", filename );
1089 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
1090 if ( fclose( fp ) ) {
1091 LOGIOERROR( "In addition: couldn't close", filename );
1092 }
1093 return ( -1 );
1094 }
1095 /* sanity check */
1096 if ( t3->elems > t3->length ) {
1098 "Number of elements read larger than length of toplist: %zu > %zu\n",
1099 t3->elems, t3->length );
1100 if ( fclose( fp ) ) {
1101 LOGIOERROR( "In addition: couldn't close", filename );
1102 }
1103 return ( -2 );
1104 }
1105
1106 /* read data */
1107 len = fread( t3->data, t3->size, t3->elems, fp );
1108 if ( len != t3->elems ) {
1109 LOGIOERROR( "Couldn't read data from", filename );
1110 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %zu\n", len, t3->elems );
1111 if ( fclose( fp ) ) {
1112 LOGIOERROR( "In addition: couldn't close", filename );
1113 }
1114 clear_toplist( tl );
1115 clear_toplist( t2 );
1116 clear_toplist( t3 );
1117 return ( -1 );
1118 }
1119
1120 /* read heap order */
1121 for ( UINT4 i = 0; i < t3->elems; i++ ) {
1122 UINT4 idx;
1123 len = fread( &idx, sizeof( idx ), 1, fp );
1124 if ( len != 1 ) {
1125 LOGIOERROR( "Couldn't read idx from", filename );
1126 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
1127 if ( fclose( fp ) ) {
1128 LOGIOERROR( "In addition: couldn't close", filename );
1129 }
1130 return ( -1 );
1131 }
1132 t3->heap[i] = ( char * )( t3->data + idx * t3->size );
1133 for ( len = 0; len < sizeof( idx ); len++ ) {
1134 indexsum += *( ( ( char * )&idx ) + len );
1135 }
1136 }
1137 } /* if (t3) */
1138
1139
1140 /* read counter */
1141 len = fread( counter, sizeof( *counter ), 1, fp );
1142 if ( len != 1 ) {
1143 LOGIOERROR( "Couldn't read counter from", filename );
1144 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
1145 if ( fclose( fp ) ) {
1146 LOGIOERROR( "In addition: couldn't close", filename );
1147 }
1148 clear_toplist( tl );
1149 if ( t2 ) {
1150 clear_toplist( t2 );
1151 }
1152 if ( t3 ) {
1153 clear_toplist( t3 );
1154 }
1155 return ( -1 );
1156 }
1157
1158 /* read checksum */
1159 len = fread( &checksum, sizeof( checksum ), 1, fp );
1160 if ( len != 1 ) {
1161 LOGIOERROR( "Couldn't read checksum from", filename );
1162 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
1163 if ( fclose( fp ) ) {
1164 LOGIOERROR( "In addition: couldn't close", filename );
1165 }
1166 if ( t2 ) {
1167 clear_toplist( t2 );
1168 }
1169 if ( t3 ) {
1170 clear_toplist( t3 );
1171 }
1172
1173 clear_toplist( tl );
1174 return ( -1 );
1175 }
1176
1177 /* close file */
1178 if ( fclose( fp ) ) {
1179 LOGIOERROR( "Couldn't close", filename );
1180 clear_toplist( tl );
1181 if ( t2 ) {
1182 clear_toplist( t2 );
1183 }
1184 if ( t3 ) {
1185 clear_toplist( t3 );
1186 }
1187
1188 return ( -1 );
1189 }
1190
1191 /* verify checksum */
1192 checksum -= indexsum;
1193 for ( len = 0; len < sizeof( tl->elems ); len++ ) {
1194 checksum -= *( ( ( char * ) & ( tl->elems ) ) + len );
1195 }
1196 for ( len = 0; len < ( tl->elems * tl->size ); len++ ) {
1197 checksum -= *( ( ( char * )tl->data ) + len );
1198 }
1199 if ( t2 ) {
1200 for ( len = 0; len < sizeof( t2->elems ); len++ ) {
1201 checksum -= *( ( ( char * ) & ( t2->elems ) ) + len );
1202 }
1203 for ( len = 0; len < ( t2->elems * t2->size ); len++ ) {
1204 checksum -= *( ( ( char * )t2->data ) + len );
1205 }
1206 }
1207 if ( t3 ) {
1208 for ( len = 0; len < sizeof( t3->elems ); len++ ) {
1209 checksum -= *( ( ( char * ) & ( t3->elems ) ) + len );
1210 }
1211 for ( len = 0; len < ( t3->elems * t3->size ); len++ ) {
1212 checksum -= *( ( ( char * )t3->data ) + len );
1213 }
1214 }
1215 for ( len = 0; len < sizeof( *counter ); len++ ) {
1216 checksum -= *( ( ( char * )counter ) + len );
1217 }
1218 if ( checksum ) {
1219 LogPrintf( LOG_CRITICAL, "Checksum error: %d\n", checksum );
1220 clear_toplist( tl );
1221 if ( t2 ) {
1222 clear_toplist( t2 );
1223 }
1224 if ( t3 ) {
1225 clear_toplist( t3 );
1226 }
1227
1228 return ( -2 );
1229 }
1230
1231 /* all went well */
1232 LogPrintf( LOG_DEBUG, "Successfully read checkpoint:%d\n", *counter );
1233
1234 return ( 0 );
1235} /* read_gct_checkpoint() */
1236
1237
1238/**
1239 * removes a checkpoint
1240 * returns 0 on success, errno on failure
1241 */
1243{
1244 /* do nothing with an empty filename */
1245 if ( !filename ) {
1246 LogPrintf( LOG_DETAIL, "%s(): checkpoint filename NULL\n", __func__ );
1247 return ( 0 );
1248 }
1249
1250 if ( unlink( filename ) ) {
1251 LOGIOERROR( "Couldn't delete checkpoint", filename );
1252 return ( errno );
1253 }
1254 return ( 0 );
1255} /* clear_gct_checkpoint() */
1256
1257
1258#ifdef DEBUG_SORTING
1259static void dump_heap_order( const toplist_t *tl, const char *name )
1260{
1261 unsigned int i;
1262 FILE *fp;
1263 if ( ( fp = fopen( name, "w" ) ) ) {
1264 for ( i = 0; i < tl->elems; i++ ) {
1265 fprintf( fp, "%u\n", ( unsigned int )( ( tl->heap[i] - tl->data ) / sizeof( GCTtopOutputEntry ) ) );
1266 }
1267 fclose( fp );
1268 }
1269}
1270
1271static void sort_gctFstat_toplist_debug( toplist_t *l )
1272{
1273 if ( !debugfp ) {
1274 debugfp = fopen( "debug_sort", "w" );
1275 }
1277 if ( debugfp ) {
1278 fclose( debugfp );
1279 debugfp = NULL;
1280 }
1281}
1282#endif
1283
1284int write_hfs_oputput( const char *filename, toplist_t *tl )
1285{
1286 /* reduce the precision of the calculated values before doing the sort to
1287 the precision we will write the result with. This should ensure a sorting
1288 order that looks right to the validator, too */
1290#ifdef DEBUG_SORTING
1291 dump_heap_order( tl, "heap_before.dump" );
1292 sort_gctFstat_toplist_debug( tl );
1293 dump_heap_order( tl, "heap_after.dump" );
1294#else
1296#endif
1297 return ( _atomic_write_gctFstat_toplist_to_file( tl, filename, NULL, 1 ) );
1298}
static void reduce_gctFstatline_precision(void *line)
Definition: GCTtoplist.c:464
void sort_gctFstat_toplist(toplist_t *l)
sorts the toplist with an internal sorting function, used before finally writing it
Definition: GCTtoplist.c:291
int create_gctFstat_toplist(toplist_t **tl, UINT8 length, SortBy_t whatToSortBy)
creates a toplist with length elements, returns -1 on error (usually out of memory),...
Definition: GCTtoplist.c:246
void free_gctFstat_toplist(toplist_t **l)
frees the space occupied by the toplist
Definition: GCTtoplist.c:270
int clear_gct_checkpoint(const char *filename)
removes a checkpoint returns 0 on success, errno on failure
Definition: GCTtoplist.c:1242
static int print_single_detector_quantities_to_str(char *outstr, size_t outstrlen, const REAL4 *quantities, const UINT4 numDetectors)
Definition: GCTtoplist.c:389
static int write_gctFstat_toplist_item_to_fp(GCTtopOutputEntry fline, FILE *fp, UINT4 *checksum)
Definition: GCTtoplist.c:439
#define TEMP_EXT
static int print_gctFstatline_to_str(GCTtopOutputEntry fline, char *buf, int buflen)
Definition: GCTtoplist.c:298
static int gctNC_smaller(const void *a, const void *b)
Definition: GCTtoplist.c:148
#define __func__
log an I/O error, i.e.
Definition: GCTtoplist.c:673
static void reduce_gctFstat_toplist_precision(toplist_t *l)
Definition: GCTtoplist.c:480
static int gctBSGLtL_smaller(const void *a, const void *b)
Definition: GCTtoplist.c:192
static int gctFstat_result_order(const void *a, const void *b)
Definition: GCTtoplist.c:93
static int gctBtSGLtL_smaller(const void *a, const void *b)
Definition: GCTtoplist.c:213
char * global_column_headings_stringp
static int gctFstat_smaller(const void *a, const void *b)
Definition: GCTtoplist.c:125
static int print_single_detector_intval_to_str(char *outstr, size_t outstrlen, const INT4 *quantities, const UINT4 numDetectors)
Definition: GCTtoplist.c:411
static int gctFstat_final_qsort(const void *a, const void *b)
Definition: GCTtoplist.c:236
int finite(double)
int insert_into_gctFstat_toplist(toplist_t *tl, GCTtopOutputEntry *elem)
Inserts an element in to the toplist either if there is space left or the element is larger than the ...
Definition: GCTtoplist.c:281
int write_gctFstat_toplist_to_fp(toplist_t *tl, FILE *fp, UINT4 *checksum)
Writes the toplist to an (already open) filepointer Returns the number of written charactes sets the ...
Definition: GCTtoplist.c:489
static int gctBSGL_smaller(const void *a, const void *b)
Definition: GCTtoplist.c:171
#define TMP_EXT
int read_gct_checkpoint(const char *filename, toplist_t *tl, toplist_t *t2, toplist_t *t3, UINT4 *counter)
tries to read a checkpoint
Definition: GCTtoplist.c:941
int write_gct_checkpoint(const char *filename, toplist_t *tl, toplist_t *t2, toplist_t *t3, UINT4 counter, BOOLEAN do_sync)
Checkpointing.
Definition: GCTtoplist.c:688
#define SYNC_FAIL_LIMIT
Definition: GCTtoplist.c:79
#define LOGIOERROR(mess, filename)
Definition: GCTtoplist.c:682
int write_hfs_oputput(const char *filename, toplist_t *tl)
write the final output file:
Definition: GCTtoplist.c:1284
static int _atomic_write_gctFstat_toplist_to_file(toplist_t *l, const char *filename, UINT4 *checksum, int write_done)
Definition: GCTtoplist.c:514
char ** global_argv
SortBy_t
enumerate all toplist-sorting options: by F (0), number-count (1), BSGL (2), "dual" toplists F + BSGL...
Definition: GCTtoplist.h:71
@ SORTBY_NC
Definition: GCTtoplist.h:73
@ SORTBY_BtSGLtL
Definition: GCTtoplist.h:77
@ SORTBY_BSGL
Definition: GCTtoplist.h:74
@ SORTBY_BSGLtL
Definition: GCTtoplist.h:76
int global_argc
int create_toplist(toplist_t **list, size_t length, size_t size, int(*smaller)(const void *, const void *))
Definition: HeapToplist.c:101
void free_toplist(toplist_t **list)
Definition: HeapToplist.c:139
int insert_into_toplist(toplist_t *list, void *element)
Definition: HeapToplist.c:151
void go_through_toplist(toplist_t *list, void(*handle)(void *))
Definition: HeapToplist.c:177
void clear_toplist(toplist_t *list)
Definition: HeapToplist.c:132
#define LALCalloc(m, n)
#define LALFree(p)
const LALVCSInfoList lalPulsarVCSInfoList
NULL-terminated list of VCS and build information for LALPulsar and its dependencies
#define c
const char * name
Definition: SearchTiming.c:93
#define fprintf
int l
#define LAL_REAL4_MAX
unsigned char BOOLEAN
uint64_t UINT8
#define XLAL_LAST_ELEM(x)
int64_t INT8
char CHAR
uint32_t UINT4
int32_t INT4
float REAL4
void XLALFree(void *p)
#define LAL_REAL8_FORMAT
#define LAL_UINT8_FORMAT
char * XLALVCSInfoString(const LALVCSInfoList vcs_list, const int verbose, const char *prefix)
void LogPrintf(LogLevel_t, const char *format,...) _LAL_GCC_PRINTF_FORMAT_(2
LOG_CRITICAL
LOG_DEBUG
LOG_NORMAL
LOG_DETAIL
static const INT4 r
static const INT4 a
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
size_t numDetectors
Definition: GCTtoplist.h:42
REAL4 log10BSGLtL
Line-robust statistic .
Definition: GCTtoplist.h:52
REAL4 maxTwoFXl[PULSAR_MAX_DETECTORS]
fixed-size array of single-detector maximum 2F over segments
Definition: GCTtoplist.h:58
INT4 maxTwoFlSeg
index of segment with maximum multi-detector 2F
Definition: GCTtoplist.h:57
UINT4 numDetectors
number of detectors for optional avTwoFX arrays
Definition: GCTtoplist.h:54
REAL4 avTwoFXrecalc[PULSAR_MAX_DETECTORS]
fixed-size array of single-detector -values as recomputed by recalcToplistStats
Definition: GCTtoplist.h:61
REAL4 log10BSGLrecalc
Line-robust statistic recomputed by recalcToplistStats.
Definition: GCTtoplist.h:62
REAL8 Freq
frequency
Definition: GCTtoplist.h:43
REAL4 log10BSGLtLrecalc
Line-robust statistic recomputed by recalcToplistStats.
Definition: GCTtoplist.h:63
INT4 loudestSeg
index of the loudest segment in multi-F
Definition: GCTtoplist.h:65
REAL4 maxTwoFl
multi-detector maximum 2F over segments
Definition: GCTtoplist.h:56
UINT4 nc
number count
Definition: GCTtoplist.h:50
REAL4 log10BtSGLtL
Line-robust transient-CW statistic .
Definition: GCTtoplist.h:53
REAL4 twoFXloudestSeg[PULSAR_MAX_DETECTORS]
single-IFO F-stat values from the loudest segment in multi-F
Definition: GCTtoplist.h:67
REAL4 log10BSGL
Line-robust statistic .
Definition: GCTtoplist.h:51
REAL8 F2dot
spindown value f2dot = d2f/dt2
Definition: GCTtoplist.h:45
REAL8 Alpha
skyposition: longitude in equatorial coords, radians
Definition: GCTtoplist.h:47
REAL8 Delta
skyposition: latitude
Definition: GCTtoplist.h:48
REAL8 F1dot
spindown value f1dot = df/dt
Definition: GCTtoplist.h:44
REAL4 twoFloudestSeg
loudest single-segment multi-IFO F-stat value
Definition: GCTtoplist.h:66
REAL4 avTwoFX[PULSAR_MAX_DETECTORS]
fixed-size array of single-detector average -values
Definition: GCTtoplist.h:55
INT4 maxTwoFXlSeg[PULSAR_MAX_DETECTORS]
fixed-size array of index of segment with maximum single-detector 2F
Definition: GCTtoplist.h:59
BOOLEAN have_f3dot
output F3dot value
Definition: GCTtoplist.h:64
REAL8 F3dot
spindown value f2dot = d2f/dt2
Definition: GCTtoplist.h:46
REAL4 avTwoFrecalc
average of -values as recomputed by recalcToplistStats
Definition: GCTtoplist.h:60
REAL4 avTwoF
average of F-statistic values over segments
Definition: GCTtoplist.h:49
char ** heap
Definition: HeapToplist.h:40
size_t length
Definition: HeapToplist.h:36
size_t elems
Definition: HeapToplist.h:37
size_t size
Definition: HeapToplist.h:38
char * data
Definition: HeapToplist.h:39