@@ -971,6 +971,90 @@ def test_infer_sig_len(self):
971971
972972 assert record_2 .__eq__ (record )
973973
974+ def test_physical_conversion (self ):
975+ n_sig = 3
976+ adc_gain = [1.0 , 1234.567 , 765.4321 ]
977+ baseline = [10 , 20 , - 30 ]
978+ d_signal = np .repeat (np .arange (- 100 , 100 ), 3 ).reshape (- 1 , 3 )
979+ e_d_signal = list (d_signal .transpose ())
980+ fmt = ["16" , "16" , "16" ]
981+
982+ # Test adding or subtracting a small offset (0.01 ADU) to check
983+ # that we correctly round to the nearest integer
984+ for offset in (0 , - 0.01 , 0.01 ):
985+ p_signal = (d_signal + offset - baseline ) / adc_gain
986+ e_p_signal = list (p_signal .transpose ())
987+
988+ # Test converting p_signal to d_signal
989+
990+ record = wfdb .Record (
991+ n_sig = n_sig ,
992+ p_signal = p_signal .copy (),
993+ adc_gain = adc_gain ,
994+ baseline = baseline ,
995+ fmt = fmt ,
996+ )
997+
998+ d_signal_converted = record .adc (expanded = False , inplace = False )
999+ np .testing .assert_array_equal (d_signal_converted , d_signal )
1000+
1001+ record .adc (expanded = False , inplace = True )
1002+ np .testing .assert_array_equal (record .d_signal , d_signal )
1003+
1004+ # Test converting e_p_signal to e_d_signal
1005+
1006+ record = wfdb .Record (
1007+ n_sig = n_sig ,
1008+ e_p_signal = [s .copy () for s in e_p_signal ],
1009+ adc_gain = adc_gain ,
1010+ baseline = baseline ,
1011+ fmt = fmt ,
1012+ )
1013+
1014+ e_d_signal_converted = record .adc (expanded = True , inplace = False )
1015+ self .assertEqual (len (e_d_signal_converted ), n_sig )
1016+ for x , y in zip (e_d_signal_converted , e_d_signal ):
1017+ np .testing .assert_array_equal (x , y )
1018+
1019+ record .adc (expanded = True , inplace = True )
1020+ self .assertEqual (len (record .e_d_signal ), n_sig )
1021+ for x , y in zip (record .e_d_signal , e_d_signal ):
1022+ np .testing .assert_array_equal (x , y )
1023+
1024+ # Test automatic conversion using wfdb.wrsamp()
1025+
1026+ wfdb .wrsamp (
1027+ "test_physical_conversion" ,
1028+ fs = 1000 ,
1029+ sig_name = ["X" , "Y" , "Z" ],
1030+ units = ["mV" , "mV" , "mV" ],
1031+ p_signal = p_signal ,
1032+ adc_gain = adc_gain ,
1033+ baseline = baseline ,
1034+ fmt = ["16" , "16" , "16" ],
1035+ )
1036+ record = wfdb .rdrecord ("test_physical_conversion" , physical = False )
1037+ np .testing .assert_array_equal (record .d_signal , d_signal )
1038+
1039+ record = wfdb .rdrecord ("test_physical_conversion" , physical = True )
1040+ for ch , gain in enumerate (adc_gain ):
1041+ np .testing .assert_allclose (
1042+ record .p_signal [:, ch ],
1043+ p_signal [:, ch ],
1044+ rtol = 0.0000001 ,
1045+ atol = (0.05 / gain ),
1046+ )
1047+
1048+ @classmethod
1049+ def tearDownClass (cls ):
1050+ writefiles = [
1051+ "test_physical_conversion.dat" ,
1052+ "test_physical_conversion.hea" ,
1053+ ]
1054+ for file in writefiles :
1055+ if os .path .isfile (file ):
1056+ os .remove (file )
1057+
9741058
9751059class TestDownload (unittest .TestCase ):
9761060 # Test that we can download records with no "dat" file
0 commit comments