hveto.c 17.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 *  Copyright (C) 2013 Chris Pankow
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with with program; see the file COPYING. If not, write to the
 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 */

#include <lal/LALDetCharHveto.h>
21
#include <lal/LALDetCharHvetoUtils.h>
22
#include <lal/LIGOLwXML.h>
23

24 25 26 27 28
#ifndef _OPENMP
#define omp ignore
#endif


29 30 31 32 33 34 35
// Program level functions, mostly utility

// Fake a series of triggers
void populate_trig_sequence( GSequence* trig_sequence );
// Read a series of triggers from XML
void populate_trig_sequence_from_file( GSequence* trig_sequence, const char* fname, double min_snr, GSequence* ignore_list );
// print a hash table of string / int entries
36
void print_hash_table( GHashTable* tbl, const char* file );
Chris Pankow's avatar
Chris Pankow committed
37 38
// print a hash table of string / float entries
void print_hash_table_float( GHashTable* tbl, const char* file );
39 40
// print a hash table of string / string entries
void print_hash_table_string( GHashTable* tbl, const char* file );
41 42 43 44
// Read a sequence of channels to ignore
void get_ignore_list( const char* fname, GSequence* ignorelist );
// retrieve live time
void calculate_livetime( const char* fname, LALSegList* live_segs );
45 46
// Write trigger set
void write_triggers( GSequence* trig_sequence, const char* fname );
47

Chris Pankow's avatar
Chris Pankow committed
48 49 50 51
// Encode / Decode a subround winner
void encode_rnd_str(char* winner, double wind, double thresh);
void decode_rnd_str(char* winner_str, char* chan, double* wind, double* thresh);

52 53 54
// Get a listing of the channels included
GHashTable* get_channel_list( GSequence* triglist );

55 56 57 58

//int main(int argc, char** argv){
int main(int argc, char** argv){

59 60 61 62 63 64 65 66 67
	/*
    * WHich channels should we ignore?
    *
    * This list will be applied to the triggers as they are read in so as to
    * avoid unnecessary cutting and/or masking later.
    *
    * TODO: Since we mask triggers anyway, maybe the ignore list can be turned
    * into a safety study before the full algorithm kicks in.
    */
68
	GSequence* ignorelist = g_sequence_new(XLALFree);
69 70
	if( argc > 4 ){
		get_ignore_list( argv[4], ignorelist );
71 72 73
	}


74 75 76
	/*
	 * Round parameters
	 */
77
	double sig_thresh = 15.0;
78
	// TODO: Significance or SNR option
79 80 81 82 83 84 85 86
	/*
	 * Minimum threshold for the reference channel SNR and minimum threshold
	 * for the auxilary channel SNR. Treated differently since the reference
	 * channel might be mixed in with the other channels.
	 *
	 * These thresholds are applied at the time the triggers are read, so no
	 * triggers below these SNRs are even seen.
	 */
87 88 89 90 91 92 93 94 95 96 97
	// Example 2
	double min_de_snr = 8, min_aux_snr = 10;
	int nthresh = 7, nwinds = 5;
	//int nthresh = 1, nwinds = 1;
	double aux_snr_thresh[7] = {300.0, 100.0, 40.0, 20.0, 15.0, 12.0, 10.0};
	//double aux_snr_thresh[7] = {10.0};
	double twins[5] = {0.1, 0.2, 0.4, 0.8, 1.0};
	//double twins[5] = {0.2};

	// Example 1
	/*
Chris Pankow's avatar
Chris Pankow committed
98 99 100 101 102 103 104
	double min_de_snr = 30, min_aux_snr = 50;
	int nthresh = 8;
	double aux_snr_thresh[8] = {3200.0, 1600.0, 800.0, 600.0, 400.0, 200.0, 100.0, 50.0};
	int nwinds = 5;
	double twins[5] = {0.1, 0.2, 0.4, 0.8, 1.0};
	*/

105
	GSequence* trig_sequence = g_sequence_new((GDestroyNotify)XLALDestroySnglBurst);
106 107
	// Do hveto on *all* channel pairs, not just reference channel
	gboolean all_chans = FALSE;
108

109
	// Read in our triggers
110
	char refchan[1024];
111
	if( argc > 2 ){
112
		strcpy(refchan, "LSC-DARM_ERR");
113 114
		printf( "Reading file: %s\n", argv[2] );
		populate_trig_sequence_from_file( trig_sequence, argv[2], min_de_snr, ignorelist );
Chris Pankow's avatar
Chris Pankow committed
115
		printf( "list Length: %d\n", g_sequence_get_length( trig_sequence ) );
116 117
		printf( "Reading file: %s\n", argv[1] );
		populate_trig_sequence_from_file( trig_sequence, argv[1], min_aux_snr, ignorelist );
118 119
	} else {
		strcpy(refchan, "CHAN1");
120
		populate_trig_sequence( trig_sequence );
121
	}
122 123 124 125 126

	// Get the channel list
	GHashTable* chanlist = get_channel_list( trig_sequence );
	print_hash_table_string( chanlist, NULL );

Chris Pankow's avatar
Chris Pankow committed
127 128
	printf( "list Length: %d\n", g_sequence_get_length( trig_sequence ) );
	printf( "Reference channel: %s\n", refchan );
129 130 131 132 133 134 135 136

	GSequenceIter* igitr = g_sequence_get_begin_iter(ignorelist);
	while( !g_sequence_iter_is_end(igitr) ){
		printf( "Ignoring %s\n", (char *)g_sequence_get(igitr) );
		igitr = g_sequence_iter_next(igitr);
	}
	g_sequence_free(ignorelist);

Chris Pankow's avatar
Chris Pankow committed
137 138
	LALSegList live;
	XLALSegListInit( &live );
139
	double livetime = 0;
140 141 142 143 144 145
	if( argc > 3 ){
		const char* livefname = argv[3];
		printf( "Livetime filename: %s\n", livefname );
		calculate_livetime( argv[3], &live );
		size_t i;
		for( i=0; i<live.length; i++ ){
146 147
			LALSeg s = live.segs[i];
			livetime += XLALGPSDiff( &s.end, &s.start );
148
			printf( "Segment #%zu:\t(%d.%d %d.%d)\t%f\t%f\n",
149 150 151
				i, s.start.gpsSeconds, s.start.gpsNanoSeconds, 
				s.end.gpsSeconds, s.end.gpsNanoSeconds, 
				XLALGPSDiff( &s.end, &s.start ), livetime );
152
		}
153 154
		printf( "Livetime: %f\n", livetime );

Chris Pankow's avatar
Chris Pankow committed
155
		XLALSegListSort( &live );
156
		printf( "Before prune, length: %d\n", g_sequence_get_length( trig_sequence ) );
Chris Pankow's avatar
Chris Pankow committed
157
		XLALDetCharPruneTrigs( trig_sequence, &live, min_de_snr, NULL );
158
		printf( "After prune, length: %d\n", g_sequence_get_length( trig_sequence ) );
159 160 161 162 163
	}

	LALSegList vetoes;
	XLALSegListInit( &vetoes );

Chris Pankow's avatar
Chris Pankow committed
164
	GHashTable *chancount, *chanhist, *subround_winners;
165 166 167
	//chanhist = g_hash_table_new_full( g_str_hash, g_str_equal, &g_free, &g_free );
	chanhist = g_hash_table_new( g_str_hash, g_str_equal );
	chancount = g_hash_table_new( g_str_hash, g_str_equal );
Chris Pankow's avatar
Chris Pankow committed
168
	subround_winners = g_hash_table_new( g_str_hash, g_str_equal );
169 170 171

	int rnd = 1;

172 173
	double wind = 0.8;
	int coinc_type = 1; // unique coincidences
Chris Pankow's avatar
Chris Pankow committed
174
	double rnd_sig = 0;
175

176
	char bdir[512], outpath[1024], cmd[1024];
177

178 179
	GList *channames = g_hash_table_get_keys( chancount );
	size_t nchans = g_list_length( channames ) - 1;
180 181
	nwinds--;
	nthresh--;
Chris Pankow's avatar
Chris Pankow committed
182 183 184 185

	/*
	 * Veto round loop.
	 */
186
	do {
Chris Pankow's avatar
Chris Pankow committed
187 188 189
		printf( "Round %d\n", rnd );
		
		// Set up the output path for this round
190 191 192
		sprintf( bdir, "round_%d", rnd );
		sprintf( cmd, "mkdir -p %s", bdir );
		system( cmd );
193

Chris Pankow's avatar
Chris Pankow committed
194
		// Clear the winners of the previous subrounds
195
		// FIXME: Free memory?
Chris Pankow's avatar
Chris Pankow committed
196 197 198 199 200 201
		g_hash_table_remove_all( subround_winners );

		/*
		 * FIXME: We can do this more efficiently by passing this to the scan
		 * function, and only doing a single pass.
		 */
202
		char *winner = NULL;
203
		double *sig = XLALMalloc(sizeof(double));
Chris Pankow's avatar
Chris Pankow committed
204 205 206 207
		int nw = nwinds, nt = nthresh;
		for( nt=nthresh; nt >= 0; nt-- ){
			min_aux_snr = aux_snr_thresh[nt];
			XLALDetCharPruneTrigs( trig_sequence, &live, min_aux_snr, refchan );
208
			printf( "SNR threshold (#%d) %f, triggers remaining: %d\n", nt, min_aux_snr, g_sequence_get_length( trig_sequence ) );
Chris Pankow's avatar
Chris Pankow committed
209 210
			for( nw=nwinds; nw >= 0; nw-- ){
				wind = twins[nw];
211
				printf( "Window (#%d) %f\n", nw, wind );
212 213
				winner = XLALMalloc( sizeof(char) );
                                *winner = '\0';
Chris Pankow's avatar
Chris Pankow committed
214

215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
				GHashTableIter chanit;
				g_hash_table_iter_init( &chanit, chanlist );
				gpointer chan1, chan2;
				while( g_hash_table_iter_next( &chanit, &chan1, &chan2 ) ){
					// Are we doing all channels or just the reference?
					if( !(strstr( refchan, chan1 ) || all_chans) ){
							continue;
					}

					// Set up the output path for this round / channel
					sprintf( bdir, "round_%d/%s/", rnd, (char *)chan1 );
					sprintf( cmd, "mkdir -p %s", bdir );
					system( cmd );

					// Create our channel coincidence histogram
					// FIXME: Free memory?
					printf( "Clearing coincidence table\n" );
					g_hash_table_remove_all( chanhist );
					// Create our channel count histogram
					// FIXME: Free memory?
					printf( "Clearing count table\n" );
					g_hash_table_remove_all( chancount );

					// TODO: Is there a way to avoid a rescan every round?
					XLALDetCharScanTrigs( chancount, chanhist, trig_sequence, (char*)chan1, wind, coinc_type );
					printf( "Trigger count:\n" );
					print_hash_table( chancount, NULL );
					sprintf( outpath, "%s/%s_%d_%d_count.txt", bdir, (char *)chan1, nt, nw );
					print_hash_table( chancount, outpath );
					printf( "Trigger coincidences with %s, window (%g):\n", (char*)chan1, wind );
					print_hash_table( chanhist, NULL );
					sprintf( outpath, "%s/%s_%d_%d_coinc.txt", bdir, (char *)chan1, nt, nw );
					print_hash_table( chanhist, outpath );
				}
Chris Pankow's avatar
Chris Pankow committed
249 250 251 252 253 254 255 256 257

				/* 
				 * If there's no value for the target channel, there's no 
				 * vetoes to do, move on.
				 */
				double t_ratio = wind / livetime;
				if( !g_hash_table_lookup(chancount, refchan) ){
					fprintf( stderr, "No triggers in target channel.\n" );
					break;
258 259
				} else if( g_hash_table_size(chanhist) == 0 ){
					fprintf( stderr, "No coincidences with target channel.\n" );
260
					XLALFree( winner );
261
					continue;
Chris Pankow's avatar
Chris Pankow committed
262
				} else {
263
					rnd_sig = XLALDetCharVetoRound( &winner, chancount, chanhist, refchan, t_ratio );
Chris Pankow's avatar
Chris Pankow committed
264 265
				}

266
				sig = XLALMalloc(sizeof(double));
Chris Pankow's avatar
Chris Pankow committed
267 268 269 270 271 272
				*sig = rnd_sig;
				printf( "Sub-round winner, window %2.2f, thresh %f: %s sig %g\n",  wind, min_aux_snr, winner, *sig );
				encode_rnd_str( winner, wind, min_aux_snr), 
				g_hash_table_insert( subround_winners, winner, sig );

			}
273
		}
274 275 276 277
		if( g_hash_table_size( subround_winners ) == 0 ){
			// no subround winners, just bail
			break;
		}
Chris Pankow's avatar
Chris Pankow committed
278 279 280 281 282
		print_hash_table_float( subround_winners, NULL );

		// Get the winner over all the subrounds
		GHashTableIter subrnd;
		g_hash_table_iter_init( &subrnd, subround_winners );
283
		char *chanwin = NULL;
Chris Pankow's avatar
Chris Pankow committed
284 285 286 287 288 289 290 291 292 293 294 295 296 297
		gpointer val, key;

		rnd_sig = 0;
		while( g_hash_table_iter_next( &subrnd, &key, &val ) ){
			if( *(double*)val > rnd_sig ){
				rnd_sig = *(double*)val;
				chanwin = (char*)key;
				printf( "rnd_sig: %g\n", rnd_sig );
				printf( "New winner: %s\n", chanwin );
			}
		}

		decode_rnd_str( chanwin, winner, &wind, &min_aux_snr );
		printf( "Done, round %d, winner: %s\n\tsignificance %g\n\twindow: %lf\n\tsnr thresh: %lf\n", rnd, winner, rnd_sig, wind, min_aux_snr );
298

299 300
		if( rnd_sig > sig_thresh ){
			// TODO: Subtract vetoed livetime.
301 302 303 304 305 306 307
			//XLALSegListAppend( vetoes, wind );
			LALSeg veto;
			LIGOTimeGPS start;
			LIGOTimeGPS stop;
			XLALGPSSetREAL8( &start, -wind/2.0 );
			XLALGPSSetREAL8( &stop, wind/2.0 );
			XLALSegSet( &veto, &start, &stop, 0 );
Chris Pankow's avatar
Chris Pankow committed
308
			// Remove the triggers veoted from the main list
309
			GSequence *vetoed_trigs = XLALDetCharRemoveTrigs( trig_sequence, veto, winner, min_aux_snr );
310
			sprintf( outpath, "%s/round_%d_vetoed_triggers.xml", bdir, rnd );
Chris Pankow's avatar
Chris Pankow committed
311 312 313 314
			// Write them for later use
			if( g_sequence_get_length(vetoed_trigs) > 0 ){
				write_triggers( vetoed_trigs, outpath );
			}
315 316 317 318 319 320

			// Remove livetime
			// livetime -= XLALDetCharHvetoExciseSegment( live, vetosegs );
			// TODO: Do this right
			livetime -= wind*g_sequence_get_length( vetoed_trigs );

Chris Pankow's avatar
Chris Pankow committed
321
			// Begone witcha!
322
			g_sequence_free( vetoed_trigs );
323

324
			/*
Chris Pankow's avatar
Chris Pankow committed
325 326 327
			 * TODO: This as supposed to remove the channel from the from list
			 * but we rescan anyway, so all of this is redundant -- regardless,
			 * this memory should be freed.
328 329 330
			char* key;
			size_t *value;
			gpointer *cname = (gpointer*)&key, *n = (gpointer*)&value;
331
			g_hash_table_lookup_extended( chanhist, winner, cname, n );
332 333
			g_free(key);
			g_free(value);
334
			g_hash_table_remove( chanhist, winner );
335
			*/
336 337
		}
		rnd++;
338
		//if( rnd == 3 ) break;
339 340 341 342 343 344 345 346
	} while( rnd_sig > sig_thresh && (size_t)rnd < nchans );
	printf( "Last round did not pass significance threshold or all channels have been vetoed. Ending run.\n" );

	// TODO: Delete the key / value pairs still remaining
	g_hash_table_destroy( chanhist );
	g_hash_table_destroy( chancount );

	g_sequence_free( trig_sequence );
347
	g_hash_table_destroy( chanlist );
348

Chris Pankow's avatar
Chris Pankow committed
349
	XLALSegListClear( &live );
350 351 352 353 354 355 356
	XLALSegListClear( &vetoes );
	//LALCheckMemoryLeaks();
	return 0;
}

void populate_trig_sequence_from_file( GSequence* trig_sequence, const char* fname, double min_snr, GSequence* ignore_list ){
	SnglBurst* tbl = XLALSnglBurstTableFromLIGOLw( fname );
Chris Pankow's avatar
Chris Pankow committed
357
	SnglBurst *begin = NULL, *deleteme = NULL;
358 359
	if( !tbl ) return;

360 361 362 363 364
	//#pragma omp parallel
	//{
	//#pragma omp single
	//{
	//for( ; tbl; tbl=tbl->next ){
365
	do {
366 367
		//#pragma omp task
		//{
368
		gboolean ignore = FALSE;
369 370
		GSequenceIter* igitr;
		// FIXME: Support ignorelist == NULL
Chris Pankow's avatar
Chris Pankow committed
371 372
		igitr = ignore_list ? g_sequence_get_begin_iter(ignore_list) : NULL;
		while( (igitr != NULL) & !g_sequence_iter_is_end(igitr) ){
373 374 375 376 377
			/*
			 * Note this will cause incorrect behavior if the same channel name
			 * with different interferometers is included in the same run as
			 * the SB channel names do not include ifo by default.
			 */
378
			ignore = (strstr(g_sequence_get(igitr), tbl->channel) != NULL);
379 380 381 382 383 384
			if( !ignore ) {
				igitr = g_sequence_iter_next(igitr);
			} else {
				break;
			}
		}
385
		if( tbl->snr >= min_snr && !ignore ){
386
			//printf( "Adding event %p #%d, channel: %s\n", tbl, tbl->event_id, tbl->channel );
387
			g_sequence_insert_sorted( trig_sequence, tbl, XLALGLibCompareSnglBurst, NULL );
388
			tbl=tbl->next;
389
		} else {
390
			//printf( "Ignoring event %p #%d, channel: %s\n", tbl, tbl->event_id, tbl->channel );
Chris Pankow's avatar
Chris Pankow committed
391 392 393 394 395 396
			if( !deleteme ){
				begin = deleteme = tbl;
			} else {
				deleteme->next = tbl;
				deleteme = deleteme->next;
			}
397 398
			tbl=tbl->next;
		}
399 400
		//} // end pragma task
	//}
401
	} while( tbl );
402 403
	//} // end pragma single
	//} // end pragma parallel
Chris Pankow's avatar
Chris Pankow committed
404
	printf( "Deleting %d unused events.\n", XLALSnglBurstTableLength(begin) );
405
	deleteme->next = NULL; // Detach this from its sucessor in case that's used
Chris Pankow's avatar
Chris Pankow committed
406 407 408
	deleteme = NULL;
	XLALDestroySnglBurstTable(begin);
	printf( "Done.\n" );
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
}

void populate_trig_sequence( GSequence* trig_sequence ){

	char const *channel_list[] = {
		"CHAN1",
		"CHAN2",
		"CHAN3",
		"CHAN4",
		"CHAN5",
		"CHAN6"
	};

	SnglBurst* t = NULL;
	int i = 0;
	//for(; i<1000; i++){
	for(; i<1000; i++){
		t = XLALCreateSnglBurst();
		XLALGPSSet(&t->peak_time, rand() % 100, rand() % XLAL_BILLION_INT8);
		t->snr = 1;
		t->central_freq = 100;
		t->event_id = i;
		strcpy( t->channel, channel_list[rand()%6] );
		strcpy( t->ifo, "H1" );
433
		g_sequence_insert_sorted( trig_sequence, t, XLALGLibCompareSnglBurst, NULL );
434 435 436 437 438
		fprintf( stderr, "%d %s %d.%d\n", i, t->channel, t->peak_time.gpsSeconds, t->peak_time.gpsNanoSeconds );
	}
	fprintf( stderr, "\nCreated %d events\n", i );
}

439
void print_hash_table( GHashTable* tbl, const char* file ){
440 441 442
    GHashTableIter iter;
    gpointer key, val;
	g_hash_table_iter_init( &iter, tbl );
443 444 445 446
	FILE* outfile = NULL;
	if( file ){
		outfile = fopen( file, "w" );
	}
447
	while( g_hash_table_iter_next( &iter, &key, &val ) ){
448
		if( file ){
449
			fprintf( outfile, "%s: %zu\n", (char *)key, *(size_t*)val );
450
		} else {
451
			printf( "%s: %zu\n", (char *)key, *(size_t*)val );
452 453 454 455
		}
	}
	if( outfile ){
		fclose( outfile );
456 457
	}
}
Chris Pankow's avatar
Chris Pankow committed
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
void print_hash_table_float( GHashTable* tbl, const char* file ){
    GHashTableIter iter;
    gpointer key, val;
	g_hash_table_iter_init( &iter, tbl );
	FILE* outfile = NULL;
	if( file ){
		outfile = fopen( file, "w" );
	}
	while( g_hash_table_iter_next( &iter, &key, &val ) ){
		if( file ){
			fprintf( outfile, "%s: %f\n", (char *)key, *(double*)val );
		} else {
			printf( "%s: %f\n", (char *)key, *(double*)val );
		}
	}
	if( outfile ){
		fclose( outfile );
	}
}
477

478 479 480 481 482 483 484 485 486 487
void print_hash_table_string( GHashTable* tbl, const char* file ){
    GHashTableIter iter;
    gpointer key, val;
	g_hash_table_iter_init( &iter, tbl );
	FILE* outfile = NULL;
	if( file ){
		outfile = fopen( file, "w" );
	}
	while( g_hash_table_iter_next( &iter, &key, &val ) ){
		if( file ){
488
			fprintf( outfile, "%s: %s\n", (char *)key, (char*)val );
489
		} else {
490
			printf( "%s: %s\n", (char *)key, (char*)val );
491 492 493 494 495 496 497
		}
	}
	if( outfile ){
		fclose( outfile );
	}
}

498 499 500
void get_ignore_list( const char* fname, GSequence* ignorel ){

	int cnt = 0;
501
	char* tmp;
502
	tmp = XLALMalloc( sizeof(char)*512 );
503 504
	FILE* lfile = fopen( fname, "r" );
	while(!feof(lfile)){
505
		cnt = fscanf( lfile, "%s", tmp );
506
		if( cnt == EOF ) break;
507 508
		g_sequence_append( ignorel, g_strdup(tmp) );
	}
509
	XLALFree(tmp);
510 511 512 513 514
	fclose(lfile);
}

void calculate_livetime( const char* fname, LALSegList* live_segs ){
	FILE* lfile = fopen( fname, "r" );
515 516
	//float st, end;
	int st, end;
517 518 519
	LALSeg *seg;
	int cnt = 0;
	while(!feof(lfile)){
520 521 522
		// FIXME: Having floats here causes a 32 second offset for both values
		//cnt = fscanf( lfile, "%f %f", &st, &end );
		cnt = fscanf( lfile, "%d %d", &st, &end );
523 524 525
		if( cnt == EOF ) break;
		LIGOTimeGPS start;
		LIGOTimeGPS stop;
526 527
		XLALGPSSetREAL8( &start, (double)st );
		XLALGPSSetREAL8( &stop, (double)end );
528 529 530 531 532 533
		seg = XLALSegCreate( &start, &stop, 0 );
		XLALSegListAppend( live_segs, seg );
		XLALFree( seg );
	}
	fclose(lfile);
}
534 535 536 537 538 539

void write_triggers( GSequence* trig_sequence, const char* fname ){

	// Convert a sequence back into SnglBurst
	GSequenceIter* sbit;
	SnglBurst *begin, *sb, *tmp;
Chris Pankow's avatar
Chris Pankow committed
540
	begin = sb = NULL;
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
	sbit = g_sequence_get_begin_iter( trig_sequence );
	while( !g_sequence_iter_is_end( sbit ) ){
		tmp = (SnglBurst*) g_sequence_get( sbit );
		sbit = g_sequence_iter_next( sbit );
		if( sb ){
			sb->next = tmp;
			sb = sb->next;
		} else {
			begin = sb = tmp;
		}
	}
	sb->next = NULL;
	
	LIGOLwXMLStream *str;
	str = XLALOpenLIGOLwXMLFile( fname );
	XLALWriteLIGOLwXMLSnglBurstTable( str, begin );
	XLALCloseLIGOLwXMLFile( str );
}
Chris Pankow's avatar
Chris Pankow committed
559 560

void encode_rnd_str(char* winner, double wind, double thresh){
561
	//winner = XLALRealloc( winner, sizeof(winner)+20*sizeof(char));
Chris Pankow's avatar
Chris Pankow committed
562 563 564 565 566
	sprintf( winner, "%s %1.5f %4.2f", winner, wind, thresh );
}
void decode_rnd_str(char* winner_str, char* chan, double* wind, double* thresh){
	sscanf( winner_str, "%s %lf %lf", chan, wind, thresh );
}
567 568 569 570 571 572 573

GHashTable* get_channel_list( GSequence* triglist ){
	GSequenceIter* itr = g_sequence_get_begin_iter(triglist);

	GHashTable* channellist = g_hash_table_new( g_str_hash, g_str_equal );
	while( !g_sequence_iter_is_end(itr) ){
		SnglBurst *sb = (SnglBurst*)g_sequence_get(itr);
574
		g_hash_table_insert( channellist, g_strdup(sb->channel), g_strdup(sb->channel) );
575 576 577 578
		itr = g_sequence_iter_next(itr);
	}
	return channellist;
}