Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALApps 10.1.0.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
splitbank.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Duncan Brown
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20/*-----------------------------------------------------------------------
21 *
22 * File Name: splitbank.c
23 *
24 * Author: Brown, D. A.
25 *
26 *
27 *-----------------------------------------------------------------------
28 */
29
30/**
31 * \file
32 * \ingroup lalapps_inspiral
33 *
34 * <dl>
35 * <dt>Name</dt><dd>
36 * \c lalapps_splitbank --- splits a template bank file into several smaller
37 * files</dd>
38 *
39 * <dt>Synopsis</dt><dd>
40 * <tt>lalapps_splitbank</tt>
41 * <tt>--bank-file</tt> <i>file</i>
42 * <tt>--comment</tt> <i>comment</i>
43 * <tt>--help</tt>
44 * <tt>--minimal-match</tt> <i>m</i>
45 * <tt>--number-of-banks</tt> <i>n</i>
46 * <tt>--user-tag</tt> <i>comment</i>
47 * <tt>--verbose</tt>
48 * <tt>--version</tt> </dd>
49 *
50 * <dt>Description</dt><dd>
51 * \c lalapps_splitbank splits a LIGO_LW XML file containing inspiral
52 * templates in a \c sngl_inspiral table into several smaller bank
53 * files. This allows a template bank to be split across several inspiral
54 * jobs and then recombined with \c lalapps_inca or
55 * \c lalapps_sire.
56 *
57 * The name of the output template bank files is derived from the name of
58 * the input bank file and the number of files that the bank should be split
59 * into. For example, if the input bank file:\\
60 *
61 * <tt>H1-TRIGBANK_L1-729330491-2048.xml</tt>\\
62 *
63 * is split into 3 output files, then these will be named:\\
64 *
65 * <tt>H1-TRIGBANK_L1_00-729330491-2048.xml</tt>\\
66 * <tt>H1-TRIGBANK_L1_01-729330491-2048.xml</tt>\\
67 * <tt>H1-TRIGBANK_L1_02-729330491-2048.xml</tt>\\
68 *
69 * The naming convention is to insert the bank file number after the usertag part
70 * of the filename and before the GPS start time part of the file name.
71 *
72 * In the case that the input file contains no templates, empty output bank files
73 * are generated. This is done since DAGman does not implement decision rules
74 * yet, so the nodes in the DAG must be identical regardless of the data flowing
75 * through them.</dd>
76 *
77 * <dt>Options</dt><dd>
78 * <dl>
79 *
80 * <dt><tt>--bank-file</tt> <i>file</i></dt><dd>
81 * Read the templates from the \c sngl_inspiral table in the file <i>file</i>.</dd>
82 *
83 * <dt> <tt>--comment</tt> <i>comment</i></dt><dd>
84 * Add the string <i>comment</i> to the \c process table in the output XML file.</dd>
85 *
86 * <dt><tt>--help</tt></dt><dd>
87 * Display a usage message and exit.</dd>
88 *
89 * <dt><tt>--minimal-match</tt> <i>m</i></dt><dd>
90 * Set the minimal match of the output template bank file to <i>m</i>.
91 * This option is not really needed for running \c lalapps_splitbank, it just put that value of <i>m</i> for the minimal match in all splited template banks.</dd>
92 *
93 * <dt><tt>--number-of-banks</tt> <i>n</i></dt><dd>
94 * Split the input template banks into <i>n</i> seperate output bank files.</dd>
95 *
96 * <dt><tt>--user-tag</tt> <i>comment</i></dt><dd>
97 * Set the user tag to the string <i>comment</i>. This string must not
98 * contain spaces or dashes ("-"). This string will appear in the name of
99 * the file to which output information is written, and is recorded in the
100 * various XML tables within the file.</dd>
101 *
102 * <dt><tt>--verbose</tt></dt><dd>
103 * Print debugging information to the
104 * standard output while executing.</dd>
105 *
106 * <dt><tt>--version</tt></dt><dd>
107 * Print the CVS id and exit.
108 * </dd>
109 * </dl></dd>
110 *
111 * <dt>Example</dt><dd>
112 * \code
113 * lalapps_splitbank --bank-file L1-TMPLTBANK-732488741-2048.xml \
114 * --number-of-banks 3 --minimal-match 0.97
115 * \endcode</dd>
116 *
117 * <dt>Algorithm</dt><dd>
118 * \c lalapps_splitbank counts the number of templates in the input file.
119 * It increments this by one and divides by the number of template banks to
120 * generate using standard integer division. This gives the upper limit on the
121 * number of templates in a single output file.</dd>
122 *
123 * <dt>Author</dt><dd>
124 * Duncan Brown and Alexander Dietz</dd>
125 * </dl>
126 */
127
128#include <config.h>
129#include <math.h>
130#include <stdio.h>
131#include <stdlib.h>
132#include <string.h>
133#include <sys/types.h>
134#include <sys/stat.h>
135#include <fcntl.h>
136#include <regex.h>
137#include <time.h>
138
139#include <lal/LALConfig.h>
140#include <lal/LALgetopt.h>
141#include <lal/LALStdio.h>
142#include <lal/LALStdlib.h>
143#include <lal/LALError.h>
144#include <lal/LALDatatypes.h>
145#include <lal/LIGOLwXML.h>
146#include <lal/LIGOLwXMLRead.h>
147#include <lal/LIGOMetadataTables.h>
148#include <lal/LIGOMetadataUtils.h>
149#include <lal/Date.h>
150
151#include <LALAppsVCSInfo.h>
152
153#define CVS_ID_STRING "$Id$"
154#define CVS_REVISION "$Revision$"
155#define CVS_SOURCE "$Source$"
156#define CVS_DATE "$Date$"
157#define PROGRAM_NAME "splitbank"
158
159#define USAGE \
160"Usage: %s [options] [LIGOLW XML input files]\n\n"\
161" --help display this message\n"\
162" --verbose print progress information\n"\
163" --version print version information\n"\
164" --user-tag STRING set the process_params usertag to STRING\n"\
165" --comment STRING set the process table comment to STRING\n"\
166"\n"\
167" --bank-file FILE read template bank parameters from FILE\n"\
168" --number-of-banks N split template bank into N files\n"\
169" --minimal-match M set minimal match of triggered bank to M\n"\
170
171extern int vrbflg; /* verbocity of lal function */
172
173
174int main ( int argc, char *argv[] )
175{
176 /* lal function variables */
178
179 /* template bank generation parameters */
180 CHAR *bankFileName = NULL;
181 INT4 numOutBanks = 0;
182 REAL4 minMatch = -1;
183
184 /* output data */
185 SnglInspiralTable *inputBank;
186 SnglInspiralTable *outputBank;
187 ProcessTable *proctable;
188 ProcessParamsTable *procparams;
189 ProcessParamsTable *this_proc_param;
190 LIGOLwXMLStream *xmlStream;
191
192 /* counters and other variables */
193 INT4 i, j;
194 INT4 numTmplts = 0;
195 INT4 numTmpltsWritten = 0;
196 INT4 numPerFile = 0;
197 CHAR *gpsHyphen;
198 char outBankFileName[FILENAME_MAX];
199 CHAR bankFileNameHead[FILENAME_MAX];
200 CHAR bankFileNameTail[FILENAME_MAX];
202 CHAR *userTag = NULL;
203 SnglInspiralTable *thisTmplt = NULL;
204 SnglInspiralTable *tmpTmplt = NULL;
205
206 /* LALgetopt arguments */
207 struct LALoption long_options[] =
208 {
209 {"verbose", no_argument, &vrbflg, 1 },
210 {"version", no_argument, 0, 'V'},
211 {"user-tag", required_argument, 0, 'Z'},
212 {"userTag", required_argument, 0, 'Z'},
213 {"comment", required_argument, 0, 's'},
214 {"help", no_argument, 0, 'h'},
215 {"bank-file", required_argument, 0, 'v'},
216 {"number-of-banks", required_argument, 0, 'n'},
217 {"minimal-match", required_argument, 0, 'M'},
218 {0, 0, 0, 0}
219 };
220 int c;
221
222
223 /*
224 *
225 * initialize things
226 *
227 */
228
229
231 setvbuf( stdout, NULL, _IONBF, 0 );
232
233 /* create the process and process params tables */
234 proctable = (ProcessTable *) calloc( 1, sizeof(ProcessTable) );
235 XLALGPSTimeNow(&(proctable->start_time));
238 this_proc_param = procparams =
239 (ProcessParamsTable *) calloc( 1, sizeof(ProcessParamsTable) );
240 memset( comment, 0, LIGOMETA_COMMENT_MAX * sizeof(CHAR) );
241
242
243 /*
244 *
245 * parse command line arguments
246 *
247 */
248
249
250 while ( 1 )
251 {
252 /* LALgetopt_long stores long option here */
253 int option_index = 0;
254 size_t LALoptarg_len;
255
256 c = LALgetopt_long_only( argc, argv,
257 "i:n:VZ:hs:M:",
258 long_options, &option_index );
259
260 /* detect the end of the options */
261 if ( c == - 1 )
262 {
263 break;
264 }
265
266 switch ( c )
267 {
268 case 0:
269 /* if this option set a flag, do nothing else now */
270 if ( long_options[option_index].flag != 0 )
271 {
272 break;
273 }
274 else
275 {
276 fprintf( stderr, "error parsing option %s with argument %s\n",
277 long_options[option_index].name, LALoptarg );
278 exit( 1 );
279 }
280 break;
281
282 case 'v':
283 LALoptarg_len = strlen( LALoptarg ) + 1;
284 bankFileName = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR));
285 memcpy( bankFileName, LALoptarg, LALoptarg_len );
286 snprintf( procparams->program,
288 snprintf( procparams->type, LIGOMETA_TYPE_MAX, "string" );
289 snprintf( procparams->param,
290 LIGOMETA_PARAM_MAX, "--%s", long_options[option_index].name );
291 snprintf( procparams->value, LIGOMETA_VALUE_MAX, "%s", LALoptarg );
292 break;
293
294 case 'n':
295 numOutBanks = (INT4) atoi( LALoptarg );
296 if ( numOutBanks < 0 )
297 {
298 fprintf( stderr, "invalid argument to --%s:\n"
299 "Number of output banks must be greater than zero:"
300 "(%d specified)\n",
301 long_options[option_index].name, numOutBanks );
302 exit( 1 );
303 }
304 else if ( numOutBanks > 99 )
305 {
306 fprintf( stderr,
307 "Warning: generating more than 99 banks is not reccomended!\n" );
308 }
309 this_proc_param = this_proc_param->next = (ProcessParamsTable *)
310 calloc( 1, sizeof(ProcessParamsTable) );
311 snprintf( this_proc_param->program, LIGOMETA_PROGRAM_MAX,
312 "%s", PROGRAM_NAME );
313 snprintf( this_proc_param->type, LIGOMETA_TYPE_MAX, "int" );
314 snprintf( this_proc_param->param, LIGOMETA_PARAM_MAX,
315 "--%s", long_options[option_index].name );
316 snprintf( this_proc_param->value, LIGOMETA_VALUE_MAX, "%d",
317 numOutBanks );
318 break;
319
320 case 's':
321 if ( strlen( LALoptarg ) > LIGOMETA_COMMENT_MAX - 1 )
322 {
323 fprintf( stderr, "invalid argument to --%s:\n"
324 "comment must be less than %d characters\n",
325 long_options[option_index].name, LIGOMETA_COMMENT_MAX );
326 exit( 1 );
327 }
328 else
329 {
330 snprintf( comment, LIGOMETA_COMMENT_MAX, "%s", LALoptarg );
331 }
332 break;
333
334 case 'Z':
335 /* create storage for the usertag */
336 LALoptarg_len = strlen( LALoptarg ) + 1;
337 userTag = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR) );
338 memcpy( userTag, LALoptarg, LALoptarg_len );
339
340 this_proc_param = this_proc_param->next = (ProcessParamsTable *)
341 calloc( 1, sizeof(ProcessParamsTable) );
342 snprintf( this_proc_param->program, LIGOMETA_PROGRAM_MAX, "%s",
343 PROGRAM_NAME );
344 snprintf( this_proc_param->type, LIGOMETA_TYPE_MAX, "string" );
345 snprintf( this_proc_param->param, LIGOMETA_PARAM_MAX, "-userTag" );
346 snprintf( this_proc_param->value, LIGOMETA_VALUE_MAX, "%s",
347 LALoptarg );
348 break;
349
350 case 'M':
351 minMatch = (REAL4) atof( LALoptarg );
352 if ( minMatch <= 0 )
353 {
354 fprintf( stdout, "invalid argument to --%s:\n"
355 "minimal match of bank must be > 0: "
356 "(%f specified)\n",
357 long_options[option_index].name, minMatch );
358 exit( 1 );
359 }
360 this_proc_param = this_proc_param->next = (ProcessParamsTable *)
361 calloc( 1, sizeof(ProcessParamsTable) );
362 snprintf( this_proc_param->program, LIGOMETA_PROGRAM_MAX, "%s",
363 PROGRAM_NAME );
364 snprintf( this_proc_param->type, LIGOMETA_TYPE_MAX, "float" );
365 snprintf( this_proc_param->param, LIGOMETA_PARAM_MAX, "--%s",
366 long_options[option_index].name );
367 snprintf( this_proc_param->value, LIGOMETA_VALUE_MAX, "%e",
368 minMatch );
369 break;
370
371 case 'V':
372 /* print version information and exit */
373 fprintf( stdout, "Inspiral Template Bank Splitter\n"
374 "Duncan Brown <duncan@gravity.phys.uwm.edu>\n");
375 XLALOutputVCSInfo(stderr, lalAppsVCSInfoList, 0, "%% ");
376 exit( 0 );
377 break;
378
379 case '?':
380 fprintf( stderr, USAGE, argv[0] );
381 exit( 1 );
382 break;
383
384 default:
385 fprintf( stderr, "unknown error while parsing options\n" );
386 fprintf( stderr, USAGE, argv[0] );
387 exit( 1 );
388 }
389 }
390
391 if ( LALoptind < argc )
392 {
393 fprintf( stderr, "extraneous command line arguments:\n" );
394 while ( LALoptind < argc )
395 {
396 fprintf ( stderr, "%s\n", argv[LALoptind++] );
397 }
398 exit( 1 );
399 }
400
401 /* check the values of the arguments */
402 if ( ! bankFileName )
403 {
404 fprintf( stderr, "Error: --bank-file must be specified\n" );
405 exit( 1 );
406 }
407
408 if ( ! numOutBanks )
409 {
410 fprintf( stderr, "Error: --number-of-banks must be specified\n" );
411 exit( 1 );
412 }
413
414 if ( minMatch < 0 )
415 {
416 fprintf( stderr, "Error: --minimal-match must be specified\n" );
417 exit( 1 );
418 }
419
420
421 /*
422 *
423 * read in the template bank from the input file
424 *
425 */
426
427
428 /* read in the template bank from a ligo lw xml file */
429 inputBank = XLALSnglInspiralTableFromLIGOLw( bankFileName );
430 if ( !inputBank )
431 {
432 fprintf( stderr, "error: unable to read templates from %s\n",
433 bankFileName );
434 exit( 1 );
435 }
436
437 {
439 for(numTmplts = 0, row = inputBank; row; numTmplts++, row = row->next);
440 }
441
442 if ( vrbflg ) fprintf( stdout, "read %d templates from %s\n",
443 numTmplts, bankFileName );
444
445 /* find the hypen just before the GPS start time of the bank */
446 gpsHyphen = NULL;
447 gpsHyphen = strstr( bankFileName, "-" );
448 if ( ! gpsHyphen )
449 {
450 fprintf( stderr, "Error: could not find first hypen in file name %s\n",
451 bankFileName );
452 exit( 1 );
453 }
454 gpsHyphen = strstr( gpsHyphen + 1, "-" );
455 if ( ! gpsHyphen )
456 {
457 fprintf( stderr, "Error: could not find second hypen in file name %s\n",
458 bankFileName );
459 exit( 1 );
460 }
461
462 /* store the name of the template bank file */
463 memcpy( bankFileNameHead, bankFileName,
464 (size_t) gpsHyphen - (size_t) bankFileName < FILENAME_MAX ?
465 (gpsHyphen - bankFileName) * sizeof(CHAR) : FILENAME_MAX * sizeof(CHAR) );
466 strncpy( bankFileNameTail, gpsHyphen + 1, FILENAME_MAX - 1 );
467
468 if ( vrbflg )
469 {
470 fprintf( stdout, "head of bank file name is %s\n", bankFileNameHead );
471 fprintf( stdout, "tail of bank file name is %s\n", bankFileNameTail );
472 }
473
474
475 /*
476 *
477 * write out the individual tempate bank files
478 *
479 */
480
481
482 /* compute the number of templates per output file */
483 numPerFile = floor( ( numTmplts - 0.5 )/ numOutBanks + 1 );
484 thisTmplt = inputBank;
485 if ( vrbflg ) fprintf( stdout, "writing around %d templates per file\n",
486 numPerFile );
487
488 for ( i = 0; i < numOutBanks; ++i )
489 {
490 /* open the output xml file */
491 memset( outBankFileName, 0, FILENAME_MAX * sizeof(CHAR) );
492 if(snprintf( outBankFileName, FILENAME_MAX, "%s_%02d-%s",
493 bankFileNameHead, i, bankFileNameTail ) >= FILENAME_MAX)
494 abort();
495 xmlStream = XLALOpenLIGOLwXMLFile( outBankFileName );
496
497 if ( vrbflg )
498 fprintf( stdout, "writing templates to %s... ", outBankFileName );
499
500 /* write process table */
501 XLALGPSTimeNow(&(proctable->end_time));
502 XLALWriteLIGOLwXMLProcessTable( xmlStream, proctable );
503
504 /* write process_params table */
505 XLALWriteLIGOLwXMLProcessParamsTable( xmlStream, procparams );
506
507 /* write the templates to the file */
508 outputBank = thisTmplt;
509 numTmpltsWritten = 0;
510
511 if ( thisTmplt )
512 {
513 for ( j = 0; j < numPerFile - 1 && thisTmplt->next; ++j )
514 {
515 thisTmplt = thisTmplt->next;
516 }
517 tmpTmplt = thisTmplt->next;
518 thisTmplt->next = NULL;
519 thisTmplt = tmpTmplt;
520
521 XLALWriteLIGOLwXMLSnglInspiralTable( xmlStream, outputBank );
522 }
523
524 while ( outputBank )
525 {
526 ++numTmpltsWritten;
527 tmpTmplt = outputBank;
528 outputBank = outputBank->next;
529 LALFree( tmpTmplt );
530 }
531
532 XLALCloseLIGOLwXMLFile( xmlStream );
533
534 if ( vrbflg ) fprintf( stdout, "%d templates\n", numTmpltsWritten );
535 }
536
538 exit( 0 );
539}
const LALVCSInfoList lalAppsVCSInfoList
NULL-terminated list of VCS and build information for LALApps and its dependencies
const LALVCSInfo lalAppsVCSIdentInfo
Identable VCS and build information for LALApps.
lal_errhandler_t lal_errhandler
int LAL_ERR_EXIT(LALStatus *stat, const char *func, const char *file, const int line, volatile const char *id)
int j
void LALCheckMemoryLeaks(void)
#define LALFree(p)
int LALgetopt_long_only(int argc, char *const *argv, const char *options, const struct LALoption *long_options, int *opt_index)
int LALoptind
char * LALoptarg
#define no_argument
#define required_argument
int XLALCloseLIGOLwXMLFile(LIGOLwXMLStream *xml)
LIGOLwXMLStream * XLALOpenLIGOLwXMLFile(const char *path)
int XLALWriteLIGOLwXMLProcessTable(LIGOLwXMLStream *, const ProcessTable *)
int XLALWriteLIGOLwXMLProcessParamsTable(LIGOLwXMLStream *, const ProcessParamsTable *)
int XLALWriteLIGOLwXMLSnglInspiralTable(LIGOLwXMLStream *xml, const SnglInspiralTable *sngl_inspiral)
SnglInspiralTable * XLALSnglInspiralTableFromLIGOLw(const char *fileName)
#define LIGOMETA_COMMENT_MAX
#define LIGOMETA_TYPE_MAX
#define LIGOMETA_PROGRAM_MAX
#define LIGOMETA_VALUE_MAX
#define LIGOMETA_PARAM_MAX
int XLALPopulateProcessTable(ProcessTable *ptable, const char *program_name, const char *cvs_revision, const char *cvs_source, const char *cvs_date, long process_id)
#define fprintf
LIGOTimeGPS * XLALGPSTimeNow(LIGOTimeGPS *gpstime)
#define XLAL_INIT_DECL(var,...)
char CHAR
int32_t INT4
float REAL4
int XLALOutputVCSInfo(FILE *fp, const LALVCSInfoList vcs_list, const int verbose, const char *prefix)
CHAR comment[LIGOMETA_COMMENT_MAX]
Definition: inspfrinj.c:350
CHAR * userTag
Definition: inspfrinj.c:343
char name[LIGOMETA_SOURCE_MAX]
Definition: inspinj.c:561
static LALStatus status
Definition: inspinj.c:552
int i
Definition: inspinj.c:596
row
c
INT4 numTmplts
Definition: randombank.c:84
int main(int argc, char *argv[])
Definition: splitbank.c:174
#define PROGRAM_NAME
Definition: splitbank.c:157
#define USAGE
Definition: splitbank.c:159
int vrbflg
defined in lal/lib/std/LALError.c
REAL4 minMatch
const char *const vcsDate
const char *const vcsStatus
const char *const vcsId
const char * name
int * flag
CHAR type[LIGOMETA_TYPE_MAX]
CHAR param[LIGOMETA_PARAM_MAX]
CHAR value[LIGOMETA_VALUE_MAX]
struct tagProcessParamsTable * next
CHAR program[LIGOMETA_PROGRAM_MAX]
LIGOTimeGPS start_time
LIGOTimeGPS end_time
struct tagSnglInspiralTable * next