Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALMetaIO 4.0.6.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
search_summary.c
Go to the documentation of this file.
1/*
2 * search_summary.c
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with with program; see the file COPYING. If not, write to the Free
16 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
18 */
19
20#include <stdlib.h>
21#include <stdio.h>
22#include <string.h>
23
24
25#include <metaio.h>
26
27
28#include <lal/Date.h>
29#include <lal/LALMalloc.h>
30#include <lal/LALVCSInfo.h>
31#include <lal/LIGOLwXML.h>
32#include <lal/LIGOLwXMLRead.h>
33#include <lal/LIGOMetadataTables.h>
34#include <lal/LIGOMetadataUtils.h>
35#include <lal/XLALError.h>
36
37
38/**
39 * Create a SearchSummaryTable structure.
40 */
42 const ProcessTable * process
43)
44{
45 SearchSummaryTable *new = XLALMalloc(sizeof(*new));
46
47 if(!new)
49
50 new->next = NULL;
51 if(process)
52 new->process_id = process->process_id;
53 else
54 new->process_id = -1;
55 memset(new->comment, 0, sizeof(new->comment));
56 XLALGPSSet(&new->in_start_time, 0, 0);
57 XLALGPSSet(&new->in_end_time, 0, 0);
58 XLALGPSSet(&new->out_start_time, 0, 0);
59 XLALGPSSet(&new->out_end_time, 0, 0);
60 new->nevents = -1;
61 new->nnodes = -1;
62 memset(new->ifos, 0, sizeof(new->ifos));
63
64 return new;
65}
66
67
68/**
69 * Destroy a SearchSummaryTable structure.
70 */
73)
74{
75 SearchSummaryTable *next = row ? row->next : NULL;
76 XLALFree(row);
77 return next;
78}
79
80
81/**
82 * Destroy a SearchSummaryTable linked list.
83 */
86)
87{
88 while(head)
90}
91
92
94 const void *a,
95 const void *b
96)
97{
98 const SearchSummaryTable *aPtr = *((const SearchSummaryTable * const *) a);
99 const SearchSummaryTable *bPtr = *((const SearchSummaryTable * const *) b);
100
101 INT8 ta = 0;
102 INT8 tb = 0;
103
104 /* determine the out start times */
105 ta = XLALGPSToINT8NS(&(aPtr->out_start_time));
106 tb = XLALGPSToINT8NS(&(bPtr->out_start_time));
107
108 if(ta > tb)
109 return 1;
110 else if(ta < tb)
111 return -1;
112 else {
113 /* determine the out end times */
114 ta = XLALGPSToINT8NS(&(aPtr->out_end_time));
115 tb = XLALGPSToINT8NS(&(bPtr->out_end_time));
116
117 if(ta > tb)
118 return 1;
119 else if(ta < tb)
120 return -1;
121 else
122 return 0;
123 }
124}
125
126
128 SearchSummaryTable **summHead,
129 int (*comparfunc)(const void *, const void *)
130)
131{
132 INT4 i;
133 INT4 numSumms = 0;
134 SearchSummaryTable *thisSearchSumm = NULL;
135 SearchSummaryTable **summHandle = NULL;
136
137 if(!summHead)
139
140 /* count the number of summs in the linked list */
141 for(thisSearchSumm = *summHead; thisSearchSumm; thisSearchSumm = thisSearchSumm->next)
142 ++numSumms;
143 if(!numSumms)
144 return 0;
145
146 /* allocate memory for an array of ptrs to sort and populate array */
147 summHandle = LALCalloc(numSumms, sizeof(SearchSummaryTable *));
148 for(i = 0, thisSearchSumm = *summHead; i < numSumms; ++i, thisSearchSumm = thisSearchSumm->next)
149 summHandle[i] = thisSearchSumm;
150
151 /* qsort the array using the specified function */
152 qsort(summHandle, numSumms, sizeof(summHandle[0]), comparfunc);
153
154 /* re-link the linked list in the right order */
155 thisSearchSumm = *summHead = summHandle[0];
156 for(i = 1; i < numSumms; ++i, thisSearchSumm = thisSearchSumm->next)
157 thisSearchSumm->next = summHandle[i];
158 thisSearchSumm->next = NULL;
159
160 /* free the internal memory */
161 LALFree(summHandle);
162
163 return 0;
164}
165
166
167/**
168 * Scan through a linked list of search_summary row objects and copy rows
169 * whose ifos match the given string into a new linked list, and return the
170 * address of the first entry in the new list. Returns NULL if no matching
171 * rows are found, or if an error occured (out of memory). Use XLAL
172 * error functions to check for an error status code if it matters which
173 * condition occured.
174 */
176 SearchSummaryTable *input,
177 CHAR *ifos
178)
179{
181 SearchSummaryTable **next = &output;
182
183 for(; input; input = input->next) {
184 if(strcmp(input->ifos, ifos))
185 /* IFOs don't match: move to next row */
186 continue;
187
188 /* duplicate this row */
189 *next = LALMalloc(sizeof(**next));
190 if(!*next) {
193 }
194 /* FIXME: this works OK now, but this is not guaranteed to
195 * duplicate the object if changes are made. watch out for
196 * updates to the definition in the future */
197 memcpy(*next, input, sizeof(**next));
198 next = &(*next)->next;
199 /* unlink the copy from the old list */
200 *next = NULL;
201 }
202
203 return output;
204}
205
206
207/**
208 * Read the search_summary table from a LIGO Light Weight XML file into a
209 * linked list of SearchSummaryTable structures.
210 */
212 const char *filename
213)
214{
215 static const char table_name[] = "search_summary";
216 int miostatus;
217 SearchSummaryTable *head = NULL;
218 SearchSummaryTable **next = &head;
219 struct MetaioParseEnvironment env;
220 struct {
221 int process_id;
222 int shared_object;
223 int lalwrapper_cvs_tag;
224 int lal_cvs_tag;
225 int comment;
226 int ifos;
227 int in_start_time;
228 int in_start_time_ns;
229 int in_end_time;
230 int in_end_time_ns;
231 int out_start_time;
232 int out_start_time_ns;
233 int out_end_time;
234 int out_end_time_ns;
235 int nevents;
236 int nnodes;
237 } column_pos;
238
239 /* open the file and find table */
240
241 if(MetaioOpenFile(&env, filename)) {
242 XLALPrintError("%s(): error opening \"%s\": %s\n", __func__, filename, env.mierrmsg.data ? env.mierrmsg.data : "unknown reason");
244 }
245 if(MetaioOpenTableOnly(&env, table_name)) {
246 MetaioAbort(&env);
247 XLALPrintError("%s(): cannot find %s table: %s\n", __func__, table_name, env.mierrmsg.data ? env.mierrmsg.data : "unknown reason");
249 }
250
251 /* find columns */
252
254 column_pos.process_id = XLALLIGOLwFindColumn(&env, "process_id", METAIO_TYPE_INT_8S, 1);
255 column_pos.shared_object = XLALLIGOLwFindColumn(&env, "shared_object", METAIO_TYPE_LSTRING, 1);
256 column_pos.lalwrapper_cvs_tag = XLALLIGOLwFindColumn(&env, "lalwrapper_cvs_tag", METAIO_TYPE_LSTRING, 1);
257 column_pos.lal_cvs_tag = XLALLIGOLwFindColumn(&env, "lal_cvs_tag", METAIO_TYPE_LSTRING, 1);
258 column_pos.comment = XLALLIGOLwFindColumn(&env, "comment", METAIO_TYPE_LSTRING, 1);
259 column_pos.ifos = XLALLIGOLwFindColumn(&env, "ifos", METAIO_TYPE_LSTRING, 1);
260 column_pos.in_start_time = XLALLIGOLwFindColumn(&env, "in_start_time", METAIO_TYPE_INT_4S, 1);
261 column_pos.in_start_time_ns = XLALLIGOLwFindColumn(&env, "in_start_time_ns", METAIO_TYPE_INT_4S, 1);
262 column_pos.in_end_time = XLALLIGOLwFindColumn(&env, "in_end_time", METAIO_TYPE_INT_4S, 1);
263 column_pos.in_end_time_ns = XLALLIGOLwFindColumn(&env, "in_end_time_ns", METAIO_TYPE_INT_4S, 1);
264 column_pos.out_start_time = XLALLIGOLwFindColumn(&env, "out_start_time", METAIO_TYPE_INT_4S, 1);
265 column_pos.out_start_time_ns = XLALLIGOLwFindColumn(&env, "out_start_time_ns", METAIO_TYPE_INT_4S, 1);
266 column_pos.out_end_time = XLALLIGOLwFindColumn(&env, "out_end_time", METAIO_TYPE_INT_4S, 1);
267 column_pos.out_end_time_ns = XLALLIGOLwFindColumn(&env, "out_end_time_ns", METAIO_TYPE_INT_4S, 1);
268 column_pos.nevents = XLALLIGOLwFindColumn(&env, "nevents", METAIO_TYPE_INT_4S, 1);
269 column_pos.nnodes = XLALLIGOLwFindColumn(&env, "nnodes", METAIO_TYPE_INT_4S, 1);
270
271 /* check for failure (== a required column is missing) */
272
273 if(XLALGetBaseErrno()) {
274 MetaioAbort(&env);
275 XLALPrintError("%s(): failure reading %s table\n", __func__, table_name);
277 }
278
279 /* loop over the rows in the file */
280
281 while((miostatus = MetaioGetRow(&env)) > 0) {
282 /* create a new row */
283
285
286 if(!row) {
288 MetaioAbort(&env);
290 }
291
292 /* append to linked list */
293
294 *next = row;
295 next = &(*next)->next;
296
297 /* populate the columns */
298
299 row->process_id = env.ligo_lw.table.elt[column_pos.process_id].data.int_8s;
300 /* FIXME: structure definition does not include elements
301 * for these columns */
302 /*strncpy(row->shared_object, env.ligo_lw.table.elt[column_pos.shared_object].data.lstring.data, sizeof(row->shared_object) - 1); */
303 /*strncpy(row->lalwrapper_cvs_tag, env.ligo_lw.table.elt[column_pos.lalwrapper_cvs_tag].data.lstring.data, sizeof(row->lalwrapper_cvs_tag) - 1); */
304 /*strncpy(row->lal_cvs_tag, env.ligo_lw.table.elt[column_pos.lal_cvs_tag].data.lstring.data, sizeof(row->lal_cvs_tag) - 1); */
305 strncpy(row->comment, env.ligo_lw.table.elt[column_pos.comment].data.lstring.data, sizeof(row->comment) - 1);
306 strncpy(row->ifos, env.ligo_lw.table.elt[column_pos.ifos].data.lstring.data, sizeof(row->ifos) - 1);
307 XLALGPSSet(&row->in_start_time, env.ligo_lw.table.elt[column_pos.in_start_time].data.int_4s, env.ligo_lw.table.elt[column_pos.in_start_time_ns].data.int_4s);
308 XLALGPSSet(&row->in_end_time, env.ligo_lw.table.elt[column_pos.in_end_time].data.int_4s, env.ligo_lw.table.elt[column_pos.in_end_time_ns].data.int_4s);
309 XLALGPSSet(&row->out_start_time, env.ligo_lw.table.elt[column_pos.out_start_time].data.int_4s, env.ligo_lw.table.elt[column_pos.out_start_time_ns].data.int_4s);
310 XLALGPSSet(&row->out_end_time, env.ligo_lw.table.elt[column_pos.out_end_time].data.int_4s, env.ligo_lw.table.elt[column_pos.out_end_time_ns].data.int_4s);
311 row->nevents = env.ligo_lw.table.elt[column_pos.nevents].data.int_4s;
312 row->nnodes = env.ligo_lw.table.elt[column_pos.nnodes].data.int_4s;
313 }
314 if(miostatus < 0) {
316 MetaioAbort(&env);
317 XLALPrintError("%s(): I/O error parsing %s table: %s\n", __func__, table_name, env.mierrmsg.data ? env.mierrmsg.data : "unknown reason");
319 }
320
321 /* close file */
322
323 if(MetaioClose(&env)) {
325 XLALPrintError("%s(): error parsing document after %s table: %s\n", __func__, table_name, env.mierrmsg.data ? env.mierrmsg.data : "unknown reason");
327 }
328
329 /* done */
330
331 return head;
332}
333
334
335/**
336 * Write a search_summary table to an XML file.
337 */
338
339
341 LIGOLwXMLStream *xml,
342 const SearchSummaryTable *search_summary
343)
344{
345 const char *row_head = "\n\t\t\t";
346
347 /* table header */
348
350 XLALFilePuts("\t<Table Name=\"search_summary:table\">\n", xml->fp);
351 XLALFilePuts("\t\t<Column Name=\"process:process_id\" Type=\"int_8s\"/>\n", xml->fp);
352 XLALFilePuts("\t\t<Column Name=\"shared_object\" Type=\"lstring\"/>\n", xml->fp);
353 XLALFilePuts("\t\t<Column Name=\"lalwrapper_cvs_tag\" Type=\"lstring\"/>\n", xml->fp);
354 XLALFilePuts("\t\t<Column Name=\"lal_cvs_tag\" Type=\"lstring\"/>\n", xml->fp);
355 XLALFilePuts("\t\t<Column Name=\"comment\" Type=\"lstring\"/>\n", xml->fp);
356 XLALFilePuts("\t\t<Column Name=\"ifos\" Type=\"lstring\"/>\n", xml->fp);
357 XLALFilePuts("\t\t<Column Name=\"in_start_time\" Type=\"int_4s\"/>\n", xml->fp);
358 XLALFilePuts("\t\t<Column Name=\"in_start_time_ns\" Type=\"int_4s\"/>\n", xml->fp);
359 XLALFilePuts("\t\t<Column Name=\"in_end_time\" Type=\"int_4s\"/>\n", xml->fp);
360 XLALFilePuts("\t\t<Column Name=\"in_end_time_ns\" Type=\"int_4s\"/>\n", xml->fp);
361 XLALFilePuts("\t\t<Column Name=\"out_start_time\" Type=\"int_4s\"/>\n", xml->fp);
362 XLALFilePuts("\t\t<Column Name=\"out_start_time_ns\" Type=\"int_4s\"/>\n", xml->fp);
363 XLALFilePuts("\t\t<Column Name=\"out_end_time\" Type=\"int_4s\"/>\n", xml->fp);
364 XLALFilePuts("\t\t<Column Name=\"out_end_time_ns\" Type=\"int_4s\"/>\n", xml->fp);
365 XLALFilePuts("\t\t<Column Name=\"nevents\" Type=\"int_4s\"/>\n", xml->fp);
366 XLALFilePuts("\t\t<Column Name=\"nnodes\" Type=\"int_4s\"/>\n", xml->fp);
367 XLALFilePuts("\t\t<Stream Name=\"search_summary:table\" Type=\"Local\" Delimiter=\",\">", xml->fp);
368 if(XLALGetBaseErrno())
370
371 /* rows */
372
373 for(; search_summary; search_summary = search_summary->next) {
374 if(XLALFilePrintf(xml->fp, "%s%ld,\"standalone\",\"\",\"%s\",\"%s\",\"%s\",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", row_head, search_summary->process_id, lalVCSInfo.vcsTag, search_summary->comment, search_summary->ifos, search_summary->in_start_time.gpsSeconds, search_summary->in_start_time.gpsNanoSeconds, search_summary->in_end_time.gpsSeconds, search_summary->in_end_time.gpsNanoSeconds, search_summary->out_start_time.gpsSeconds, search_summary->out_start_time.gpsNanoSeconds, search_summary->out_end_time.gpsSeconds, search_summary->out_end_time.gpsNanoSeconds, search_summary->nevents, search_summary->nnodes) < 0)
376 row_head = ",\n\t\t\t";
377 }
378
379 /* table footer */
380
381 if(XLALFilePuts("\n\t\t</Stream>\n\t</Table>\n", xml->fp) < 0)
383
384 /* done */
385
386 return 0;
387}
#define LALCalloc(m, n)
#define LALMalloc(n)
#define LALFree(p)
const LALVCSInfo lalVCSInfo
int XLALLIGOLwFindColumn(struct MetaioParseEnvironment *env, const char *name, unsigned int type, int required)
Convenience wrapper for MetaioFindColumn(), translating to XLAL-style error reporting and printing us...
int XLALFilePuts(const char *s, LALFILE *file)
int XLALFilePrintf(LALFILE *file, const char *fmt,...)
int64_t INT8
char CHAR
int32_t INT4
void * XLALMalloc(size_t n)
void XLALFree(void *p)
static const INT4 a
#define XLAL_ERROR_NULL(...)
int XLALGetBaseErrno(void)
#define XLAL_ERROR(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int XLALClearErrno(void)
XLAL_ENOMEM
XLAL_EFUNC
XLAL_EIO
LIGOTimeGPS * XLALGPSSet(LIGOTimeGPS *epoch, INT4 gpssec, INT8 gpsnan)
INT8 XLALGPSToINT8NS(const LIGOTimeGPS *epoch)
filename
SearchSummaryTable * XLALDestroySearchSummaryTableRow(SearchSummaryTable *row)
Destroy a SearchSummaryTable structure.
int XLALWriteLIGOLwXMLSearchSummaryTable(LIGOLwXMLStream *xml, const SearchSummaryTable *search_summary)
Write a search_summary table to an XML file.
void XLALDestroySearchSummaryTable(SearchSummaryTable *head)
Destroy a SearchSummaryTable linked list.
SearchSummaryTable * XLALIfoScanSearchSummary(SearchSummaryTable *input, CHAR *ifos)
Scan through a linked list of search_summary row objects and copy rows whose ifos match the given str...
int XLALCompareSearchSummaryByOutTime(const void *a, const void *b)
int XLALTimeSortSearchSummary(SearchSummaryTable **summHead, int(*comparfunc)(const void *, const void *))
SearchSummaryTable * XLALSearchSummaryTableFromLIGOLw(const char *filename)
Read the search_summary table from a LIGO Light Weight XML file into a linked list of SearchSummaryTa...
SearchSummaryTable * XLALCreateSearchSummaryTableRow(const ProcessTable *process)
Create a SearchSummaryTable structure.
const char *const vcsTag
This structure contains the file stream and current table type for writing to LIGO lightweight XML fi...
Definition: LIGOLwXML.h:71
LALFILE * fp
Definition: LIGOLwXML.h:72
INT4 gpsNanoSeconds
CHAR comment[LIGOMETA_COMMENT_MAX]
struct tagSearchSummaryTable * next
CHAR ifos[LIGOMETA_IFOS_MAX]
void output(int gps_sec, int output_type)