From 7b6100e6f83d037e2cdb7850a7cc37d702e300ca Mon Sep 17 00:00:00 2001 From: Cody Messick <cody.messick@ligo.org> Date: Mon, 18 Feb 2019 11:53:55 -0800 Subject: [PATCH] All of the changes necessary to build and run itacac instead of itac. Note that itac will no longer work after this commit --- gstlal-inspiral/bin/gstlal_inspiral | 3 +- gstlal-inspiral/gst/lal/Makefile.am | 2 +- gstlal-inspiral/gst/lal/gstlalinspiral.c | 8 +- gstlal-inspiral/lib/gstlal_snglinspiral.c | 285 +++++++----- gstlal-inspiral/lib/gstlal_snglinspiral.h | 5 +- gstlal-inspiral/lib/snglinspiralrowtype.c | 14 +- gstlal-inspiral/lib/snglinspiralrowtype.h | 7 +- gstlal-inspiral/python/inspiral.py | 13 +- gstlal-inspiral/python/lloidhandler.py | 44 +- gstlal-inspiral/python/lloidparts.py | 29 +- gstlal-inspiral/python/snglinspiraltable.c | 485 ++++++++++++++++++-- gstlal-inspiral/python/snglinspiraltable.py | 115 ++++- gstlal/gst/gst/Makefile.am | 6 +- gstlal/lib/gstlal/gstlal_peakfinder.c | 4 + gstlal/lib/gstlal/gstlal_peakfinder_top.h | 1 + 15 files changed, 825 insertions(+), 196 deletions(-) diff --git a/gstlal-inspiral/bin/gstlal_inspiral b/gstlal-inspiral/bin/gstlal_inspiral index eef8a1403f..abd079bace 100755 --- a/gstlal-inspiral/bin/gstlal_inspiral +++ b/gstlal-inspiral/bin/gstlal_inspiral @@ -843,7 +843,8 @@ for output_file_number, (svd_bank_url_dict, output_url, ranking_stat_output_url, if options.verbose: print >>sys.stderr, "attaching appsinks to pipeline ...", appsync = pipeparts.AppSync(appsink_new_buffer = handler.appsink_new_buffer) - appsinks = set(appsync.add_sink(pipeline, src, caps = Gst.Caps.from_string("application/x-lal-snglinspiral"), name = "%s_sink_%d" % (instrument, n)) for instrument, srcs in triggersrc.items() for n, src in enumerate(srcs)) + appsinks = set(appsync.add_sink(pipeline, src, caps = Gst.Caps.from_string("application/x-lal-snglinspiral"), name = "bank_%s_sink" % bank_id) for bank_id, src in triggersrc.items()) + if options.verbose: print >>sys.stderr, "attached %d, done" % len(appsinks) diff --git a/gstlal-inspiral/gst/lal/Makefile.am b/gstlal-inspiral/gst/lal/Makefile.am index 3de553fb2d..78b9d439f6 100644 --- a/gstlal-inspiral/gst/lal/Makefile.am +++ b/gstlal-inspiral/gst/lal/Makefile.am @@ -4,7 +4,7 @@ plugin_LTLIBRARIES = lib@GSTPLUGINPREFIX@gstlalinspiral.la lib@GSTPLUGINPREFIX@gstlalinspiral_la_SOURCES = \ gstlalinspiral.c \ - gstlal_itac.h gstlal_itac.c + gstlal_itacac.h gstlal_itacac.c #gstlal_triggergen.h gstlal_triggergen.c #gstlal_blcbc_triggergen.h gstlal_blcbc_triggergen.c \ #gstlal_coinc.h gstlal_coinc.c \ diff --git a/gstlal-inspiral/gst/lal/gstlalinspiral.c b/gstlal-inspiral/gst/lal/gstlalinspiral.c index b895cdf3d7..c24e6d22d8 100644 --- a/gstlal-inspiral/gst/lal/gstlalinspiral.c +++ b/gstlal-inspiral/gst/lal/gstlalinspiral.c @@ -50,14 +50,15 @@ #include <gstlal/gstlal_tags.h> +#include <gstlal_itacac.h> /* #include <gstlal_coinc.h> #include <gstlal_skymap.h> #include <gstlal_triggergen.h> #include <gstlal_timeslicechisq.h> #include <gstlal_blcbc_triggergen.h> -*/ #include <gstlal_itac.h> +*/ /* @@ -79,8 +80,9 @@ static gboolean plugin_init(GstPlugin *plugin) {"lal_skymap", GSTLAL_SKYMAP_TYPE}, {"lal_triggergen", GSTLAL_TRIGGERGEN_TYPE}, {"lal_timeslicechisq", GSTLAL_TIMESLICECHISQUARE_TYPE}, - {"lal_blcbctriggergen", GSTLAL_BLCBC_TRIGGERGEN_TYPE},*/ - {"lal_itac", GSTLAL_ITAC_TYPE}, + {"lal_blcbctriggergen", GSTLAL_BLCBC_TRIGGERGEN_TYPE}, + {"lal_itac", GSTLAL_ITAC_TYPE}, */ + {"lal_itacac", GSTLAL_ITACAC_TYPE}, {NULL, 0}, }; diff --git a/gstlal-inspiral/lib/gstlal_snglinspiral.c b/gstlal-inspiral/lib/gstlal_snglinspiral.c index 9c1123f125..02a29f4053 100644 --- a/gstlal-inspiral/lib/gstlal_snglinspiral.c +++ b/gstlal-inspiral/lib/gstlal_snglinspiral.c @@ -276,6 +276,10 @@ parsefailed: return -1; } +void gstlal_snglinspiral_array_free(SnglInspiralTable *bankarray) { + free(bankarray); +} + int gstlal_set_channel_in_snglinspiral_array(SnglInspiralTable *bankarray, int length, char *channel) { int i; @@ -328,7 +332,165 @@ int gstlal_set_min_offset_in_snglinspiral_array(SnglInspiralTable *bankarray, in return 0; } -GstBuffer *gstlal_snglinspiral_new_buffer_from_peak(struct gstlal_peak_state *input, SnglInspiralTable *bankarray, GstPad *pad, guint64 offset, guint64 length, GstClockTime time, guint rate, void *chi2, gsl_matrix_complex_float_view *snr_matrix_view, GstClockTimeDiff timediff) +int populate_snglinspiral_buffer(GstBuffer *srcbuf, struct gstlal_peak_state *input, SnglInspiralTable *bankarray, GstPad *pad, guint64 length, GstClockTime time, guint rate, void *chi2, gsl_matrix_complex_float_view *L1_snr_matrix_view, gsl_matrix_complex_float_view *H1_snr_matrix_view, gsl_matrix_complex_float_view *V1_snr_matrix_view, gsl_matrix_complex_float_view *K1_snr_matrix_view) +{ + guint channel; + guint L1_snr_timeseries_length, H1_snr_timeseries_length, V1_snr_timeseries_length, K1_snr_timeseries_length; + gboolean provided_empty_trigger = FALSE; + for(channel = 0; channel < input->channels; channel++) { + struct GSTLALSnglInspiral *event; + SnglInspiralTable *parent; + double complex maxdata_channel = 0; + + switch (input->type) + { + case GSTLAL_PEAK_COMPLEX: + maxdata_channel = (double complex) input->interpvalues.as_float_complex[channel]; + break; + + case GSTLAL_PEAK_DOUBLE_COMPLEX: + maxdata_channel = (double complex) input->interpvalues.as_double_complex[channel]; + break; + + default: + g_assert(input->type == GSTLAL_PEAK_COMPLEX || input->type == GSTLAL_PEAK_DOUBLE_COMPLEX); + } + + if (!maxdata_channel && !input->no_peaks_past_threshold) + continue; + + /* + * allocate new event structure + */ + + + /* + * Populate the SNR snippet if available + * FIXME: only supported for single precision at the moment + */ + gsl_vector_complex_float_view L1_snr_vector_view, H1_snr_vector_view, V1_snr_vector_view, K1_snr_vector_view; + gsl_vector_complex_float_view L1_snr_series_view, H1_snr_series_view, V1_snr_series_view, K1_snr_series_view; + if ((L1_snr_matrix_view || H1_snr_matrix_view || V1_snr_matrix_view || K1_snr_matrix_view) && !input->no_peaks_past_threshold) + { + /* Allocate a set of empty time series. The event takes ownership, so no need to free it*/ + /* Get the columns of SNR we are interested in */ + if(H1_snr_matrix_view != NULL) { + H1_snr_vector_view = gsl_matrix_complex_float_column(&(H1_snr_matrix_view->matrix), channel); + H1_snr_timeseries_length = H1_snr_vector_view.vector.size; + } else + H1_snr_timeseries_length = 0; + if(L1_snr_matrix_view != NULL) { + L1_snr_vector_view = gsl_matrix_complex_float_column(&(L1_snr_matrix_view->matrix), channel); + L1_snr_timeseries_length = L1_snr_vector_view.vector.size; + } else + L1_snr_timeseries_length = 0; + if(V1_snr_matrix_view != NULL) { + V1_snr_vector_view = gsl_matrix_complex_float_column(&(V1_snr_matrix_view->matrix), channel); + V1_snr_timeseries_length = V1_snr_vector_view.vector.size; + } else + V1_snr_timeseries_length = 0; + if(K1_snr_matrix_view != NULL) { + K1_snr_vector_view = gsl_matrix_complex_float_column(&(K1_snr_matrix_view->matrix), channel); + K1_snr_timeseries_length = K1_snr_vector_view.vector.size; + } else + K1_snr_timeseries_length = 0; + + event = gstlal_snglinspiral_new(H1_snr_timeseries_length, L1_snr_timeseries_length, V1_snr_timeseries_length, K1_snr_timeseries_length); + + if(H1_snr_matrix_view != NULL) { + /* Make a GSL view of the time series array data */ + H1_snr_series_view = gsl_vector_complex_float_view_array((float *) event->snr, event->H1_length); + /* Use BLAS to do the copy */ + gsl_blas_ccopy (&(H1_snr_vector_view.vector), &(H1_snr_series_view.vector)); + } + if(L1_snr_matrix_view != NULL) { + /* Make a GSL view of the time series array data */ + L1_snr_series_view = gsl_vector_complex_float_view_array((float *) &(event->snr[event->H1_length]), event->L1_length); + /* Use BLAS to do the copy */ + gsl_blas_ccopy (&(L1_snr_vector_view.vector), &(L1_snr_series_view.vector)); + } + if(V1_snr_matrix_view != NULL) { + /* Make a GSL view of the time series array data */ + V1_snr_series_view = gsl_vector_complex_float_view_array((float *) &(event->snr[event->H1_length + event->L1_length]), event->V1_length); + /* Use BLAS to do the copy */ + gsl_blas_ccopy (&(V1_snr_vector_view.vector), &(V1_snr_series_view.vector)); + } + if(K1_snr_matrix_view != NULL) { + /* Make a GSL view of the time series array data */ + K1_snr_series_view = gsl_vector_complex_float_view_array((float *) &(event->snr[event->H1_length + event->L1_length + event->V1_length]), event->K1_length); + /* Use BLAS to do the copy */ + gsl_blas_ccopy (&(K1_snr_vector_view.vector), &(K1_snr_series_view.vector)); + } + } else { + if(!provided_empty_trigger) { + //fprintf(stderr, "allocating snglinspiral with 0 length for %s event\n", bankarray[channel].ifo); + provided_empty_trigger = TRUE; + event = gstlal_snglinspiral_new(0,0,0,0); + } else + return 0; + } + + if (!event) { + /* FIXME handle error */ + } + /* + * populate + */ + + parent = (SnglInspiralTable *) event; + *parent = bankarray[channel]; + parent->snr = cabs(maxdata_channel); + parent->coa_phase = carg(maxdata_channel); + + + XLALINT8NSToGPS(&event->epoch, time); + XLALGPSAddGPS(&event->epoch, &parent->end); + parent->end = event->epoch; + XLALGPSAdd(&parent->end, (double) input->interpsamples[channel] / rate); + XLALGPSAdd(&event->epoch, ((gint) input->samples[channel] - (gint) input->pad) / (double) rate); + event->deltaT = 1. / rate; + + parent->end_time_gmst = XLALGreenwichMeanSiderealTime(&parent->end); + parent->eff_distance = gstlal_effective_distance(parent->snr, parent->sigmasq); + /* populate chi squared if we have it */ + parent->chisq = 0.0; + parent->chisq_dof = 1; + switch (input->type) + { + case GSTLAL_PEAK_COMPLEX: + if (chi2) parent->chisq = (double) *(((float *) chi2 ) + channel); + break; + + case GSTLAL_PEAK_DOUBLE_COMPLEX: + if (chi2) parent->chisq = (double) *(((double *) chi2 ) + channel); + break; + + default: + g_assert(input->type == GSTLAL_PEAK_COMPLEX || input->type == GSTLAL_PEAK_DOUBLE_COMPLEX); + } + + + /* + * add to buffer + */ + + gst_buffer_append_memory( + srcbuf, + gst_memory_new_wrapped( + GST_MEMORY_FLAG_READONLY | GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS, + event, + sizeof(*event) + (event->H1_length + event->L1_length + event->V1_length + event->K1_length) * sizeof(event->snr[0]), + 0, + sizeof(*event) + (event->H1_length + event->L1_length + event->V1_length + event->K1_length) * sizeof(event->snr[0]), + event, + (GDestroyNotify) gstlal_snglinspiral_free + ) + ); + } + return 0; +} + +GstBuffer *gstlal_snglinspiral_new_buffer_from_peak(struct gstlal_peak_state *input, SnglInspiralTable *bankarray, GstPad *pad, guint64 offset, guint64 length, GstClockTime time, guint rate, void *chi2, gsl_matrix_complex_float_view *L1_snr_matrix_view, gsl_matrix_complex_float_view *H1_snr_matrix_view, gsl_matrix_complex_float_view *V1_snr_matrix_view, gsl_matrix_complex_float_view *K1_snr_matrix_view, GstClockTimeDiff timediff) { GstBuffer *srcbuf = gst_buffer_new(); @@ -349,109 +511,26 @@ GstBuffer *gstlal_snglinspiral_new_buffer_from_peak(struct gstlal_peak_state *in GST_BUFFER_PTS(srcbuf) = time + timediff; GST_BUFFER_DURATION(srcbuf) = (GstClockTime) gst_util_uint64_scale_int_round(GST_SECOND, length, rate); - if (input->num_events) { - guint channel; - for(channel = 0; channel < input->channels; channel++) { - struct GSTLALSnglInspiral *event; - SnglInspiralTable *parent; - double complex maxdata_channel = 0; - - switch (input->type) - { - case GSTLAL_PEAK_COMPLEX: - maxdata_channel = (double complex) input->interpvalues.as_float_complex[channel]; - break; - - case GSTLAL_PEAK_DOUBLE_COMPLEX: - maxdata_channel = (double complex) input->interpvalues.as_double_complex[channel]; - break; - - default: - g_assert(input->type == GSTLAL_PEAK_COMPLEX || input->type == GSTLAL_PEAK_DOUBLE_COMPLEX); - } - - if (!maxdata_channel) - continue; - - /* - * allocate new event structure - */ - - - /* - * Populate the SNR snippet if available - * FIXME: only supported for single precision at the moment - */ - if (snr_matrix_view) - { - /* Get the column of SNR we are interested in */ - gsl_vector_complex_float_view snr_vector_view = gsl_matrix_complex_float_column(&(snr_matrix_view->matrix), channel); - /* Allocate an empty time series to hold it. The event takes ownership, so no need to free it*/ - event = gstlal_snglinspiral_new(snr_vector_view.vector.size); - /* Make a GSL view of the time series array data */ - gsl_vector_complex_float_view snr_series_view = gsl_vector_complex_float_view_array((float *) event->snr, event->length); - /* Use BLAS to do the copy */ - gsl_blas_ccopy (&(snr_vector_view.vector), &(snr_series_view.vector)); - } else - event = gstlal_snglinspiral_new(0); - - parent = (SnglInspiralTable *) event; - if (!event) { - /* FIXME handle error */ - } - - /* - * populate - */ - - *parent = bankarray[channel]; - parent->snr = cabs(maxdata_channel); - parent->coa_phase = carg(maxdata_channel); - - XLALINT8NSToGPS(&event->epoch, time); - XLALGPSAddGPS(&event->epoch, &parent->end); - parent->end = event->epoch; - XLALGPSAdd(&parent->end, (double) input->interpsamples[channel] / rate); - XLALGPSAdd(&event->epoch, ((gint) input->samples[channel] - (gint) input->pad) / (double) rate); - event->deltaT = 1. / rate; - - parent->end_time_gmst = XLALGreenwichMeanSiderealTime(&parent->end); - parent->eff_distance = gstlal_effective_distance(parent->snr, parent->sigmasq); - /* populate chi squared if we have it */ - parent->chisq = 0.0; - parent->chisq_dof = 1; - switch (input->type) - { - case GSTLAL_PEAK_COMPLEX: - if (chi2) parent->chisq = (double) *(((float *) chi2 ) + channel); - break; - - case GSTLAL_PEAK_DOUBLE_COMPLEX: - if (chi2) parent->chisq = (double) *(((double *) chi2 ) + channel); - break; - - default: - g_assert(input->type == GSTLAL_PEAK_COMPLEX || input->type == GSTLAL_PEAK_DOUBLE_COMPLEX); - } + if (input->num_events || input->no_peaks_past_threshold) { + populate_snglinspiral_buffer(srcbuf, input, bankarray, pad, length, time, rate, chi2, L1_snr_matrix_view, H1_snr_matrix_view, V1_snr_matrix_view, K1_snr_matrix_view); + } + return srcbuf; +} - /* - * add to buffer - */ - - gst_buffer_append_memory( - srcbuf, - gst_memory_new_wrapped( - GST_MEMORY_FLAG_READONLY | GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS, - event, - sizeof(*event) + sizeof(event->snr[0]) * event->length, - 0, - sizeof(*event) + sizeof(event->snr[0]) * event->length, - event, - (GDestroyNotify) gstlal_snglinspiral_free - ) - ); - } +int gstlal_snglinspiral_append_peak_to_buffer(GstBuffer *srcbuf, struct gstlal_peak_state *input, SnglInspiralTable *bankarray, GstPad *pad, guint64 offset, guint64 length, GstClockTime time, guint rate, void *chi2, gsl_matrix_complex_float_view *L1_snr_matrix_view, gsl_matrix_complex_float_view *H1_snr_matrix_view, gsl_matrix_complex_float_view *V1_snr_matrix_view, gsl_matrix_complex_float_view *K1_snr_matrix_view) +{ + // + // Add peak information to a buffer, GST_BUFFER_OFFSET cannot be + // changed but GST_BUFFER_OFFSET_END can + // + + /* Update the offset end and duration */ + if(offset+length > GST_BUFFER_OFFSET_END(srcbuf)) { + GST_BUFFER_OFFSET_END(srcbuf) = offset + length; + GST_BUFFER_DURATION(srcbuf) = (GstClockTime) gst_util_uint64_scale_int_round(GST_SECOND, GST_BUFFER_OFFSET_END(srcbuf) - GST_BUFFER_OFFSET(srcbuf), rate); } - return srcbuf; + populate_snglinspiral_buffer(srcbuf, input, bankarray, pad, length, time, rate, chi2, L1_snr_matrix_view, H1_snr_matrix_view, V1_snr_matrix_view, K1_snr_matrix_view); + + return 0; } diff --git a/gstlal-inspiral/lib/gstlal_snglinspiral.h b/gstlal-inspiral/lib/gstlal_snglinspiral.h index 7ae2671515..07095ce626 100644 --- a/gstlal-inspiral/lib/gstlal_snglinspiral.h +++ b/gstlal-inspiral/lib/gstlal_snglinspiral.h @@ -47,10 +47,13 @@ int gstlal_set_instrument_in_snglinspiral_array(SnglInspiralTable *bankarray, in int gstlal_set_sigmasq_in_snglinspiral_array(SnglInspiralTable *bankarray, int length, double *sigmasq); int gstlal_set_min_offset_in_snglinspiral_array(SnglInspiralTable *bankarray, int length, GstClockTimeDiff *difftime); +void gstlal_snglinspiral_array_free(SnglInspiralTable *bankarray); + /* * FIXME: only support single precision SNR snippets at the moment */ -GstBuffer *gstlal_snglinspiral_new_buffer_from_peak(struct gstlal_peak_state *input, SnglInspiralTable *bankarray, GstPad *pad, guint64 offset, guint64 length, GstClockTime time, guint rate, void *chi2, gsl_matrix_complex_float_view *snr_matrix_view, GstClockTimeDiff); +GstBuffer *gstlal_snglinspiral_new_buffer_from_peak(struct gstlal_peak_state *input, SnglInspiralTable *bankarray, GstPad *pad, guint64 offset, guint64 length, GstClockTime time, guint rate, void *chi2, gsl_matrix_complex_float_view *L1_snr_matrix_view, gsl_matrix_complex_float_view *H1_snr_matrix_view, gsl_matrix_complex_float_view *V1_snr_matrix_view, gsl_matrix_complex_float_view *K1_snr_matrix_view, GstClockTimeDiff); +int gstlal_snglinspiral_append_peak_to_buffer(GstBuffer *srcbuf, struct gstlal_peak_state *input, SnglInspiralTable *bankarray, GstPad *pad, guint64 offset, guint64 L1, GstClockTime time, guint rate, void *chi2, gsl_matrix_complex_float_view *L1_snr_matrix_view, gsl_matrix_complex_float_view *H1_snr_matrix_view, gsl_matrix_complex_float_view *V1_snr_matrix_view, gsl_matrix_complex_float_view *K1_snr_matrix_view); G_END_DECLS diff --git a/gstlal-inspiral/lib/snglinspiralrowtype.c b/gstlal-inspiral/lib/snglinspiralrowtype.c index 366a38c3ae..7f7bb1fe37 100644 --- a/gstlal-inspiral/lib/snglinspiralrowtype.c +++ b/gstlal-inspiral/lib/snglinspiralrowtype.c @@ -37,6 +37,7 @@ #include <snglinspiralrowtype.h> + /** * Allocate a new struct GSTLALSnglInspiral * @@ -44,11 +45,16 @@ */ -struct GSTLALSnglInspiral *gstlal_snglinspiral_new(size_t length) +struct GSTLALSnglInspiral *gstlal_snglinspiral_new(size_t H1_length, size_t L1_length, size_t V1_length, size_t K1_length) { - struct GSTLALSnglInspiral *row = calloc(1, sizeof(*row) + length * sizeof(row->snr[0])); - if (row) - row->length = length; + struct GSTLALSnglInspiral *row = calloc(1, sizeof(*row) + (H1_length + L1_length + V1_length + K1_length) * sizeof(row->snr[0])); + if (row) { + row->L1_length = L1_length; + row->H1_length = H1_length; + row->V1_length = V1_length; + row->K1_length = K1_length; + } + return row; } diff --git a/gstlal-inspiral/lib/snglinspiralrowtype.h b/gstlal-inspiral/lib/snglinspiralrowtype.h index cfcb362f51..54a251db9d 100644 --- a/gstlal-inspiral/lib/snglinspiralrowtype.h +++ b/gstlal-inspiral/lib/snglinspiralrowtype.h @@ -56,12 +56,15 @@ struct GSTLALSnglInspiral { SnglInspiralTable parent; LIGOTimeGPS epoch; double deltaT; - size_t length; + size_t L1_length; + size_t H1_length; + size_t V1_length; + size_t K1_length; float complex snr[]; }; -struct GSTLALSnglInspiral *gstlal_snglinspiral_new(size_t length); +struct GSTLALSnglInspiral *gstlal_snglinspiral_new(size_t L1_length, size_t H1_length, size_t V1_length, size_t K1_length); void gstlal_snglinspiral_free(struct GSTLALSnglInspiral *row); diff --git a/gstlal-inspiral/python/inspiral.py b/gstlal-inspiral/python/inspiral.py index 8c942bf7d8..90863117dd 100644 --- a/gstlal-inspiral/python/inspiral.py +++ b/gstlal-inspiral/python/inspiral.py @@ -555,6 +555,7 @@ class GracedBWrapper(object): if self.verbose: print >>sys.stderr, "sending %s to gracedb ..." % filename + print >>sys.stderr, "sending %s to gracedb ..." % filename message = StringIO.StringIO() xmldoc = last_coincs[coinc_event.coinc_event_id] # give the alert all the standard inspiral @@ -568,13 +569,19 @@ class GracedBWrapper(object): # already has it pass # add SNR time series if available + # FIXME Probably only want one time series for each ifo for event in last_coincs.sngl_inspirals(coinc_event.coinc_event_id): - snr_time_series = event.snr_time_series - if snr_time_series is not None: - xmldoc.childNodes[-1].appendChild(lalseries.build_COMPLEX8TimeSeries(snr_time_series)).appendChild(ligolw_param.Param.from_pyvalue(u"event_id", event.event_id)) + for ifo in ("H1", "L1", "V1", "K1"): + snr_time_series = getattr(event, "%s_snr_time_series" % ifo) + if snr_time_series is not None: + snr_time_series_element = lalseries.build_COMPLEX8TimeSeries(snr_time_series) + snr_time_series_element.appendChild(ligolw_param.Param.from_pyvalue(u"event_id", event.event_id)) + snr_time_series_element.appendChild(ligolw_param.Param.from_pyvalue(u"ifo", ifo)) + xmldoc.childNodes[-1].appendChild(snr_time_series_element) # translate IDs from integers to ilwd:char for # backwards compatibility ilwdify.do_it_to(xmldoc) + # serialize to XML ligolw_utils.write_fileobj(xmldoc, message, gz = False) xmldoc.unlink() diff --git a/gstlal-inspiral/python/lloidhandler.py b/gstlal-inspiral/python/lloidhandler.py index d12ca2f0da..873ba1b74c 100644 --- a/gstlal-inspiral/python/lloidhandler.py +++ b/gstlal-inspiral/python/lloidhandler.py @@ -950,7 +950,7 @@ class Handler(simplehandler.Handler): memory.unmap(mapinfo) # FIXME: ugly way to get the instrument - instrument = elem.get_name().split("_", 1)[0] + instruments = set([event.ifo for event in events]) # extract segment. move the segment's upper # boundary to include all triggers. ARGH the 1 ns @@ -958,10 +958,7 @@ class Handler(simplehandler.Handler): # "in" the segment (segments are open from above) # FIXME: is there another way? buf_timestamp = LIGOTimeGPS(0, buf.pts) - if events: - buf_seg = segments.segment(buf_timestamp, max(buf_timestamp + LIGOTimeGPS(0, buf.duration), max(event.end for event in events) + 0.000000001)) - else: - buf_seg = segments.segment(buf_timestamp, buf_timestamp + LIGOTimeGPS(0, buf.duration)) + buf_seg = dict((instrument, segments.segment(buf_timestamp, max(buf_timestamp + LIGOTimeGPS(0, buf.duration), max(event.end for event in events if event.ifo == instrument) + 0.000000001))) for instrument in instruments) buf_is_gap = bool(buf.mini_object.flags & Gst.BufferFlags.GAP) # sanity check that gap buffers are empty assert not (buf_is_gap and events) @@ -1062,12 +1059,35 @@ class Handler(simplehandler.Handler): # is aware of this buffer. if not buf_is_gap: snr_min = self.rankingstat.snr_min - self.rankingstat.denominator.triggerrates[instrument].add_ratebin(map(float, buf_seg), len([event for event in events if event.snr >= snr_min])) + for instrument in instruments: + # FIXME At the moment, empty triggers are added to + # inform the "how many instruments were on test", the + # correct thing to do is probably to add metadata to + # the buffer containing information about which + # instruments were on + self.rankingstat.denominator.triggerrates[instrument].add_ratebin(map(float, buf_seg[instrument]), len([event for event in events if event.snr >= snr_min and event.ifo == instrument])) + + # FIXME At the moment, empty triggers are added to + # inform the "how many instruments were on test", the + # correct thing to do is probably to add metadata to + # the buffer containing information about which + # instruments were on + real_events = [] + for event in events: + if event.snr >= snr_min: + real_events.append(event) + + events = real_events # run stream thinca. for absent_instrument in self.absent_instruments: self.stream_thinca.push(absent_instrument, (), buf_timestamp) - if self.stream_thinca.push(instrument, events, buf_timestamp): + for instrument in self.rankingstat.instruments: + if instrument in instruments or instrument in self.absent_instruments: + continue + self.stream_thinca.push(instrument, (), buf_timestamp) + + if any([self.stream_thinca.push(instrument, [event for event in events if event.ifo == instrument], buf_timestamp) for instrument in instruments]): flushed_sngls = self.stream_thinca.pull(self.rankingstat, fapfar = self.fapfar, zerolag_rankingstatpdf = self.zerolag_rankingstatpdf, coinc_sieve = self.rankingstat.fast_path_cut_from_triggers, cluster = self.cluster) self.coincs_document.commit() @@ -1080,7 +1100,10 @@ class Handler(simplehandler.Handler): # that are too old to be used to form # candidates. for event in flushed_sngls: - del event.snr_time_series + del event.H1_snr_time_series + del event.L1_snr_time_series + del event.V1_snr_time_series + del event.K1_snr_time_series def _record_horizon_distance(self, instrument, timestamp, horizon_distance): @@ -1274,7 +1297,10 @@ class Handler(simplehandler.Handler): # for the triggers that are too old to be used to form # candidates. for event in flushed_sngls: - del event.snr_time_series + del event.H1_snr_time_series + del event.L1_snr_time_series + del event.V1_snr_time_series + del event.K1_snr_time_series def __do_gracedb_alerts(self, last_coincs): diff --git a/gstlal-inspiral/python/lloidparts.py b/gstlal-inspiral/python/lloidparts.py index c0dc7e8c88..de887c9e37 100644 --- a/gstlal-inspiral/python/lloidparts.py +++ b/gstlal-inspiral/python/lloidparts.py @@ -81,6 +81,7 @@ from glue import iterutils from gstlal import datasource from gstlal import multirate_datasource from gstlal import pipeparts +from gstlal import pipeio # @@ -656,8 +657,8 @@ def mkLLOIDmulti(pipeline, detectors, banks, psd, psd_fft_length = 32, ht_gate_t # construct trigger generators # - triggersrcs = dict((instrument, set()) for instrument in hoftdicts) - for instrument, bank in [(instrument, bank) for instrument, banklist in banks.items() for bank in banklist]: + itacac_dict = {} + for i, (instrument, bank) in enumerate([(instrument, bank) for instrument, banklist in banks.items() for bank in banklist]): suffix = "%s%s" % (instrument, (bank.logname and "_%s" % bank.logname or "")) if control_branch is not None: if instrument != "H2": @@ -695,10 +696,19 @@ def mkLLOIDmulti(pipeline, detectors, banks, psd, psd_fft_length = 32, ht_gate_t # but 4 is about the lowest we can do stably for # coincidence online... nsamps_window = max(max(bank.get_rates()) / 4, 256) # FIXME stupid hack - head = pipeparts.mkitac(pipeline, snr, nsamps_window, bank.template_bank_filename, autocorrelation_matrix = bank.autocorrelation_bank, mask_matrix = bank.autocorrelation_mask, snr_thresh = 4.0, sigmasq = bank.sigmasq) - if verbose: - head = pipeparts.mkprogressreport(pipeline, head, "progress_xml_%s" % suffix) - triggersrcs[instrument].add(head) + if bank.bank_id not in itacac_dict: + itacac_dict[bank.bank_id] = pipeparts.mkgeneric(pipeline, None, "lal_itacac") + + head = itacac_dict[bank.bank_id] + pad = head.get_request_pad("sink%d" % len(head.sinkpads)) + if instrument == 'H1' or instrument == 'L1': + for prop, val in [("n", nsamps_window), ("snr-thresh", 4.0), ("bank_filename", bank.template_bank_filename), ("sigmasq", bank.sigmasq), ("autocorrelation_matrix", pipeio.repack_complex_array_to_real(bank.autocorrelation_bank)), ("autocorrelation_mask", bank.autocorrelation_mask)]: + pad.set_property(prop, val) + snr.srcpads[0].link(pad) + else: + for prop, val in [("n", nsamps_window), ("snr-thresh", 4.0), ("bank_filename", bank.template_bank_filename), ("sigmasq", bank.sigmasq), ("autocorrelation_matrix", pipeio.repack_complex_array_to_real(bank.autocorrelation_bank)), ("autocorrelation_mask", bank.autocorrelation_mask)]: + pad.set_property(prop, val) + snr.srcpads[0].link(pad) else: raise NotImplementedError("Currently only 'autochisq' is supported") # FIXME: find a way to use less memory without this hack @@ -710,5 +720,8 @@ def mkLLOIDmulti(pipeline, detectors, banks, psd, psd_fft_length = 32, ht_gate_t # done # - assert any(triggersrcs.values()) - return triggersrcs + assert any(itacac_dict.values()) + if verbose: + for bank_id, head in itacac_dict.items(): + itacac_dict[bank_id] = pipeparts.mkprogressreport(pipeline, head, "progress_xml_bank_%s" % bank_id) + return itacac_dict diff --git a/gstlal-inspiral/python/snglinspiraltable.c b/gstlal-inspiral/python/snglinspiraltable.c index 13e8f2f7c6..ee714e8272 100644 --- a/gstlal-inspiral/python/snglinspiraltable.c +++ b/gstlal-inspiral/python/snglinspiraltable.c @@ -38,6 +38,9 @@ #include <snglinspiralrowtype.h> +#include <gst/gst.h> +#include <gsl/gsl_blas.h> +#include <gsl/gsl_matrix_float.h> static PyObject *LIGOTimeGPSType = NULL; @@ -55,7 +58,10 @@ static PyObject *LIGOTimeGPSType = NULL; typedef struct { PyObject_HEAD SnglInspiralTable row; - COMPLEX8TimeSeries *snr; + COMPLEX8TimeSeries *H1_snr; + COMPLEX8TimeSeries *L1_snr; + COMPLEX8TimeSeries *V1_snr; + COMPLEX8TimeSeries *K1_snr; } gstlal_GSTLALSnglInspiral; @@ -225,36 +231,272 @@ static int template_id_set(PyObject *obj, PyObject *val, void *null) return 0; } +static PyObject *H1_snr_component_get(PyObject *obj, void *data) +{ + COMPLEX8TimeSeries *H1_snr = ((gstlal_GSTLALSnglInspiral *) obj)->H1_snr; + const char *name = data; + + if(!H1_snr) { + PyErr_SetString(PyExc_ValueError, "no snr time series available"); + return NULL; + } + if(!strcmp(name, "_H1_snr_name")) { + return PyString_FromString(H1_snr->name); + } else if(!strcmp(name, "_H1_snr_epoch_gpsSeconds")) { + return PyInt_FromLong(H1_snr->epoch.gpsSeconds); + } else if(!strcmp(name, "_H1_snr_epoch_gpsNanoSeconds")) { + return PyInt_FromLong(H1_snr->epoch.gpsNanoSeconds); + } else if(!strcmp(name, "_H1_snr_f0")) { + return PyFloat_FromDouble(H1_snr->f0); + } else if(!strcmp(name, "_H1_snr_deltaT")) { + return PyFloat_FromDouble(H1_snr->deltaT); + } else if(!strcmp(name, "_H1_snr_sampleUnits")) { + char *s = XLALUnitToString(&H1_snr->sampleUnits); + PyObject *result = PyString_FromString(s); + XLALFree(s); + return result; + } else if(!strcmp(name, "_H1_snr_data_length")) { + return PyInt_FromLong(H1_snr->data->length); + } else if(!strcmp(name, "_H1_snr_data")) { + npy_intp dims[] = {H1_snr->data->length}; + PyObject *array = PyArray_SimpleNewFromData(1, dims, NPY_CFLOAT, H1_snr->data->data); + if(!array) + return NULL; + Py_INCREF(obj); + PyArray_SetBaseObject((PyArrayObject *) array, obj); + return array; + } + PyErr_BadArgument(); + return NULL; +} + + +static PyObject *L1_snr_component_get(PyObject *obj, void *data) +{ + COMPLEX8TimeSeries *L1_snr = ((gstlal_GSTLALSnglInspiral *) obj)->L1_snr; + const char *name = data; + if(!L1_snr) { + PyErr_SetString(PyExc_ValueError, "no snr time series available"); + return NULL; + } + if(!strcmp(name, "_L1_snr_name")) { + return PyString_FromString(L1_snr->name); + } else if(!strcmp(name, "_L1_snr_epoch_gpsSeconds")) { + return PyInt_FromLong(L1_snr->epoch.gpsSeconds); + } else if(!strcmp(name, "_L1_snr_epoch_gpsNanoSeconds")) { + return PyInt_FromLong(L1_snr->epoch.gpsNanoSeconds); + } else if(!strcmp(name, "_L1_snr_f0")) { + return PyFloat_FromDouble(L1_snr->f0); + } else if(!strcmp(name, "_L1_snr_deltaT")) { + return PyFloat_FromDouble(L1_snr->deltaT); + } else if(!strcmp(name, "_L1_snr_sampleUnits")) { + char *s = XLALUnitToString(&L1_snr->sampleUnits); + PyObject *result = PyString_FromString(s); + XLALFree(s); + return result; + } else if(!strcmp(name, "_L1_snr_data_length")) { + return PyInt_FromLong(L1_snr->data->length); + } else if(!strcmp(name, "_L1_snr_data")) { + npy_intp dims[] = {L1_snr->data->length}; + PyObject *array = PyArray_SimpleNewFromData(1, dims, NPY_CFLOAT, L1_snr->data->data); + if(!array) + return NULL; + Py_INCREF(obj); + PyArray_SetBaseObject((PyArrayObject *) array, obj); + return array; + } + PyErr_BadArgument(); + return NULL; +} + +static PyObject *V1_snr_component_get(PyObject *obj, void *data) +{ + COMPLEX8TimeSeries *V1_snr = ((gstlal_GSTLALSnglInspiral *) obj)->V1_snr; + const char *name = data; + + if(!V1_snr) { + PyErr_SetString(PyExc_ValueError, "no snr time series available"); + return NULL; + } + if(!strcmp(name, "_V1_snr_name")) { + return PyString_FromString(V1_snr->name); + } else if(!strcmp(name, "_V1_snr_epoch_gpsSeconds")) { + return PyInt_FromLong(V1_snr->epoch.gpsSeconds); + } else if(!strcmp(name, "_V1_snr_epoch_gpsNanoSeconds")) { + return PyInt_FromLong(V1_snr->epoch.gpsNanoSeconds); + } else if(!strcmp(name, "_V1_snr_f0")) { + return PyFloat_FromDouble(V1_snr->f0); + } else if(!strcmp(name, "_V1_snr_deltaT")) { + return PyFloat_FromDouble(V1_snr->deltaT); + } else if(!strcmp(name, "_V1_snr_sampleUnits")) { + char *s = XLALUnitToString(&V1_snr->sampleUnits); + PyObject *result = PyString_FromString(s); + XLALFree(s); + return result; + } else if(!strcmp(name, "_V1_snr_data_length")) { + return PyInt_FromLong(V1_snr->data->length); + } else if(!strcmp(name, "_V1_snr_data")) { + npy_intp dims[] = {V1_snr->data->length}; + PyObject *array = PyArray_SimpleNewFromData(1, dims, NPY_CFLOAT, V1_snr->data->data); + if(!array) + return NULL; + Py_INCREF(obj); + PyArray_SetBaseObject((PyArrayObject *) array, obj); + return array; + } + PyErr_BadArgument(); + return NULL; +} + + +static PyObject *K1_snr_component_get(PyObject *obj, void *data) +{ + COMPLEX8TimeSeries *K1_snr = ((gstlal_GSTLALSnglInspiral *) obj)->K1_snr; + const char *name = data; + + if(!K1_snr) { + PyErr_SetString(PyExc_ValueError, "no snr time series available"); + return NULL; + } + if(!strcmp(name, "_K1_snr_name")) { + return PyString_FromString(K1_snr->name); + } else if(!strcmp(name, "_K1_snr_epoch_gpsSeconds")) { + return PyInt_FromLong(K1_snr->epoch.gpsSeconds); + } else if(!strcmp(name, "_K1_snr_epoch_gpsNanoSeconds")) { + return PyInt_FromLong(K1_snr->epoch.gpsNanoSeconds); + } else if(!strcmp(name, "_K1_snr_f0")) { + return PyFloat_FromDouble(K1_snr->f0); + } else if(!strcmp(name, "_K1_snr_deltaT")) { + return PyFloat_FromDouble(K1_snr->deltaT); + } else if(!strcmp(name, "_K1_snr_sampleUnits")) { + char *s = XLALUnitToString(&K1_snr->sampleUnits); + PyObject *result = PyString_FromString(s); + XLALFree(s); + return result; + } else if(!strcmp(name, "_K1_snr_data_length")) { + return PyInt_FromLong(K1_snr->data->length); + } else if(!strcmp(name, "_K1_snr_data")) { + npy_intp dims[] = {K1_snr->data->length}; + PyObject *array = PyArray_SimpleNewFromData(1, dims, NPY_CFLOAT, K1_snr->data->data); + if(!array) + return NULL; + Py_INCREF(obj); + PyArray_SetBaseObject((PyArrayObject *) array, obj); + return array; + } + PyErr_BadArgument(); + return NULL; +} + +/* static PyObject *snr_component_get(PyObject *obj, void *data) { - COMPLEX8TimeSeries *snr = ((gstlal_GSTLALSnglInspiral *) obj)->snr; + COMPLEX8TimeSeries *H1_snr = ((gstlal_GSTLALSnglInspiral *) obj)->H1_snr; + COMPLEX8TimeSeries *L1_snr = ((gstlal_GSTLALSnglInspiral *) obj)->L1_snr; + COMPLEX8TimeSeries *V1_snr = ((gstlal_GSTLALSnglInspiral *) obj)->V1_snr; + COMPLEX8TimeSeries *K1_snr = ((gstlal_GSTLALSnglInspiral *) obj)->K1_snr; const char *name = data; - if(!snr) { + if(!H1_snr && !L1_snr && !V1_snr && !K1_snr) { PyErr_SetString(PyExc_ValueError, "no snr time series available"); return NULL; } - if(!strcmp(name, "_snr_name")) { - return PyString_FromString(snr->name); - } else if(!strcmp(name, "_snr_epoch_gpsSeconds")) { - return PyInt_FromLong(snr->epoch.gpsSeconds); - } else if(!strcmp(name, "_snr_epoch_gpsNanoSeconds")) { - return PyInt_FromLong(snr->epoch.gpsNanoSeconds); - } else if(!strcmp(name, "_snr_f0")) { - return PyFloat_FromDouble(snr->f0); - } else if(!strcmp(name, "_snr_deltaT")) { - return PyFloat_FromDouble(snr->deltaT); - } else if(!strcmp(name, "_snr_sampleUnits")) { - char *s = XLALUnitToString(&snr->sampleUnits); + if(!strcmp(name, "_H1_snr_name")) { + return PyString_FromString(H1_snr->name); + } else if(!strcmp(name, "_L1_snr_name")) { + return PyString_FromString(L1_snr->name); + } else if(!strcmp(name, "_V1_snr_name")) { + return PyString_FromString(V1_snr->name); + } else if(!strcmp(name, "_K1_snr_name")) { + return PyString_FromString(K1_snr->name); + } else if(!strcmp(name, "_H1_snr_epoch_gpsSeconds")) { + return PyInt_FromLong(H1_snr->epoch.gpsSeconds); + } else if(!strcmp(name, "_L1_snr_epoch_gpsSeconds")) { + return PyInt_FromLong(L1_snr->epoch.gpsSeconds); + } else if(!strcmp(name, "_V1_snr_epoch_gpsSeconds")) { + return PyInt_FromLong(V1_snr->epoch.gpsSeconds); + } else if(!strcmp(name, "_K1_snr_epoch_gpsSeconds")) { + return PyInt_FromLong(K1_snr->epoch.gpsSeconds); + } else if(!strcmp(name, "_H1_snr_epoch_gpsNanoSeconds")) { + return PyInt_FromLong(H1_snr->epoch.gpsNanoSeconds); + } else if(!strcmp(name, "_L1_snr_epoch_gpsNanoSeconds")) { + return PyInt_FromLong(L1_snr->epoch.gpsNanoSeconds); + } else if(!strcmp(name, "_V1_snr_epoch_gpsNanoSeconds")) { + return PyInt_FromLong(V1_snr->epoch.gpsNanoSeconds); + } else if(!strcmp(name, "_K1_snr_epoch_gpsNanoSeconds")) { + return PyInt_FromLong(K1_snr->epoch.gpsNanoSeconds); + } else if(!strcmp(name, "_H1_snr_f0")) { + return PyFloat_FromDouble(H1_snr->f0); + } else if(!strcmp(name, "_L1_snr_f0")) { + return PyFloat_FromDouble(L1_snr->f0); + } else if(!strcmp(name, "_V1_snr_f0")) { + return PyFloat_FromDouble(V1_snr->f0); + } else if(!strcmp(name, "_K1_snr_f0")) { + return PyFloat_FromDouble(K1_snr->f0); + } else if(!strcmp(name, "_H1_snr_deltaT")) { + return PyFloat_FromDouble(H1_snr->deltaT); + } else if(!strcmp(name, "_L1_snr_deltaT")) { + return PyFloat_FromDouble(L1_snr->deltaT); + } else if(!strcmp(name, "_V1_snr_deltaT")) { + return PyFloat_FromDouble(V1_snr->deltaT); + } else if(!strcmp(name, "_K1_snr_deltaT")) { + return PyFloat_FromDouble(K1_snr->deltaT); + } else if(!strcmp(name, "_H1_snr_sampleUnits")) { + char *s = XLALUnitToString(&H1_snr->sampleUnits); + PyObject *result = PyString_FromString(s); + XLALFree(s); + return result; + } else if(!strcmp(name, "_L1_snr_sampleUnits")) { + char *s = XLALUnitToString(&L1_snr->sampleUnits); + PyObject *result = PyString_FromString(s); + XLALFree(s); + return result; + } else if(!strcmp(name, "_V1_snr_sampleUnits")) { + char *s = XLALUnitToString(&V1_snr->sampleUnits); + PyObject *result = PyString_FromString(s); + XLALFree(s); + return result; + } else if(!strcmp(name, "_K1_snr_sampleUnits")) { + char *s = XLALUnitToString(&K1_snr->sampleUnits); PyObject *result = PyString_FromString(s); XLALFree(s); return result; - } else if(!strcmp(name, "_snr_data_length")) { - return PyInt_FromLong(snr->data->length); - } else if(!strcmp(name, "_snr_data")) { - npy_intp dims[] = {snr->data->length}; - PyObject *array = PyArray_SimpleNewFromData(1, dims, NPY_CFLOAT, snr->data->data); + } else if(!strcmp(name, "_H1_snr_data_length")) { + return PyInt_FromLong(H1_snr->data->length); + } else if(!strcmp(name, "_L1_snr_data_length")) { + return PyInt_FromLong(L1_snr->data->length); + } else if(!strcmp(name, "_V1_snr_data_length")) { + return PyInt_FromLong(V1_snr->data->length); + } else if(!strcmp(name, "_K1_snr_data_length")) { + return PyInt_FromLong(K1_snr->data->length); + } else if(!strcmp(name, "_H1_snr_data")) { + npy_intp dims[] = {H1_snr->data->length}; + PyObject *array = PyArray_SimpleNewFromData(1, dims, NPY_CFLOAT, H1_snr->data->data); + if(!array) + return NULL; + Py_INCREF(obj); + PyArray_SetBaseObject((PyArrayObject *) array, obj); + return array; + } else if(!strcmp(name, "_L1_snr_data")) { + npy_intp dims[] = {L1_snr->data->length}; + PyObject *array = PyArray_SimpleNewFromData(1, dims, NPY_CFLOAT, L1_snr->data->data); + if(!array) + return NULL; + Py_INCREF(obj); + PyArray_SetBaseObject((PyArrayObject *) array, obj); + return array; + } else if(!strcmp(name, "_V1_snr_data")) { + npy_intp dims[] = {V1_snr->data->length}; + PyObject *array = PyArray_SimpleNewFromData(1, dims, NPY_CFLOAT, V1_snr->data->data); + if(!array) + return NULL; + Py_INCREF(obj); + PyArray_SetBaseObject((PyArrayObject *) array, obj); + return array; + } else if(!strcmp(name, "_K1_snr_data")) { + npy_intp dims[] = {K1_snr->data->length}; + PyObject *array = PyArray_SimpleNewFromData(1, dims, NPY_CFLOAT, K1_snr->data->data); if(!array) return NULL; Py_INCREF(obj); @@ -264,6 +506,7 @@ static PyObject *snr_component_get(PyObject *obj, void *data) PyErr_BadArgument(); return NULL; } +*/ static struct PyGetSetDef getset[] = { @@ -272,14 +515,38 @@ static struct PyGetSetDef getset[] = { {"channel", pylal_inline_string_get, pylal_inline_string_set, "channel", &(struct pylal_inline_string_description) {offsetof(gstlal_GSTLALSnglInspiral, row.channel), LIGOMETA_CHANNEL_MAX}}, {"end", end_get, end_set, "end", NULL}, {"template_id", template_id_get, template_id_set, "template_id", NULL}, - {"_snr_name", snr_component_get, NULL, ".snr.name", "_snr_name"}, - {"_snr_epoch_gpsSeconds", snr_component_get, NULL, ".snr.epoch.gpsSeconds", "_snr_epoch_gpsSeconds"}, - {"_snr_epoch_gpsNanoSeconds", snr_component_get, NULL, ".snr.epoch.gpsNanoSeconds", "_snr_epoch_gpsNanoSeconds"}, - {"_snr_f0", snr_component_get, NULL, ".snr.f0", "_snr_f0"}, - {"_snr_deltaT", snr_component_get, NULL, ".snr.deltaT", "_snr_deltaT"}, - {"_snr_sampleUnits", snr_component_get, NULL, ".snr.sampleUnits", "_snr_sampleUnits"}, - {"_snr_data_length", snr_component_get, NULL, ".snr.data.length", "_snr_data_length"}, - {"_snr_data", snr_component_get, NULL, ".snr.data", "_snr_data"}, + {"_H1_snr_name", H1_snr_component_get, NULL, ".H1_snr.name", "_H1_snr_name"}, + {"_L1_snr_name", L1_snr_component_get, NULL, ".L1_snr.name", "_L1_snr_name"}, + {"_V1_snr_name", V1_snr_component_get, NULL, ".V1_snr.name", "_V1_snr_name"}, + {"_K1_snr_name", K1_snr_component_get, NULL, ".K1_snr.name", "_K1_snr_name"}, + {"_H1_snr_epoch_gpsSeconds", H1_snr_component_get, NULL, ".H1_snr.epoch.gpsSeconds", "_H1_snr_epoch_gpsSeconds"}, + {"_L1_snr_epoch_gpsSeconds", L1_snr_component_get, NULL, ".L1_snr.epoch.gpsSeconds", "_L1_snr_epoch_gpsSeconds"}, + {"_V1_snr_epoch_gpsSeconds", V1_snr_component_get, NULL, ".V1_snr.epoch.gpsSeconds", "_V1_snr_epoch_gpsSeconds"}, + {"_K1_snr_epoch_gpsSeconds", K1_snr_component_get, NULL, ".K1_snr.epoch.gpsSeconds", "_K1_snr_epoch_gpsSeconds"}, + {"_H1_snr_epoch_gpsNanoSeconds", H1_snr_component_get, NULL, ".H1_snr.epoch.gpsNanoSeconds", "_H1_snr_epoch_gpsNanoSeconds"}, + {"_L1_snr_epoch_gpsNanoSeconds", L1_snr_component_get, NULL, ".L1_snr.epoch.gpsNanoSeconds", "_L1_snr_epoch_gpsNanoSeconds"}, + {"_V1_snr_epoch_gpsNanoSeconds", V1_snr_component_get, NULL, ".V1_snr.epoch.gpsNanoSeconds", "_V1_snr_epoch_gpsNanoSeconds"}, + {"_K1_snr_epoch_gpsNanoSeconds", K1_snr_component_get, NULL, ".K1_snr.epoch.gpsNanoSeconds", "_K1_snr_epoch_gpsNanoSeconds"}, + {"_H1_snr_f0", H1_snr_component_get, NULL, ".H1_snr.f0", "_H1_snr_f0"}, + {"_L1_snr_f0", L1_snr_component_get, NULL, ".L1_snr.f0", "_L1_snr_f0"}, + {"_V1_snr_f0", V1_snr_component_get, NULL, ".V1_snr.f0", "_V1_snr_f0"}, + {"_K1_snr_f0", K1_snr_component_get, NULL, ".K1_snr.f0", "_K1_snr_f0"}, + {"_H1_snr_deltaT", H1_snr_component_get, NULL, ".H1_snr.deltaT", "_H1_snr_deltaT"}, + {"_L1_snr_deltaT", L1_snr_component_get, NULL, ".L1_snr.deltaT", "_L1_snr_deltaT"}, + {"_V1_snr_deltaT", V1_snr_component_get, NULL, ".V1_snr.deltaT", "_V1_snr_deltaT"}, + {"_K1_snr_deltaT", K1_snr_component_get, NULL, ".K1_snr.deltaT", "_K1_snr_deltaT"}, + {"_H1_snr_sampleUnits", H1_snr_component_get, NULL, ".H1_snr.sampleUnits", "_H1_snr_sampleUnits"}, + {"_L1_snr_sampleUnits", L1_snr_component_get, NULL, ".L1_snr.sampleUnits", "_L1_snr_sampleUnits"}, + {"_V1_snr_sampleUnits", V1_snr_component_get, NULL, ".V1_snr.sampleUnits", "_V1_snr_sampleUnits"}, + {"_K1_snr_sampleUnits", K1_snr_component_get, NULL, ".K1_snr.sampleUnits", "_K1_snr_sampleUnits"}, + {"_H1_snr_data_length", H1_snr_component_get, NULL, ".H1_snr.data.length", "_H1_snr_data_length"}, + {"_L1_snr_data_length", L1_snr_component_get, NULL, ".L1_snr.data.length", "_L1_snr_data_length"}, + {"_V1_snr_data_length", V1_snr_component_get, NULL, ".V1_snr.data.length", "_V1_snr_data_length"}, + {"_K1_snr_data_length", K1_snr_component_get, NULL, ".K1_snr.data.length", "_K1_snr_data_length"}, + {"_H1_snr_data", H1_snr_component_get, NULL, ".H1_snr.data", "_H1_snr_data"}, + {"_L1_snr_data", L1_snr_component_get, NULL, ".L1_snr.data", "_L1_snr_data"}, + {"_V1_snr_data", V1_snr_component_get, NULL, ".V1_snr.data", "_V1_snr_data"}, + {"_K1_snr_data", K1_snr_component_get, NULL, ".K1_snr.data", "_K1_snr_data"}, {NULL,} }; @@ -303,7 +570,14 @@ static PyObject *__new__(PyTypeObject *type, PyObject *args, PyObject *kwds) static void __del__(PyObject *self) { - XLALDestroyCOMPLEX8TimeSeries(((gstlal_GSTLALSnglInspiral *) self)->snr); + if(((gstlal_GSTLALSnglInspiral *) self)->H1_snr != NULL) + XLALDestroyCOMPLEX8TimeSeries(((gstlal_GSTLALSnglInspiral *) self)->H1_snr); + if(((gstlal_GSTLALSnglInspiral *) self)->L1_snr != NULL) + XLALDestroyCOMPLEX8TimeSeries(((gstlal_GSTLALSnglInspiral *) self)->L1_snr); + if(((gstlal_GSTLALSnglInspiral *) self)->V1_snr != NULL) + XLALDestroyCOMPLEX8TimeSeries(((gstlal_GSTLALSnglInspiral *) self)->V1_snr); + if(((gstlal_GSTLALSnglInspiral *) self)->K1_snr != NULL) + XLALDestroyCOMPLEX8TimeSeries(((gstlal_GSTLALSnglInspiral *) self)->K1_snr); Py_TYPE(self)->tp_free(self); } @@ -338,18 +612,72 @@ static PyObject *from_buffer(PyObject *cls, PyObject *args) return NULL; } ((gstlal_GSTLALSnglInspiral*)item)->row = gstlal_snglinspiral->parent; + + if(gstlal_snglinspiral->H1_length) + { + const size_t H1_nbytes = sizeof(gstlal_snglinspiral->snr[0]) * gstlal_snglinspiral->H1_length; + if (data + H1_nbytes > end) + { + Py_DECREF(item); + Py_DECREF(result); + PyErr_SetString(PyExc_ValueError, "buffer overrun while copying H1 SNR time series"); + return NULL; + } + COMPLEX8TimeSeries *series = XLALCreateCOMPLEX8TimeSeries("H1_snr", &gstlal_snglinspiral->epoch, 0., gstlal_snglinspiral->deltaT, &lalDimensionlessUnit, gstlal_snglinspiral->H1_length); + if (!series) + { + Py_DECREF(item); + Py_DECREF(result); + PyErr_SetString(PyExc_MemoryError, "out of memory"); + return NULL; + } + + memcpy(series->data->data, gstlal_snglinspiral->snr, H1_nbytes); + data += H1_nbytes; + ((gstlal_GSTLALSnglInspiral*)item)->H1_snr = series; + } else + ((gstlal_GSTLALSnglInspiral*)item)->H1_snr = NULL; + + /* duplicate the SNR time series */ - if(gstlal_snglinspiral->length) + if(gstlal_snglinspiral->L1_length) + { + const size_t L1_nbytes = sizeof(gstlal_snglinspiral->snr[0]) * gstlal_snglinspiral->L1_length; + if (data + L1_nbytes > end) + { + Py_DECREF(item); + Py_DECREF(result); + PyErr_SetString(PyExc_ValueError, "buffer overrun while copying L1 SNR time series"); + return NULL; + } + COMPLEX8TimeSeries *series = XLALCreateCOMPLEX8TimeSeries("L1_snr", &gstlal_snglinspiral->epoch, 0., gstlal_snglinspiral->deltaT, &lalDimensionlessUnit, gstlal_snglinspiral->L1_length); + if (!series) + { + Py_DECREF(item); + Py_DECREF(result); + PyErr_SetString(PyExc_MemoryError, "out of memory"); + return NULL; + } + + memcpy(series->data->data, &(gstlal_snglinspiral->snr[gstlal_snglinspiral->H1_length]), L1_nbytes); + data += L1_nbytes; + ((gstlal_GSTLALSnglInspiral*)item)->L1_snr = series; + } else + ((gstlal_GSTLALSnglInspiral*)item)->L1_snr = NULL; + + + if(gstlal_snglinspiral->V1_length) { - const size_t nbytes = sizeof(gstlal_snglinspiral->snr[0]) * gstlal_snglinspiral->length; - if (data + nbytes > end) + const size_t V1_nbytes = sizeof(gstlal_snglinspiral->snr[0]) * gstlal_snglinspiral->V1_length; + if (data + V1_nbytes > end) { Py_DECREF(item); Py_DECREF(result); PyErr_SetString(PyExc_ValueError, "buffer overrun while copying SNR time series"); return NULL; } - COMPLEX8TimeSeries *series = XLALCreateCOMPLEX8TimeSeries("snr", &gstlal_snglinspiral->epoch, 0., gstlal_snglinspiral->deltaT, &lalDimensionlessUnit, gstlal_snglinspiral->length); + + COMPLEX8TimeSeries *series = XLALCreateCOMPLEX8TimeSeries("V1_snr", &gstlal_snglinspiral->epoch, 0., gstlal_snglinspiral->deltaT, &lalDimensionlessUnit, gstlal_snglinspiral->V1_length); if (!series) { Py_DECREF(item); @@ -357,10 +685,38 @@ static PyObject *from_buffer(PyObject *cls, PyObject *args) PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } - memcpy(series->data->data, gstlal_snglinspiral->snr, nbytes); - data += nbytes; - ((gstlal_GSTLALSnglInspiral*)item)->snr = series; - } + + memcpy(series->data->data, &(gstlal_snglinspiral->snr[gstlal_snglinspiral->H1_length + gstlal_snglinspiral->L1_length]), V1_nbytes); + data += V1_nbytes; + ((gstlal_GSTLALSnglInspiral*)item)->V1_snr = series; + } else + ((gstlal_GSTLALSnglInspiral*)item)->V1_snr = NULL; + + if(gstlal_snglinspiral->K1_length) + { + const size_t K1_nbytes = sizeof(gstlal_snglinspiral->snr[0]) * gstlal_snglinspiral->K1_length; + if (data + K1_nbytes > end) + { + Py_DECREF(item); + Py_DECREF(result); + PyErr_SetString(PyExc_ValueError, "buffer overrun while copying SNR time series"); + return NULL; + } + COMPLEX8TimeSeries *series = XLALCreateCOMPLEX8TimeSeries("K1_snr", &gstlal_snglinspiral->epoch, 0., gstlal_snglinspiral->deltaT, &lalDimensionlessUnit, gstlal_snglinspiral->K1_length); + if (!series) + { + Py_DECREF(item); + Py_DECREF(result); + PyErr_SetString(PyExc_MemoryError, "out of memory"); + return NULL; + } + + memcpy(series->data->data, &(gstlal_snglinspiral->snr[gstlal_snglinspiral->H1_length + gstlal_snglinspiral->L1_length + gstlal_snglinspiral->V1_length]), K1_nbytes); + data += K1_nbytes; + ((gstlal_GSTLALSnglInspiral*)item)->K1_snr = series; + } else + ((gstlal_GSTLALSnglInspiral*)item)->K1_snr = NULL; + PyList_Append(result, item); Py_DECREF(item); @@ -379,10 +735,34 @@ static PyObject *from_buffer(PyObject *cls, PyObject *args) } -static PyObject *_snr_time_series_deleter(PyObject *self, PyObject *args) +static PyObject *_L1_snr_time_series_deleter(PyObject *self, PyObject *args) { - XLALDestroyCOMPLEX8TimeSeries(((gstlal_GSTLALSnglInspiral *) self)->snr); - ((gstlal_GSTLALSnglInspiral *) self)->snr = NULL; + XLALDestroyCOMPLEX8TimeSeries(((gstlal_GSTLALSnglInspiral *) self)->L1_snr); + ((gstlal_GSTLALSnglInspiral *) self)->L1_snr = NULL; + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *_H1_snr_time_series_deleter(PyObject *self, PyObject *args) +{ + XLALDestroyCOMPLEX8TimeSeries(((gstlal_GSTLALSnglInspiral *) self)->H1_snr); + ((gstlal_GSTLALSnglInspiral *) self)->H1_snr = NULL; + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *_V1_snr_time_series_deleter(PyObject *self, PyObject *args) +{ + XLALDestroyCOMPLEX8TimeSeries(((gstlal_GSTLALSnglInspiral *) self)->V1_snr); + ((gstlal_GSTLALSnglInspiral *) self)->V1_snr = NULL; + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *_K1_snr_time_series_deleter(PyObject *self, PyObject *args) +{ + XLALDestroyCOMPLEX8TimeSeries(((gstlal_GSTLALSnglInspiral *) self)->K1_snr); + ((gstlal_GSTLALSnglInspiral *) self)->K1_snr = NULL; Py_INCREF(Py_None); return Py_None; } @@ -393,10 +773,22 @@ static PyObject *random_obj(PyObject *cls, PyObject *args) gstlal_GSTLALSnglInspiral *new = (gstlal_GSTLALSnglInspiral *) __new__((PyTypeObject *) cls, NULL, NULL); unsigned i; - new->snr = XLALCreateCOMPLEX8TimeSeries("", &(LIGOTimeGPS) {0, 0}, 0., 1. / 16384, &lalDimensionlessUnit, 16384); + new->L1_snr = XLALCreateCOMPLEX8TimeSeries("", &(LIGOTimeGPS) {0, 0}, 0., 1. / 16384, &lalDimensionlessUnit, 16384); + new->H1_snr = XLALCreateCOMPLEX8TimeSeries("", &(LIGOTimeGPS) {0, 0}, 0., 1. / 16384, &lalDimensionlessUnit, 16384); + new->V1_snr = XLALCreateCOMPLEX8TimeSeries("", &(LIGOTimeGPS) {0, 0}, 0., 1. / 16384, &lalDimensionlessUnit, 16384); + new->K1_snr = XLALCreateCOMPLEX8TimeSeries("", &(LIGOTimeGPS) {0, 0}, 0., 1. / 16384, &lalDimensionlessUnit, 16384); + + for(i = 0; i < new->L1_snr->data->length; i++) + new->L1_snr->data->data[i] = 0.; + + for(i = 0; i < new->H1_snr->data->length; i++) + new->H1_snr->data->data[i] = 0.; + + for(i = 0; i < new->V1_snr->data->length; i++) + new->V1_snr->data->data[i] = 0.; - for(i = 0; i < new->snr->data->length; i++) - new->snr->data->data[i] = 0.; + for(i = 0; i < new->K1_snr->data->length; i++) + new->K1_snr->data->data[i] = 0.; return (PyObject *) new; } @@ -404,8 +796,11 @@ static PyObject *random_obj(PyObject *cls, PyObject *args) static struct PyMethodDef methods[] = { {"from_buffer", from_buffer, METH_VARARGS | METH_CLASS, "Construct a tuple of GSTLALSnglInspiral objects from a buffer object. The buffer is interpreted as a C array of GSTLALSnglInspiral structures. All data is copied, the buffer can be deallocated afterwards."}, - {"_snr_time_series_deleter", _snr_time_series_deleter, METH_NOARGS, "Release the SNR time series attached to the GSTLALSnglInspiral object."}, - {"random", random_obj, METH_NOARGS | METH_CLASS, "Make a GSTLALSnglInspiral with an SNR time series attached to assist with writing test code."}, + {"_L1_snr_time_series_deleter", _L1_snr_time_series_deleter, METH_NOARGS, "Release the L1 SNR time series attached to the GSTLALSnglInspiral object."}, + {"_H1_snr_time_series_deleter", _H1_snr_time_series_deleter, METH_NOARGS, "Release the H1 SNR time series attached to the GSTLALSnglInspiral object."}, + {"_V1_snr_time_series_deleter", _V1_snr_time_series_deleter, METH_NOARGS, "Release the V1 SNR time series attached to the GSTLALSnglInspiral object."}, + {"_K1_snr_time_series_deleter", _K1_snr_time_series_deleter, METH_NOARGS, "Release the K1 SNR time series attached to the GSTLALSnglInspiral object."}, + {"random", random_obj, METH_NOARGS | METH_CLASS, "Make a GSTLALSnglInspiral with an SNR time series attached to it for L1, H1, V1, and K1 to assist with writing test code."}, {NULL,} }; diff --git a/gstlal-inspiral/python/snglinspiraltable.py b/gstlal-inspiral/python/snglinspiraltable.py index 74926fec2f..9477038ee1 100644 --- a/gstlal-inspiral/python/snglinspiraltable.py +++ b/gstlal-inspiral/python/snglinspiraltable.py @@ -30,20 +30,20 @@ class GSTLALSnglInspiral(_snglinspiraltable.GSTLALSnglInspiral): spin2 = lsctables.SnglInspiral.spin2 @property - def snr_time_series(self): + def H1_snr_time_series(self): try: - name = self._snr_name + name = self._H1_snr_name except ValueError: # C interface raises ValueError if the internal snr # pointer is NULL return None series = lal.CreateCOMPLEX8TimeSeries( name, - lal.LIGOTimeGPS(self._snr_epoch_gpsSeconds, self._snr_epoch_gpsNanoSeconds), - self._snr_f0, - self._snr_deltaT, - lal.Unit(self._snr_sampleUnits), - self._snr_data_length + lal.LIGOTimeGPS(self._H1_snr_epoch_gpsSeconds, self._H1_snr_epoch_gpsNanoSeconds), + self._H1_snr_f0, + self._H1_snr_deltaT, + lal.Unit(self._H1_snr_sampleUnits), + self._H1_snr_data_length ) # we want to be able to keep the table row object in memory # for an extended period of time so we need to be able to @@ -53,9 +53,102 @@ class GSTLALSnglInspiral(_snglinspiraltable.GSTLALSnglInspiral): # allowed references to the original memory to leak out # into Python land we could never know if it's safe to free # it - series.data.data[:] = self._snr_data + series.data.data[:] = self._H1_snr_data return series - @snr_time_series.deleter - def snr_time_series(self): - self._snr_time_series_deleter() + @property + def L1_snr_time_series(self): + try: + name = self._L1_snr_name + except ValueError: + # C interface raises ValueError if the internal snr + # pointer is NULL + return None + series = lal.CreateCOMPLEX8TimeSeries( + name, + lal.LIGOTimeGPS(self._L1_snr_epoch_gpsSeconds, self._L1_snr_epoch_gpsNanoSeconds), + self._L1_snr_f0, + self._L1_snr_deltaT, + lal.Unit(self._L1_snr_sampleUnits), + self._L1_snr_data_length + ) + # we want to be able to keep the table row object in memory + # for an extended period of time so we need to be able to + # release the memory used by the SNR time series when we no + # longer need it, and so we copy the data here instead of + # holding a reference to the original memory. if we + # allowed references to the original memory to leak out + # into Python land we could never know if it's safe to free + # it + series.data.data[:] = self._L1_snr_data + return series + + @property + def V1_snr_time_series(self): + try: + name = self._V1_snr_name + except ValueError: + # C interface raises ValueError if the internal snr + # pointer is NULL + return None + series = lal.CreateCOMPLEX8TimeSeries( + name, + lal.LIGOTimeGPS(self._V1_snr_epoch_gpsSeconds, self._V1_snr_epoch_gpsNanoSeconds), + self._V1_snr_f0, + self._V1_snr_deltaT, + lal.Unit(self._V1_snr_sampleUnits), + self._V1_snr_data_length + ) + # we want to be able to keep the table row object in memory + # for an extended period of time so we need to be able to + # release the memory used by the SNR time series when we no + # longer need it, and so we copy the data here instead of + # holding a reference to the original memory. if we + # allowed references to the original memory to leak out + # into Python land we could never know if it's safe to free + # it + series.data.data[:] = self._V1_snr_data + return series + + @property + def K1_snr_time_series(self): + try: + name = self._K1_snr_name + except ValueError: + # C interface raises ValueError if the internal snr + # pointer is NULL + return None + series = lal.CreateCOMPLEX8TimeSeries( + name, + lal.LIGOTimeGPS(self._K1_snr_epoch_gpsSeconds, self._K1_snr_epoch_gpsNanoSeconds), + self._K1_snr_f0, + self._K1_snr_deltaT, + lal.Unit(self._K1_snr_sampleUnits), + self._K1_snr_data_length + ) + # we want to be able to keep the table row object in memory + # for an extended period of time so we need to be able to + # release the memory used by the SNR time series when we no + # longer need it, and so we copy the data here instead of + # holding a reference to the original memory. if we + # allowed references to the original memory to leak out + # into Python land we could never know if it's safe to free + # it + series.data.data[:] = self._K1_snr_data + return series + + @H1_snr_time_series.deleter + def H1_snr_time_series(self): + self._H1_snr_time_series_deleter() + + @L1_snr_time_series.deleter + def L1_snr_time_series(self): + self._L1_snr_time_series_deleter() + + @V1_snr_time_series.deleter + def V1_snr_time_series(self): + self._V1_snr_time_series_deleter() + + @K1_snr_time_series.deleter + def K1_snr_time_series(self): + self._K1_snr_time_series_deleter() diff --git a/gstlal/gst/gst/Makefile.am b/gstlal/gst/gst/Makefile.am index c3b3344a54..ce4494d28c 100644 --- a/gstlal/gst/gst/Makefile.am +++ b/gstlal/gst/gst/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_builddir)/lib -plugin_LTLIBRARIES = libgstlal_adder.la libgstpythonplugin.la +plugin_LTLIBRARIES = libgstlal_adder.la libgstlal_adder_la_SOURCES = \ gstadder.h gstadder.c \ @@ -8,7 +8,3 @@ libgstlal_adder_la_SOURCES = \ libgstlal_adder_la_CFLAGS = $(AM_CFLAGS) $(ORC_CFLAGS) $(gstreamer_CFLAGS) $(gstreamer_audio_CFLAGS) -DGST_PACKAGE_NAME=\"gstlal\" -DGST_PACKAGE_ORIGIN=\"\" libgstlal_adder_la_LIBADD = $(top_builddir)/lib/gstlal/libgstlal.la $(top_builddir)/lib/gstlal/libgstlaltypes.la libgstlal_adder_la_LDFLAGS = $(AM_LDFLAGS) $(ORC_LIBS) $(gstreamer_LIBS) $(gstreamer_audio_LIBS) $(GSTLAL_PLUGIN_LDFLAGS) - -libgstpythonplugin_la_SOURCES = gstpythonplugin.c -libgstpythonplugin_la_CFLAGS = $(AM_CPPFLAGS) $(PYTHON_CPPFLAGS) $(PYGOBJECT_CFLAGS) $(gstreamer_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) -DPYTHON_VERSION="\"$(PYTHON_VERSION)\"" -DPY_LIB_LOC="\"$(PYTHON_LIB_LOC)\"" -DPY_ABI_FLAGS="\"$(PYTHON_ABI_FLAGS)\"" -DPY_LIB_SUFFIX="\"$(PYTHON_LIB_SUFFIX)\"" -DGST_API_VERSION="\"$(GSTREAMER_RELEASE)\"" -DPLUGINDIR="\"$(plugindir)\"" -libgstpythonplugin_la_LDFLAGS = $(AM_LDFLAGS) $(PYTHON_LIBS) $(gstreamer_LIBS) $(GSTLAL_PLUGIN_LDFLAGS) $(PYGOBJECT_LIBS) diff --git a/gstlal/lib/gstlal/gstlal_peakfinder.c b/gstlal/lib/gstlal/gstlal_peakfinder.c index 2411ee20c7..c7db8aeb88 100644 --- a/gstlal/lib/gstlal/gstlal_peakfinder.c +++ b/gstlal/lib/gstlal/gstlal_peakfinder.c @@ -25,6 +25,7 @@ struct gstlal_peak_state *gstlal_peak_state_new(guint channels, gstlal_peak_type new->thresh = 0; new->type = type; new->is_gap = FALSE; + new->no_peaks_past_threshold = TRUE; switch (new->type) { @@ -84,6 +85,9 @@ int gstlal_peak_state_clear(struct gstlal_peak_state *val) memset(val->interpvalues.as_float, 0.0, val->channels * val->unit); val->num_events = 0; val->is_gap = FALSE; + // dont reset the value of no peaks past threshold, user is responsibile for that + // FIXME This will be removed eventually, see itacac for more info + //val->no_peaks_past_threshold = TRUE; return 0; } diff --git a/gstlal/lib/gstlal/gstlal_peakfinder_top.h b/gstlal/lib/gstlal/gstlal_peakfinder_top.h index 1882d5f5a6..f6693648ee 100644 --- a/gstlal/lib/gstlal/gstlal_peakfinder_top.h +++ b/gstlal/lib/gstlal/gstlal_peakfinder_top.h @@ -48,6 +48,7 @@ struct gstlal_peak_state { LanczosTriggerInterpolant *interp; gboolean is_gap; + gboolean no_peaks_past_threshold; }; -- GitLab