From bd7d3689e4b65fee19786ecd65f91c50ac628944 Mon Sep 17 00:00:00 2001
From: Aaron Viets <aaron.viets@ligo.org>
Date: Thu, 23 Aug 2018 08:23:58 -0700
Subject: [PATCH] lal_dqtukey:  Bug fix for invert_control property.

---
 gstlal-calibration/gst/lal/gstlal_dqtukey.c  | 15 ++--
 gstlal-calibration/tests/lal_dqtukey_test.py | 92 ++++++++++++++++++++
 2 files changed, 102 insertions(+), 5 deletions(-)
 create mode 100755 gstlal-calibration/tests/lal_dqtukey_test.py

diff --git a/gstlal-calibration/gst/lal/gstlal_dqtukey.c b/gstlal-calibration/gst/lal/gstlal_dqtukey.c
index a517b82bab..5b2ea5a2b1 100644
--- a/gstlal-calibration/gst/lal/gstlal_dqtukey.c
+++ b/gstlal-calibration/gst/lal/gstlal_dqtukey.c
@@ -160,7 +160,12 @@ ones: \
 	} \
 	*remainder = 0; \
 	while(i < src_size) { \
-		if((gboolean) ((src[i] ^ required_on) & required_on_xor_off) == invert_control) { \
+		/*
+		 * (a ? b : !b) is the equivalent of (a == b), that is, checking if a and b have the same
+		 * truth value. Using (a == b) does not work, even if a is typecasted to a boolean. The
+		 * case where a is nonzero and not 1 and b is TRUE fails.
+		 */ \
+		if((src[i] ^ required_on) & required_on_xor_off ? invert_control : !invert_control) { \
 			/* Conditions were met */ \
 			if(!((i + 1) % num_cycle_in)) { \
 				/* In case rate in > rate out */ \
@@ -193,7 +198,7 @@ zeros: \
 	} \
 	*remainder = 0; \
 	while(i < src_size) { \
-		if((gboolean) ((src[i] ^ required_on) & required_on_xor_off) == invert_control) { \
+		if((src[i] ^ required_on) & required_on_xor_off ? invert_control : !invert_control) { \
 			/* Conditions were met */ \
 			if(!(i % num_cycle_in)) { \
 				/* In case rate in > rate out */ \
@@ -247,7 +252,7 @@ ramp_up: \
 	} \
 	*remainder = 0; \
 	while(i < src_size) { \
-		if((gboolean) ((src[i] ^ required_on) & required_on_xor_off) == invert_control) { \
+		if((src[i] ^ required_on) & required_on_xor_off ? invert_control : !invert_control) { \
 			/* Conditions were met */ \
 			if(!((i + 1) % num_cycle_in)) { \
 				/* In case rate in > rate out */ \
@@ -280,7 +285,7 @@ ramp_up: \
  \
 ramp_down: \
 	while(i < src_size) { \
-		if((gboolean) ((src[i] ^ required_on) & required_on_xor_off) == invert_control) { \
+		if((src[i] ^ required_on) & required_on_xor_off ? invert_control : !invert_control) { \
 			/* Conditions were met */ \
 			if(!(i % num_cycle_in)) { \
 				/* In case rate in > rate out */ \
@@ -314,7 +319,7 @@ ramp_down: \
  \
 double_ramp: \
 	while(i < src_size) { \
-		if((gboolean) ((src[i] ^ required_on) & required_on_xor_off) == invert_control) { \
+		if((src[i] ^ required_on) & required_on_xor_off ? invert_control : !invert_control) { \
 			/* Conditions were met */ \
 			if(!(i % num_cycle_in)) { \
 				/* In case rate in > rate out */ \
diff --git a/gstlal-calibration/tests/lal_dqtukey_test.py b/gstlal-calibration/tests/lal_dqtukey_test.py
new file mode 100755
index 0000000000..c5a2f88472
--- /dev/null
+++ b/gstlal-calibration/tests/lal_dqtukey_test.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+# Copyright (C) 2018  Aaron Viets
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#
+# =============================================================================
+#
+#				   Preamble
+#
+# =============================================================================
+#
+
+
+import numpy
+import sys
+from gstlal import pipeparts
+from gstlal import calibration_parts
+import test_common
+from gi.repository import Gst
+
+
+#
+# =============================================================================
+#
+#				  Pipelines
+#
+# =============================================================================
+#
+
+def lal_dqtukey_01(pipeline, name):
+
+	#
+	# This test passes a random series of integers through lal_dqtukey
+	#
+
+	rate_in = 16		# Hz
+	rate_out = 16384	# Hz
+	buffer_length = 1.0	# seconds
+	test_duration = 30.0	# seconds
+
+	#
+	# build pipeline
+	#
+
+	head = test_common.int_test_src(pipeline, buffer_length = buffer_length, rate = rate_in, width = 32, test_duration = test_duration, wave = 5, freq = 0)
+	head = pipeparts.mktee(pipeline, head)
+	pipeparts.mknxydumpsink(pipeline, head, "%s_in.txt" % name)
+	normal = pipeparts.mkgeneric(pipeline, head, "lal_dqtukey", transition_samples = 1024, required_on = 2, required_off = 1, invert_control = False)
+	invert = pipeparts.mkgeneric(pipeline, head, "lal_dqtukey", transition_samples = 1024, required_on = 2, required_off = 1, invert_control = True)
+	invwin = pipeparts.mkgeneric(pipeline, head, "lal_dqtukey", transition_samples = 1024, required_on = 2, required_off = 1, invert_control = False, invert_window = True)
+	invboth = pipeparts.mkgeneric(pipeline, head, "lal_dqtukey", transition_samples = 1024, required_on = 2, required_off = 1, invert_control = True, invert_window = True)
+	normal = pipeparts.mkcapsfilter(pipeline, normal, "audio/x-raw,rate=%s,format=F64LE" % rate_out)
+	invert = pipeparts.mkcapsfilter(pipeline, invert, "audio/x-raw,rate=%s,format=F64LE" % rate_out)
+	invwin = pipeparts.mkcapsfilter(pipeline, invwin, "audio/x-raw,rate=%s,format=F64LE" % rate_out)
+	invboth = pipeparts.mkcapsfilter(pipeline, invboth, "audio/x-raw,rate=%s,format=F64LE" % rate_out)
+	pipeparts.mknxydumpsink(pipeline, normal, "%s_normal_out.txt" % name)
+	pipeparts.mknxydumpsink(pipeline, invert, "%s_invert_out.txt" % name)
+	pipeparts.mknxydumpsink(pipeline, invwin, "%s_invwin_out.txt" % name)
+	pipeparts.mknxydumpsink(pipeline, invboth, "%s_invboth_out.txt" % name)
+
+	#
+	# done
+	#
+	
+	return pipeline
+
+
+#
+# =============================================================================
+#
+#				     Main
+#
+# =============================================================================
+#
+
+
+test_common.build_and_run(lal_dqtukey_01, "lal_dqtukey_01")
+
+
-- 
GitLab