diff --git a/gstlal-calibration/gst/lal/gstlal_transferfunction.c b/gstlal-calibration/gst/lal/gstlal_transferfunction.c index f8d153222494a4df041254a20171dce117caf090..db926eb37462b69a91721a0bbd6d6b8e30919b67 100644 --- a/gstlal-calibration/gst/lal/gstlal_transferfunction.c +++ b/gstlal-calibration/gst/lal/gstlal_transferfunction.c @@ -122,6 +122,7 @@ enum property { ARG_LOW_PASS, ARG_TRANSFER_FUNCTIONS, ARG_FIR_FILTERS, + ARG_INPUT_MAY_BE_ZERO, ARG_FAKE }; @@ -423,6 +424,10 @@ static gboolean find_transfer_functions_ ## DTYPE(GSTLALTransferFunction *elemen stride = element->fft_length - element->fft_overlap; \ num_tfs = element->channels - 1; \ DTYPE *real_fft = (DTYPE *) element->workspace.w ## S_OR_D ## pf.fft; \ + \ + /* Check a few inputs to see if we have valid data yet */ \ + for(i = 0; i < 2 * element->channels; i++) \ + success &= isnormal(src[i]) || (element->input_may_be_zero && src[i] == 0.0); \ \ /* Determine how many fft's we will calculate from combined leftover and new input data */ \ num_ffts = minimum64((element->workspace.w ## S_OR_D ## pf.num_leftover + stride - 1) / stride, element->num_ffts - element->workspace.w ## S_OR_D ## pf.num_ffts_in_avg); \ @@ -1441,6 +1446,10 @@ static void set_property(GObject *object, enum property id, const GValue *value, gstlal_doubles_from_g_value_array(g_value_get_boxed(value), element->fir_filters, &m); break; + case ARG_INPUT_MAY_BE_ZERO: + element->input_may_be_zero = g_value_get_boolean(value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, id, pspec); break; @@ -1535,6 +1544,10 @@ static void get_property(GObject *object, enum property id, GValue *value, GPara } break; + case ARG_INPUT_MAY_BE_ZERO: + g_value_set_boolean(value, element->input_may_be_zero); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, id, pspec); break; @@ -1752,6 +1765,15 @@ static void gstlal_transferfunction_class_init(GSTLALTransferFunctionClass *klas ), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE ); + properties[ARG_INPUT_MAY_BE_ZERO] = g_param_spec_boolean( + "input-may-be-zero", + "Input may be zero", + "Set to True if transfer functions should be computed even if an input\n\t\t\t" + "channel contains zeros. Default is False, to prevent errors when an\n\t\t\t" + "input channel has no data yet at start of stream, etc.", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT + ); g_object_class_install_property( @@ -1824,6 +1846,11 @@ static void gstlal_transferfunction_class_init(GSTLALTransferFunctionClass *klas ARG_FIR_FILTERS, properties[ARG_FIR_FILTERS] ); + g_object_class_install_property( + gobject_class, + ARG_INPUT_MAY_BE_ZERO, + properties[ARG_INPUT_MAY_BE_ZERO] + ); } diff --git a/gstlal-calibration/gst/lal/gstlal_transferfunction.h b/gstlal-calibration/gst/lal/gstlal_transferfunction.h index d99ff3770127b1093749d6321270414bd3bb6210..62f0fb7a56cb60cc2fdde73b8fbf27316c6941b3 100644 --- a/gstlal-calibration/gst/lal/gstlal_transferfunction.h +++ b/gstlal-calibration/gst/lal/gstlal_transferfunction.h @@ -143,6 +143,7 @@ struct _GSTLALTransferFunction { int low_pass; complex double *transfer_functions; double *fir_filters; + gboolean input_may_be_zero; }; diff --git a/gstlal-calibration/tests/lal_transferfunction_test.py b/gstlal-calibration/tests/lal_transferfunction_test.py index d279cbb9010989a2c02032fd7aaccfc3eac2d9fa..5d414e0b13bd0fc43a72b2f43242118da0a19a43 100755 --- a/gstlal-calibration/tests/lal_transferfunction_test.py +++ b/gstlal-calibration/tests/lal_transferfunction_test.py @@ -126,7 +126,8 @@ def lal_transferfunction_02(pipeline, name): witness1 = calibration_parts.mkadder(pipeline, calibration_parts.list_srcs(pipeline, calibration_parts.highpass(pipeline, hoft, rate, fcut = 400), calibration_parts.lowpass(pipeline, noise, rate, fcut = 400))) witness2 = calibration_parts.mkadder(pipeline, calibration_parts.list_srcs(pipeline, calibration_parts.lowpass(pipeline, hoft, rate, fcut = 600), calibration_parts.highpass(pipeline, noise, rate, fcut = 600))) - clean_data = calibration_parts.clean_data(pipeline, hoft, rate, calibration_parts.list_srcs(pipeline, witness1, witness2), rate, 4 * rate, 3 * rate + 1, 128, rate * test_duration, int(0.5 * rate), 5.0, filename = "highpass_lowpass_tfs.txt") + hoft = calibration_parts.highpass(pipeline, hoft, rate) + clean_data = calibration_parts.clean_data(pipeline, hoft, rate, calibration_parts.list_srcs(pipeline, witness1, witness2), rate, 4 * rate, 2 * rate, 128, rate * test_duration, int(0.5 * rate), 10.0, filename = "highpass_lowpass_tfs.txt") pipeparts.mknxydumpsink(pipeline, clean_data, "%s_out.txt" % name) return pipeline