LALPulsar 7.1.1.1-eeff03c
HoughFstatToplist.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Bernd Machenschalk, Reinhard Prix
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20#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
35#include "HoughFstatToplist.h"
36
37/* Windows specifics */
38#ifdef _WIN32
39#include <io.h>
40
41/* errno */
42extern int errno;
43extern int _doserrno;
44
45/* snprintf */
46#define snprintf _snprintf
47
48/* fsync */
49#define fsync _commit
50#define fileno _fileno
51
52#else /* WIN32 */
53
54/* errno */
55#include <errno.h>
56
57#endif /* WIN32 */
58
59/* define min macro if not already defined */
60#ifndef min
61#define min(a,b) ((a)<(b)?(a):(b))
62#endif
63
64/* maximum number of succesive failures before switching off syncing */
65#define SYNC_FAIL_LIMIT 5
66
67/* local prototypes */
69static int _atomic_write_houghFstat_toplist_to_file( toplist_t *l, const char *filename, UINT4 *checksum, int write_done );
70static int print_houghFstatline_to_str( HoughFstatOutputEntry fline, char *buf, int buflen );
71
72
73/* ordering function for sorting the list */
74static int houghFstat_toplist_qsort_function( const void *a, const void *b )
75{
76 if ( ( ( const HoughFstatOutputEntry * )a )->Freq < ( ( const HoughFstatOutputEntry * )b )->Freq ) {
77 return -1;
78 } else if ( ( ( const HoughFstatOutputEntry * )a )->Freq > ( ( const HoughFstatOutputEntry * )b )->Freq ) {
79 return 1;
80 } else if ( ( ( const HoughFstatOutputEntry * )a )->Alpha < ( ( const HoughFstatOutputEntry * )b )->Alpha ) {
81 return -1;
82 } else if ( ( ( const HoughFstatOutputEntry * )a )->Alpha > ( ( const HoughFstatOutputEntry * )b )->Alpha ) {
83 return 1;
84 } else if ( ( ( const HoughFstatOutputEntry * )a )->Delta < ( ( const HoughFstatOutputEntry * )b )->Delta ) {
85 return -1;
86 } else if ( ( ( const HoughFstatOutputEntry * )a )->Delta > ( ( const HoughFstatOutputEntry * )b )->Delta ) {
87 return 1;
88 } else if ( ( ( const HoughFstatOutputEntry * )a )->f1dot < ( ( const HoughFstatOutputEntry * )b )->f1dot ) {
89 return -1;
90 } else if ( ( ( const HoughFstatOutputEntry * )a )->f1dot > ( ( const HoughFstatOutputEntry * )b )->f1dot ) {
91 return 1;
92 } else {
93 return 0;
94 }
95}
96
97/* ordering function defining the toplist */
98static int houghFstat_smaller( const void *a, const void *b )
99{
100 if ( ( ( const HoughFstatOutputEntry * )a )->HoughFstat < ( ( const HoughFstatOutputEntry * )b )->HoughFstat ) {
101 return ( 1 );
102 } else if ( ( ( const HoughFstatOutputEntry * )a )->HoughFstat > ( ( const HoughFstatOutputEntry * )b )->HoughFstat ) {
103 return ( -1 );
104 } else {
105 return ( houghFstat_toplist_qsort_function( a, b ) );
106 }
107}
108
109
110/* creates a toplist with length elements,
111 returns -1 on error (usually out of memory), else 0 */
113{
114 return ( create_toplist( tl, length, sizeof( HoughFstatOutputEntry ), houghFstat_smaller ) );
115}
116
117
118/* frees the space occupied by the toplist */
120{
121 /* special handling of sumTwoFX entries, which are REAL4Vectors
122 * and need to be free'ed first if they are non-NULL
123 */
124 UINT4 i;
125 for ( i = 0; i < ( *l )->elems; i++ ) {
127 XLALDestroyREAL4Vector( elem->sumTwoFX );
128 } /* for cand < numCands */
129
130 /* free the rest of the toplist and the 'container' */
131 free_toplist( l );
132
133}
134
135
136/* Inserts an element in to the toplist either if there is space left
137 or the element is larger than the smallest element in the toplist.
138 In the latter case, remove the smallest element from the toplist and
139 look for the now smallest one.
140 Returns 1 if the element was actually inserted, 0 if not. */
142{
143 if ( !tl ) {
144 return 0;
145 } else {
146 return ( insert_into_toplist( tl, ( void * )&elem ) );
147 }
148}
149
150
151/* (q)sort the toplist according to the sorting function. */
153{
155}
156
157
158/* reads a (created!) toplist from an open filepointer
159 returns the number of bytes read,
160 0 if we found a %DONE marker at the end,
161 -1 if the file contained a syntax error,
162 -2 if given an improper toplist */
163int read_houghFstat_toplist_from_fp( toplist_t *l, FILE *fp, UINT4 *checksum, UINT4 maxbytes )
164{
165 CHAR line[256]; /* buffer for reading a line */
166 UINT4 items, lines; /* number of items read from a line, linecounter */
167 UINT4 len, chars = 0; /* length of a line, total characters read from the file */
168 UINT4 i; /* loop counter */
169 CHAR lastchar; /* last character of a line read, should be newline */
170 HoughFstatOutputEntry HoughFstatLine;
171 REAL8 epsilon = 1e-5;
172
173 /* basic check that the list argument is valid */
174 if ( !l ) {
175 return -2;
176 }
177
178 /* make sure the line buffer is terminated correctly */
179 XLAL_LAST_ELEM( line ) = '\0';
180
181 /* init the checksum if given */
182 if ( checksum ) {
183 *checksum = 0;
184 }
185
186 /* set maxbytes to maximum if zero */
187 if ( maxbytes == 0 ) {
188 maxbytes--;
189 }
190
191 lines = 1;
192 while ( fgets( line, sizeof( line ) - 1, fp ) ) {
193
194 if ( !strncmp( line, "%DONE\n", strlen( "%DONE\n" ) ) ) {
195 LogPrintf( LOG_NORMAL, "WARNING: found end marker - the task was already finished\n" );
196 return ( 0 );
197 }
198
199 len = strlen( line );
200 chars += len;
201
202 if ( len == 0 ) {
203 LogPrintf( LOG_CRITICAL, "Line %d is empty.\n", lines );
204 return -1;
205 } else if ( line[len - 1] != '\n' ) {
207 "Line %d is too long or has no NEWLINE. First %zu chars are:\n'%s'\n",
208 lines, sizeof( line ) - 1, line );
209 return -1;
210 }
211
212 items = sscanf( line,
217 " %" LAL_REAL8_FORMAT "%c",
218 &HoughFstatLine.Freq,
219 &HoughFstatLine.Alpha,
220 &HoughFstatLine.Delta,
221 &HoughFstatLine.f1dot,
222 &HoughFstatLine.HoughFstat,
223 &lastchar );
224
225 /* check the values scanned */
226 if (
227 items != 6 ||
228
229 !isfinite( HoughFstatLine.Freq ) ||
230 !isfinite( HoughFstatLine.f1dot ) ||
231 !isfinite( HoughFstatLine.Alpha ) ||
232 !isfinite( HoughFstatLine.Delta ) ||
233 !isfinite( HoughFstatLine.HoughFstat ) ||
234
235 HoughFstatLine.Freq < 0.0 ||
236 HoughFstatLine.Alpha < 0.0 - epsilon ||
237 HoughFstatLine.Alpha > LAL_TWOPI + epsilon ||
238 HoughFstatLine.Delta < -0.5 * LAL_PI - epsilon ||
239 HoughFstatLine.Delta > 0.5 * LAL_PI + epsilon ||
240
241 lastchar != '\n'
242 ) {
244 "Line %d has invalid values.\n"
245 "First %zu chars are:\n"
246 "%s\n"
247 "All fields should be finite\n"
248 "1st field should be positive.\n"
249 "2nd field should lie between 0 and %1.15f.\n"
250 "3rd field should lie between %1.15f and %1.15f.\n",
251 lines, sizeof( line ) - 1, line,
252 ( double )LAL_TWOPI, ( double ) - LAL_PI / 2.0, ( double )LAL_PI / 2.0 );
253 return -1;
254 }
255
256 if ( checksum )
257 for ( i = 0; i < len; i++ ) {
258 *checksum += line[i];
259 }
260
261 insert_into_toplist( l, &HoughFstatLine );
262 lines++;
263
264 /* NOTE: it *CAN* happen (and on Linux it DOES) that the fully buffered HoughFstat stream
265 * gets written to the File at program termination.
266 * This does not seem to happen on Mac though, most likely due to different
267 * exit()-calls used (_exit() vs exit() etc.....)
268 *
269 * The bottom-line is: the File-contents CAN legally extend beyond maxbytes,
270 * which is why we'll ensure here that we don't actually read more than
271 * maxbytes.
272 */
273 if ( chars == maxbytes ) {
274 LogPrintf( LOG_DEBUG, "Read exactly %d == maxbytes from HoughFstat-file, that's enough.\n",
275 chars );
276 break;
277 }
278 /* however, if we've read more than maxbytes, something is gone wrong */
279 if ( chars > maxbytes ) {
280 LogPrintf( LOG_CRITICAL, "Read %d bytes > maxbytes %d from HoughFstat-file ... corrupted.\n",
281 chars, maxbytes );
282 return -1;
283 }
284
285 } /* while (fgets() ) */
286
287 return chars;
288
289} /* read_houghFstat_toplist_from_fp() */
290
291
292/* Prints a Tooplist line to a string buffer.
293 Separate function to assure consistency of output and reduced precision for sorting */
294static int print_houghFstatline_to_str( HoughFstatOutputEntry fline, char *buf, int buflen )
295{
296 const char *fn = __func__;
297
298 /* add extra output-field containing sumTwoF and per-detector sumTwoFX if non-NULL */
299 char extraFStr[256] = ""; /* defaults to empty */
300 char buf0[256];
301 if ( fline.sumTwoFX ) {
302 snprintf( extraFStr, sizeof( extraFStr ), " %.6f", fline.sumTwoF );
303 UINT4 numDet = fline.sumTwoFX->length;
304 UINT4 X;
305 for ( X = 0; X < numDet ; X ++ ) {
306 snprintf( buf0, sizeof( buf0 ), " %7.6f", fline.sumTwoFX->data[X] );
307 UINT4 len1 = strlen( extraFStr ) + strlen( buf0 ) + 1;
308 if ( len1 > sizeof( extraFStr ) ) {
309 XLALPrintError( "%s: assembled output string too long! (%d > %zu)\n", fn, len1, sizeof( extraFStr ) );
310 break; /* we can't really terminate with error in this function, but at least we avoid crashing */
311 }
312 strcat( extraFStr, buf0 );
313 } /* for X < numDet */
314
315 } /* if sumTwoFX */
316
317 return ( snprintf( buf, buflen,
318 /* output precision: choose by following (generous!) significant-digit constraints:
319 * Freq:1e-13
320 * Alpha,Delta:1e-7
321 * f1dot:1e-5
322 * F:1e-6
323 */
324 "%16.15f %16.15f %- 16.15f %- 21.15g %- 16.15f %16.15f %- 16.15f %- 8.7f %8.7f%s\n",
325 fline.Freq,
326 fline.Alpha,
327 fline.Delta,
328 fline.f1dot,
329 fline.HoughFstat,
330 fline.AlphaBest,
331 fline.DeltaBest,
332 fline.MeanSig,
333 fline.VarianceSig,
334 extraFStr ) );
335}
336
337
338/* writes an HoughFstatOutputEntry line to an open filepointer.
339 Returns the number of chars written, -1 if in error
340 Updates checksum if given */
342{
343 char linebuf[256];
344 UINT4 i;
345
346 UINT4 length = print_houghFstatline_to_str( fline, linebuf, sizeof( linebuf ) - 1 );
347
348 if ( length > sizeof( linebuf ) - 1 ) {
349 return -1;
350 }
351
352 if ( checksum )
353 for ( i = 0; i < length; i++ ) {
354 *checksum += linebuf[i];
355 }
356
357 XLAL_LAST_ELEM( linebuf ) = '\0';
358
359 return ( fprintf( fp, "%s", linebuf ) );
360}
361
362
363/* Reduces the precision of all elements in the toplist which influence the sorting order.
364 To be called before sorting and finally writing out the list */
366{
367 char linebuf[256];
368 print_houghFstatline_to_str( ( *( HoughFstatOutputEntry * )line ), linebuf, sizeof( linebuf ) );
369 sscanf( linebuf,
374 "%*s\n",
375 &( ( *( HoughFstatOutputEntry * )line ).Freq ),
376 &( ( *( HoughFstatOutputEntry * )line ).Alpha ),
377 &( ( *( HoughFstatOutputEntry * )line ).Delta ),
378 &( ( *( HoughFstatOutputEntry * )line ).f1dot ) );
379}
380
382{
384}
385
386
387/* Writes the toplist to an (already open) filepointer
388 Returns the number of written charactes
389 Returns something <0 on error */
391{
392 UINT8 c = 0, i;
393 INT8 r;
394 if ( checksum ) {
395 *checksum = 0;
396 }
397 for ( i = 0; i < tl->elems; i++ )
398 if ( ( r = write_houghFstat_toplist_item_to_fp( *( ( HoughFstatOutputEntry * )( void * )( tl->heap[i] ) ), fp, checksum ) ) < 0 ) {
399 LogPrintf( LOG_CRITICAL, "Failed to write toplistitem to output fp: %d: %s\n",
400 errno, strerror( errno ) );
401#ifdef _MSC_VER
402 LogPrintf( LOG_CRITICAL, "Windows system call returned: %d\n", _doserrno );
403#endif
404 return ( r );
405 } else {
406 c += r;
407 }
408 return ( c );
409}
410
411
412/* writes the given toplitst to a temporary file, then renames the temporary file to filename.
413 The name of the temporary file is derived from the filename by appending ".tmp". Returns the
414 number of chars written or -1 if the temp file could not be opened.
415 This just calls _atomic_write_houghFstat_toplist_to_file() telling it not to write a %DONE marker*/
417{
418 return ( _atomic_write_houghFstat_toplist_to_file( l, filename, checksum, 0 ) );
419}
420
421/* function that does the actual work of atomic_write_houghFstat_toplist_to_file(),
422 appending a %DONE marker if specified (not when called from atomic_write_houghFstat_toplist_to_file().
423 NOTE that the checksum will be a little wrong when %DOME is appended, as this line is not counted */
424static int _atomic_write_houghFstat_toplist_to_file( toplist_t *l, const char *filename, UINT4 *checksum, int write_done )
425{
426 char *tempname;
427 INT4 length;
428 FILE *fpnew;
429 UINT4 s;
430
431#define TEMP_EXT ".tmp"
432 s = strlen( filename ) + strlen( TEMP_EXT ) + 1;
433 tempname = ( char * )malloc( s );
434 if ( !tempname ) {
435 LogPrintf( LOG_CRITICAL, "Could not allocate new filename\n" );
436 return ( -1 );
437 }
438 strcpy( tempname, filename );
439 strcat( tempname, TEMP_EXT );
440
441 fpnew = fopen( tempname, "wb" );
442 if ( !fpnew ) {
443 LogPrintf( LOG_CRITICAL, "Failed to open temp HoughFstat file \"%s\" for writing: %d: %s\n",
444 tempname, errno, strerror( errno ) );
445#ifdef _MSC_VER
446 LogPrintf( LOG_CRITICAL, "Windows system call returned: %d\n", _doserrno );
447#endif
448 free( tempname );
449 return -1;
450 }
451 length = write_houghFstat_toplist_to_fp( l, fpnew, checksum );
452
453 if ( ( write_done ) && ( length >= 0 ) ) {
454 int ret;
455 ret = fprintf( fpnew, "%%DONE\n" );
456 if ( ret < 0 ) {
457 length = ret;
458 } else {
459 length += ret;
460 }
461 }
462
463 fclose( fpnew );
464
465 if ( length < 0 ) {
466 LogPrintf( LOG_CRITICAL, "Failed to write temp HoughFstat file \"%s\": %d: %s\n",
467 tempname, errno, strerror( errno ) );
468#ifdef _MSC_VER
469 LogPrintf( LOG_CRITICAL, "Windows system call returned: %d\n", _doserrno );
470#endif
471 free( tempname );
472 return ( length );
473 }
474
475 if ( rename( tempname, filename ) ) {
476 LogPrintf( LOG_CRITICAL, "Failed to rename HoughFstat file to \"%s\": %d: %s\n",
477 filename, errno, strerror( errno ) );
478#ifdef _MSC_VER
479 LogPrintf( LOG_CRITICAL, "Windows system call returned: %d\n", _doserrno );
480#endif
481 free( tempname );
482 return -1;
483 }
484
485 free( tempname );
486 return length;
487}
488
489
490/* meant for the final writing of the toplist
491 - reduces toplist precision
492 - sorts the toplist
493 - then calls atomic_write_houghFstat_toplist_to_file() */
495{
498 return ( atomic_write_houghFstat_toplist_to_file( l, filename, checksum ) );
499}
500
501
502
503
504/* New easier checkpointing - simply dump the whole toplist (plus a counter and
505 a checksum) into a binary file.
506 The heap structure array is hard to dump because it's based on pointers, so it
507 is restored after reding the data back in by sorting the list once.
508*/
509
510/** log an I/O error, i.e. source code line no., ferror, errno and strerror, and doserrno on Windows, too */
511#ifndef __func__
512#ifdef __FUNCTION__
513#define __func__ __FUNCTION__
514#else
515#define __func__ ""
516#endif
517#endif
518
519#ifdef _WIN32
520#define LOGIOERROR(mess,filename) \
521 LogPrintf(LOG_CRITICAL, "ERROR: %s %s: %s (%s:%d): doserr:%d, ferr:%d, errno:%d: %s\n",\
522 mess,filename,__func__,__FILE__,__LINE__,_doserrno,((fp)?(ferror(fp)):0),errno,strerror(errno))
523#else
524#define LOGIOERROR(mess,filename) \
525 LogPrintf(LOG_CRITICAL, "ERROR: %s %s: %s (%s:%d): errno:%d: %s\n",\
526 mess,filename,__func__,__FILE__,__LINE__,errno,strerror(errno))
527#endif
528
529/* dumps toplist to a temporary file, then renames the file to filename */
530int write_hfs_checkpoint( const char *filename, toplist_t *tl, UINT4 counter, BOOLEAN do_sync )
531{
532#define TMP_EXT ".tmp"
533 char *tmpfilename;
534 FILE *fp;
535 UINT4 len;
536 UINT4 checksum;
537 static UINT4 sync_fail_counter = 0;
538
539 /* construct temporary filename */
540 len = strlen( filename ) + strlen( TMP_EXT ) + 1;
541 tmpfilename = LALCalloc( len, sizeof( char ) );
542 if ( !tmpfilename ) {
543 LogPrintf( LOG_CRITICAL, "Couldn't allocate tmpfilename\n" );
544 return ( -2 );
545 }
546 strcpy( tmpfilename, filename );
547 strcat( tmpfilename, TMP_EXT );
548
549 /* calculate checksum */
550 checksum = 0;
551 for ( len = 0; len < sizeof( tl->elems ); len++ ) {
552 checksum += *( ( ( char * ) & ( tl->elems ) ) + len );
553 }
554 for ( len = 0; len < ( tl->elems * tl->size ); len++ ) {
555 checksum += *( ( ( char * )tl->data ) + len );
556 }
557 for ( len = 0; len < sizeof( counter ); len++ ) {
558 checksum += *( ( ( char * )&counter ) + len );
559 }
560
561 /* open tempfile */
562 fp = fopen( tmpfilename, "wb" );
563 if ( !fp ) {
564 LOGIOERROR( "Couldn't open", tmpfilename );
565 return ( -1 );
566 }
567
568 /* write number of elements */
569 len = fwrite( &( tl->elems ), sizeof( tl->elems ), 1, fp );
570 if ( len != 1 ) {
571 LOGIOERROR( "Couldn't write elems to", tmpfilename );
572 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
573 if ( fclose( fp ) ) {
574 LOGIOERROR( "In addition: couldn't close", tmpfilename );
575 }
576 return ( -1 );
577 }
578
579 /* write data */
580 len = fwrite( tl->data, tl->size, tl->elems, fp );
581 if ( len != tl->elems ) {
582 LOGIOERROR( "Couldn't write data to", tmpfilename );
583 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %zu\n", len, tl->elems );
584 if ( fclose( fp ) ) {
585 LOGIOERROR( "In addition: couldn't close", tmpfilename );
586 }
587 return ( -1 );
588 }
589
590 /* write counter */
591 len = fwrite( &counter, sizeof( counter ), 1, fp );
592 if ( len != 1 ) {
593 LOGIOERROR( "Couldn't write counter to", tmpfilename );
594 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
595 if ( fclose( fp ) ) {
596 LOGIOERROR( "In addition: couldn't close", tmpfilename );
597 }
598 return ( -1 );
599 }
600
601 /* write checksum */
602 len = fwrite( &checksum, sizeof( checksum ), 1, fp );
603 if ( len != 1 ) {
604 LOGIOERROR( "Couldn't write checksum to", tmpfilename );
605 LogPrintf( LOG_CRITICAL, "fwrite() returned %d, length was %d\n", len, 1 );
606 if ( fclose( fp ) ) {
607 LOGIOERROR( "In addition: couldn't close", tmpfilename );
608 }
609 return ( -1 );
610 }
611
612 if ( do_sync && ( sync_fail_counter < SYNC_FAIL_LIMIT ) ) {
613 /* make sure the data ends up on disk */
614 if ( fsync( fileno( fp ) ) ) {
615 LOGIOERROR( "Couldn't sync", tmpfilename );
616 sync_fail_counter++;
617 if ( sync_fail_counter >= SYNC_FAIL_LIMIT ) {
618 LogPrintf( LOG_NORMAL, "WARNING: syncing disabled\n" );
619 }
620 } else {
621 sync_fail_counter = 0;
622 }
623 }
624
625 /* close tempfile */
626 if ( fclose( fp ) ) {
627 LOGIOERROR( "Couldn't close", tmpfilename );
628 return ( -1 );
629 }
630
631 /* rename to filename */
632 if ( rename( tmpfilename, filename ) ) {
633 LOGIOERROR( "Couldn't rename\n", tmpfilename );
634 return ( -1 );
635 }
636
637 /* all went well */
638 return ( 0 );
639}
640
641
642int read_hfs_checkpoint( const char *filename, toplist_t *tl, UINT4 *counter )
643{
644 FILE *fp;
645 UINT4 len;
646 UINT4 checksum;
647
648 /* counter should be 0 if we couldn't read a checkpoint */
649 *counter = 0;
650
651 /* try to open file */
652 fp = fopen( filename, "rb" );
653 if ( !fp ) {
654 if ( errno == ENOENT ) {
655 LogPrintf( LOG_NORMAL, "INFO: No checkpoint %s found - starting from scratch\n", filename );
656 clear_toplist( tl );
657 return ( 1 );
658 } else {
659 LOGIOERROR( "Checkpoint found but couldn't open", filename );
660 clear_toplist( tl );
661 return ( -1 );
662 }
663 }
664
665 /* read number of elements */
666 len = fread( &( tl->elems ), sizeof( tl->elems ), 1, fp );
667 if ( len != 1 ) {
668 LOGIOERROR( "Couldn't read elems from", filename );
669 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
670 if ( fclose( fp ) ) {
671 LOGIOERROR( "In addition: couldn't close", filename );
672 }
673 return ( -1 );
674 }
675 /* sanity check */
676 if ( tl->elems > tl->length ) {
678 "Number of elements read larger than length of toplist: %zu > %zu\n",
679 tl->elems, tl->length );
680 if ( fclose( fp ) ) {
681 LOGIOERROR( "In addition: couldn't close", filename );
682 }
683 return ( -2 );
684 }
685
686 /* read data */
687 len = fread( tl->data, tl->size, tl->elems, fp );
688 if ( len != tl->elems ) {
689 LOGIOERROR( "Couldn't read data from", filename );
690 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %zu\n", len, tl->elems );
691 if ( fclose( fp ) ) {
692 LOGIOERROR( "In addition: couldn't close", filename );
693 }
694 clear_toplist( tl );
695 return ( -1 );
696 }
697
698 /* read counter */
699 len = fread( counter, sizeof( *counter ), 1, fp );
700 if ( len != 1 ) {
701 LOGIOERROR( "Couldn't read counter from", filename );
702 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
703 if ( fclose( fp ) ) {
704 LOGIOERROR( "In addition: couldn't close", filename );
705 }
706 clear_toplist( tl );
707 return ( -1 );
708 }
709
710 /* read checksum */
711 len = fread( &checksum, sizeof( checksum ), 1, fp );
712 if ( len != 1 ) {
713 LOGIOERROR( "Couldn't read checksum to", filename );
714 LogPrintf( LOG_CRITICAL, "fread() returned %d, length was %d\n", len, 1 );
715 if ( fclose( fp ) ) {
716 LOGIOERROR( "In addition: couldn't close", filename );
717 }
718 clear_toplist( tl );
719 return ( -1 );
720 }
721
722 /* close file */
723 if ( fclose( fp ) ) {
724 LOGIOERROR( "Couldn't close", filename );
725 clear_toplist( tl );
726 return ( -1 );
727 }
728
729 /* verify checksum */
730 for ( len = 0; len < sizeof( tl->elems ); len++ ) {
731 checksum -= *( ( ( char * ) & ( tl->elems ) ) + len );
732 }
733 for ( len = 0; len < ( tl->elems * tl->size ); len++ ) {
734 checksum -= *( ( ( char * )tl->data ) + len );
735 }
736 for ( len = 0; len < sizeof( *counter ); len++ ) {
737 checksum -= *( ( ( char * )counter ) + len );
738 }
739 if ( checksum ) {
740 LogPrintf( LOG_CRITICAL, "Checksum error: %d\n", checksum );
741 clear_toplist( tl );
742 return ( -2 );
743 }
744
745 /* restore Heap structure by sorting */
746 for ( len = 0; len < tl->elems; len++ ) {
747 tl->heap[len] = tl->data + len * tl->size;
748 }
750
751 /* all went well */
752 LogPrintf( LOG_DEBUG, "Successfully read checkpoint\n" );
753
754 return ( 0 );
755}
756
757
758int write_hfs_oputput( const char *filename, toplist_t *tl )
759{
760 /* reduce the precision of the calculated values before doing the sort to
761 the precision we will write the result with. This should ensure a sorting
762 order that looks right to the validator, too */
765 return ( _atomic_write_houghFstat_toplist_to_file( tl, filename, NULL, 1 ) );
766}
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
void qsort_toplist(toplist_t *list, int(*compare)(const void *, const void *))
Definition: HeapToplist.c:241
void * toplist_elem(toplist_t *list, size_t ind)
Definition: HeapToplist.c:185
void qsort_toplist_r(toplist_t *list, int(*compare)(const void *, const void *))
Definition: HeapToplist.c:249
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
int read_hfs_checkpoint(const char *filename, toplist_t *tl, UINT4 *counter)
tries to read a checkpoint
int create_houghFstat_toplist(toplist_t **tl, UINT8 length)
creates a toplist with length elements, returns -1 on error (usually out of memory),...
int write_houghFstat_toplist_item_to_fp(HoughFstatOutputEntry fline, FILE *fp, UINT4 *checksum)
File IO.
static int houghFstat_smaller(const void *a, const void *b)
void sort_houghFstat_toplist(toplist_t *l)
sorts the toplist with an internal sorting function, used before finally writing it
#define TEMP_EXT
void free_houghFstat_toplist(toplist_t **l)
frees the space occupied by the toplist
#define __func__
log an I/O error, i.e.
static int _atomic_write_houghFstat_toplist_to_file(toplist_t *l, const char *filename, UINT4 *checksum, int write_done)
int final_write_houghFstat_toplist_to_file(toplist_t *l, const char *filename, UINT4 *checksum)
meant for the final writing of the toplist
int write_hfs_checkpoint(const char *filename, toplist_t *tl, UINT4 counter, BOOLEAN do_sync)
new, simpler checkpointing for HierarchicalSearch
static void reduce_houghFstat_toplist_precision(toplist_t *l)
static void reduce_houghFstatline_precision(void *line)
int read_houghFstat_toplist_from_fp(toplist_t *l, FILE *fp, UINT4 *checksum, UINT4 maxbytes)
reads a (created!) toplist from an open filepointer sets the checksum if non-NULL reads maximum maxby...
static int houghFstat_toplist_qsort_function(const void *a, const void *b)
int atomic_write_houghFstat_toplist_to_file(toplist_t *l, const char *filename, UINT4 *checksum)
writes the given toplitst to a temporary file, then renames the temporary file to filename.
#define TMP_EXT
int write_houghFstat_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 ...
int insert_into_houghFstat_toplist(toplist_t *tl, HoughFstatOutputEntry elem)
Inserts an element in to the toplist either if there is space left or the element is larger than the ...
#define SYNC_FAIL_LIMIT
#define LOGIOERROR(mess, filename)
int write_hfs_oputput(const char *filename, toplist_t *tl)
write the final output file:
static int print_houghFstatline_to_str(HoughFstatOutputEntry fline, char *buf, int buflen)
#define LALCalloc(m, n)
#define c
#define fprintf
int l
double e
#define LAL_PI
#define LAL_TWOPI
unsigned char BOOLEAN
uint64_t UINT8
double REAL8
#define XLAL_LAST_ELEM(x)
int64_t INT8
char CHAR
uint32_t UINT4
int32_t INT4
#define LAL_REAL8_FORMAT
void LogPrintf(LogLevel_t, const char *format,...) _LAL_GCC_PRINTF_FORMAT_(2
LOG_CRITICAL
LOG_DEBUG
LOG_NORMAL
static const INT4 r
static const INT4 a
void XLALDestroyREAL4Vector(REAL4Vector *vector)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
Type to hold the fields that will be kept in a "toplist"
REAL8 AlphaBest
skyposition of best candidate: longitude
REAL4 sumTwoF
sum of 2F-values as recomputed in LV postprocessing
REAL8 Delta
skyposition: latitude
REAL8 VarianceSig
variance of significance values in hough map
REAL8 f1dot
spindown value f1dot = df/dt
REAL8 Alpha
Skyposition: longitude in equatorial coords, radians.
REAL4Vector * sumTwoFX
sum of 2F-values per detector, computed in LV postprocessing
REAL8 Freq
Frequency at maximum (?) of the cluster.
REAL8 DeltaBest
skyposition of best candidate: latitude
REAL8 MeanSig
mean of significance values in hough map
REAL8 HoughFstat
Hough significance.
REAL4 * data
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