22import os
33import math
44from . import downloads
5- import pdb
5+
66# All defined WFDB dat formats
77datformats = ["80" ,"212" ,"16" ,"24" ,"32" ]
88
@@ -486,16 +486,11 @@ def rdsegment(filename, dirname, pbdir, nsig, fmt, siglen, byteoffset,
486486
487487 # Copy over the wanted signals
488488 for cn in range (len (out_datchannel [fn ])):
489-
490489 signals [out_datchannel [fn ][cn ]] = datsignals [r_w_channel [fn ][cn ]]
491490
492-
493-
494491 return signals
495492
496493
497-
498-
499494def rddat (filename , dirname , pbdir , fmt , nsig ,
500495 siglen , byteoffset , sampsperframe ,
501496 skew , sampfrom , sampto , smoothframes ):
@@ -543,7 +538,7 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
543538 # Get the intermediate bytes or samples to process. Bit of a discrepancy. Recall special formats
544539 # load uint8 bytes, other formats already load samples.
545540
546- #Get values from dat file, and append bytes/samples if needed.
541+ # Read values from dat file, and append bytes/samples if needed.
547542 if extraflatsamples :
548543 if fmt in ['212' , '310' , '311' ]:
549544 # Extra number of bytes to append onto the bytes read from the dat file.
@@ -557,8 +552,7 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
557552 else :
558553 sigbytes = getdatbytes (filename , dirname , pbdir , fmt , startbyte , nreadsamples )
559554
560- # Read the required bytes from the dat file.
561- # Then continue to process the read values into proper samples
555+ # Continue to process the read values into proper samples
562556
563557 # Special formats
564558 if fmt in ['212' , '310' , '311' ]:
@@ -599,7 +593,9 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
599593 else :
600594 for frame in range (sampsperframe [ch ]):
601595 sig [:, ch ] += sigbytes [sum (([0 ] + sampsperframe )[:ch + 1 ]) + frame ::tsampsperframe ]
602- sig = (sig / sampsperframe )
596+
597+ # Have to change the dtype for averaging frames
598+ sig = (sig .astype ('float64' ) / sampsperframe )
603599
604600 # Skew the signal
605601 sig = skewsig (sig , skew , nsig , readlen , fmt , nanreplace )
@@ -657,7 +653,8 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
657653 else :
658654 for frame in range (sampsperframe [ch ]):
659655 sig [:, ch ] += sigbytes [sum (([0 ] + sampsperframe )[:ch + 1 ]) + frame ::tsampsperframe ]
660- sig = (sig / sampsperframe )
656+ # Have to change the dtype for averaging frames
657+ sig = (sig .astype ('float64' ) / sampsperframe )
661658
662659 # Skew the signal
663660 sig = skewsig (sig , skew , nsig , readlen , fmt , nanreplace )
@@ -834,7 +831,6 @@ def getdatbytes(filename, dirname, pbdir, fmt, startbyte, nsamp):
834831 return sigbytes
835832
836833
837-
838834def bytes2samples (sigbytes , nsamp , fmt ):
839835 """
840836 Converts loaded uint8 blocks into samples for special formats
@@ -977,288 +973,6 @@ def checksigdims(sig, readlen, nsig, sampsperframe):
977973 raise ValueError ('Samples were not loaded correctly' )
978974
979975
980-
981-
982-
983-
984-
985-
986-
987-
988-
989-
990-
991-
992-
993-
994-
995- # OLD! DO NOT USE
996-
997- # Read digital samples from a wfdb signal file
998- # Returns the signal and the number of bytes read.
999- def processwfdbbytes (filename , dirname , pbdir , fmt , startbyte , readlen , nsig , sampsperframe , floorsamp = 0 ):
1000- """
1001- Read digital samples from a wfdb dat file
1002-
1003- Input variables:
1004- - filename: the name of the dat file.
1005- - dirname: the full directory where the dat file is located, if the dat file is local.
1006- - pbdir: the physiobank directory where the dat file is located, if the dat file is remote.
1007- - fmt: the format of the dat file
1008- - startbyte: the starting byte to skip to
1009- - readlen: the length of the signal to be read, in samples.
1010- - nsig:
1011- - floorsamp: the extra sample index used to read special formats (212, 310, 311).
1012-
1013- """
1014-
1015- # Total number of samples per frame
1016- tsampsperframe = sum (sampsperframe )
1017-
1018- # Total number of signal samples to be collected (including discarded ones)
1019- nsamp = readlen * tsampsperframe + floorsamp
1020-
1021- # Reading the dat file into np array and reshaping. Formats 212, 310, and 311 need special processing.
1022- # Note that for these formats with multi samples/frame, have to convert
1023- # bytes to samples before returning average frame values.
1024- if fmt == '212' :
1025- # Read the bytes from the file as unsigned integer blocks
1026- sigbytes , bytesloaded = getdatbytes (filename , dirname , pbdir , fmt , nsamp , startbyte )
1027-
1028- # use this for byte processing
1029- processnsamp = nsamp
1030-
1031- # For odd sampled records, imagine an extra sample and add an extra byte
1032- # to simplify the processing step and remove the extra sample at the end.
1033- if processnsamp % 2 :
1034- sigbytes = np .append (sigbytes , 0 ).astype ('uint64' )
1035- processnsamp += 1
1036-
1037- # No extra samples/frame
1038- if tsampsperframe == nsig :
1039- # Turn the bytes into actual samples.
1040- sig = np .zeros (processnsamp ) # 1d array of actual samples
1041- # One sample pair is stored in one byte triplet.
1042- sig [0 ::2 ] = sigbytes [0 ::3 ] + 256 * \
1043- np .bitwise_and (sigbytes [1 ::3 ], 0x0f ) # Even numbered samples
1044- if len (sig > 1 ):
1045- # Odd numbered samples
1046- sig [1 ::2 ] = sigbytes [2 ::3 ] + 256 * np .bitwise_and (sigbytes [1 ::3 ] >> 4 , 0x0f )
1047- if floorsamp : # Remove extra sample read
1048- sig = sig [floorsamp :]
1049-
1050- # Remove extra sample read if originally odd sampled
1051- if nsamp % 2 :
1052- sig = sig [:- 1 ]
1053-
1054- # Reshape into final array of samples
1055- sig = sig .reshape (readlen , nsig )
1056- sig = sig .astype (int )
1057- # Loaded values as unsigned. Convert to 2's complement form: values
1058- # > 2^11-1 are negative.
1059- sig [sig > 2047 ] -= 4096
1060- # At least one channel has multiple samples per frame. All extra samples are averaged
1061- else :
1062- # Turn the bytes into actual samples.
1063- sigall = np .zeros (processnsamp ) # 1d array of actual samples
1064- sigall [0 ::2 ] = sigbytes [0 ::3 ] + 256 * \
1065- np .bitwise_and (sigbytes [1 ::3 ], 0x0f ) # Even numbered samples
1066-
1067- if len (sigall ) > 1 :
1068- # Odd numbered samples
1069- sigall [1 ::2 ] = sigbytes [2 ::3 ] + 256 * \
1070- np .bitwise_and (sigbytes [1 ::3 ] >> 4 , 0x0f )
1071- if floorsamp : # Remove extra sample read
1072- sigall = sigall [floorsamp :]
1073-
1074- # Remove extra sample read if originally odd sampled
1075- if nsamp % 2 :
1076- sigall = sigall [:- 1 ]
1077-
1078- # Convert to int64 to be able to hold -ve values
1079- sigall = sigall .astype ('int' )
1080- # Loaded values as unsigned. Convert to 2's complement form: values
1081- # > 2^11-1 are negative.
1082- sigall [sigall > 2047 ] -= 4096
1083- # Give the average sample in each frame for each channel
1084- sig = np .zeros ([readlen , nsig ])
1085- for ch in range (0 , nsig ):
1086- if sampsperframe [ch ] == 1 :
1087- sig [:, ch ] = sigall [
1088- sum (([0 ] + sampsperframe )[:ch + 1 ])::tsampsperframe ]
1089- else :
1090- for frame in range (0 , sampsperframe [ch ]):
1091- sig [:, ch ] += sigall [sum (([0 ] + sampsperframe )
1092- [:ch + 1 ]) + frame ::tsampsperframe ]
1093- sig = (sig / sampsperframe ).astype ('int' )
1094- # Three 10 bit samples packed into 4 bytes with 2 bits discarded
1095- elif fmt == '310' :
1096-
1097- # Read the bytes from the file as unsigned integer blocks
1098- sigbytes , bytesloaded = getdatbytes (filename , dirname , pbdir , fmt , nsamp , startbyte )
1099-
1100- if tsampsperframe == nsig : # No extra samples/frame
1101- # Turn the bytes into actual samples.
1102- # 1d array of actual samples. Fill the individual triplets.
1103-
1104- sig = np .zeros (nsamp )
1105-
1106- sig [0 ::3 ] = (sigbytes [0 ::4 ] >> 1 )[0 :len (sig [0 ::3 ])] + 128 * \
1107- np .bitwise_and (sigbytes [1 ::4 ], 0x07 )[0 :len (sig [0 ::3 ])]
1108- if len (sig > 1 ):
1109- sig [1 ::3 ] = (sigbytes [2 ::4 ] >> 1 )[0 :len (sig [1 ::3 ])] + 128 * \
1110- np .bitwise_and (sigbytes [3 ::4 ], 0x07 )[0 :len (sig [1 ::3 ])]
1111- if len (sig > 2 ):
1112- sig [2 ::3 ] = np .bitwise_and ((sigbytes [1 ::4 ] >> 3 ), 0x1f )[0 :len (
1113- sig [2 ::3 ])] + 32 * np .bitwise_and (sigbytes [3 ::4 ] >> 3 , 0x1f )[0 :len (sig [2 ::3 ])]
1114- # First signal is 7 msb of first byte and 3 lsb of second byte.
1115- # Second signal is 7 msb of third byte and 3 lsb of forth byte
1116- # Third signal is 5 msb of second byte and 5 msb of forth byte
1117-
1118- if floorsamp : # Remove extra sample read
1119- sig = sig [floorsamp :]
1120- # Reshape into final array of samples
1121- sig = sig .reshape (readlen , nsig )
1122- # Convert to int64 to be able to hold -ve values
1123- sig = sig .astype ('int' )
1124- # Loaded values as unsigned. Convert to 2's complement form: values
1125- # > 2^9-1 are negative.
1126- sig [sig > 511 ] -= 1024
1127-
1128- else : # At least one channel has multiple samples per frame. All extra samples are averaged.
1129- # Turn the bytes into actual samples.
1130- # 1d array of actual samples. Fill the individual triplets.
1131- sigall = np .zeros (nsamp )
1132- sigall [0 ::3 ] = (sigbytes [0 ::4 ] >> 1 )[0 :len (
1133- sigall [0 ::3 ])] + 128 * np .bitwise_and (sigbytes [1 ::4 ], 0x07 )[0 :len (sigall [0 ::3 ])]
1134- if len (sigall > 1 ):
1135- sigall [1 ::3 ] = (sigbytes [2 ::4 ] >> 1 )[0 :len (
1136- sigall [1 ::3 ])] + 128 * np .bitwise_and (sigbytes [3 ::4 ], 0x07 )[0 :len (sigall [1 ::3 ])]
1137- if len (sigall > 2 ):
1138- sigall [2 ::3 ] = np .bitwise_and ((sigbytes [1 ::4 ] >> 3 ), 0x1f )[0 :len (
1139- sigall [2 ::3 ])] + 32 * np .bitwise_and (sigbytes [3 ::4 ] >> 3 , 0x1f )[0 :len (sigall [2 ::3 ])]
1140- if floorsamp : # Remove extra sample read
1141- sigall = sigall [floorsamp :]
1142- # Convert to int64 to be able to hold -ve values
1143- sigall = sigall .astype ('int' )
1144- # Loaded values as unsigned. Convert to 2's complement form: values
1145- # > 2^9-1 are negative.
1146- sigall [sigall > 511 ] -= 1024
1147-
1148- # Give the average sample in each frame for each channel
1149- sig = np .zeros ([readlen , nsig ])
1150- for ch in range (0 , nsig ):
1151- if sampsperframe [ch ] == 1 :
1152- sig [:, ch ] = sigall [
1153- sum (([0 ] + sampsperframe )[:ch + 1 ])::tsampsperframe ]
1154- else :
1155- for frame in range (0 , sampsperframe [ch ]):
1156- sig [:, ch ] += sigall [sum (([0 ] + sampsperframe )
1157- [:ch + 1 ]) + frame ::tsampsperframe ]
1158- sig = (sig / sampsperframe ).astype ('int' )
1159-
1160- elif fmt == '311' : # Three 10 bit samples packed into 4 bytes with 2 bits discarded
1161-
1162- # Read the bytes from the file as unsigned integer blocks
1163- sigbytes , bytesloaded = getdatbytes (filename , dirname , pbdir , fmt , nsamp , startbyte )
1164-
1165- if tsampsperframe == nsig : # No extra samples/frame
1166- # Turn the bytes into actual samples.
1167- # 1d array of actual samples. Fill the individual triplets.
1168- sig = np .zeros (nsamp )
1169-
1170- sig [0 ::3 ] = sigbytes [0 ::4 ][
1171- 0 :len (sig [0 ::3 ])] + 256 * np .bitwise_and (sigbytes [1 ::4 ], 0x03 )[0 :len (sig [0 ::3 ])]
1172- if len (sig > 1 ):
1173- sig [1 ::3 ] = (sigbytes [1 ::4 ] >> 2 )[0 :len (sig [1 ::3 ])] + 64 * \
1174- np .bitwise_and (sigbytes [2 ::4 ], 0x0f )[0 :len (sig [1 ::3 ])]
1175- if len (sig > 2 ):
1176- sig [2 ::3 ] = (sigbytes [2 ::4 ] >> 4 )[0 :len (sig [2 ::3 ])] + 16 * \
1177- np .bitwise_and (sigbytes [3 ::4 ], 0x7f )[0 :len (sig [2 ::3 ])]
1178- # First signal is first byte and 2 lsb of second byte.
1179- # Second signal is 6 msb of second byte and 4 lsb of third byte
1180- # Third signal is 4 msb of third byte and 6 msb of forth byte
1181- if floorsamp : # Remove extra sample read
1182- sig = sig [floorsamp :]
1183- # Reshape into final array of samples
1184- sig = sig .reshape (readlen , nsig )
1185- # Convert to int64 to be able to hold -ve values
1186- sig = sig .astype ('int' )
1187- # Loaded values as unsigned. Convert to 2's complement form: values
1188- # > 2^9-1 are negative.
1189- sig [sig > 511 ] -= 1024
1190-
1191- else : # At least one channel has multiple samples per frame. All extra samples are averaged.
1192- # Turn the bytes into actual samples.
1193- # 1d array of actual samples. Fill the individual triplets.
1194- sigall = np .zeros (nsamp )
1195- sigall [
1196- 0 ::3 ] = sigbytes [
1197- 0 ::4 ][
1198- 0 :len (
1199- sigall [
1200- 0 ::3 ])] + 256 * np .bitwise_and (
1201- sigbytes [
1202- 1 ::4 ], 0x03 )[
1203- 0 :len (
1204- sigall [
1205- 0 ::3 ])]
1206- if len (sigall > 1 ):
1207- sigall [1 ::3 ] = (sigbytes [1 ::4 ] >> 2 )[0 :len (
1208- sigall [1 ::3 ])] + 64 * np .bitwise_and (sigbytes [2 ::4 ], 0x0f )[0 :len (sigall [1 ::3 ])]
1209- if len (sigall > 2 ):
1210- sigall [2 ::3 ] = (sigbytes [2 ::4 ] >> 4 )[0 :len (
1211- sigall [2 ::3 ])] + 16 * np .bitwise_and (sigbytes [3 ::4 ], 0x7f )[0 :len (sigall [2 ::3 ])]
1212- if floorsamp : # Remove extra sample read
1213- sigall = sigall [floorsamp :]
1214- # Convert to int64 to be able to hold -ve values
1215- sigall = sigall .astype ('int' )
1216- # Loaded values as unsigned. Convert to 2's complement form: values
1217- # > 2^9-1 are negative.
1218- sigall [sigall > 511 ] -= 1024
1219- # Give the average sample in each frame for each channel
1220- sig = np .zeros ([readlen , nsig ])
1221- for ch in range (0 , nsig ):
1222- if sampsperframe [ch ] == 1 :
1223- sig [:, ch ] = sigall [
1224- sum (([0 ] + sampsperframe )[:ch + 1 ])::tsampsperframe ]
1225- else :
1226- for frame in range (0 , sampsperframe [ch ]):
1227- sig [:, ch ] += sigall [sum (([0 ] + sampsperframe )
1228- [:ch + 1 ]) + frame ::tsampsperframe ]
1229- sig = (sig / sampsperframe ).astype ('int' )
1230-
1231- else : # Simple format signals that can be loaded as they are stored.
1232-
1233- # Read the dat file in the specified format
1234- sigbytes , bytesloaded = getdatbytes (filename , dirname , pbdir , fmt , nsamp , startbyte )
1235-
1236- # No extra samples/frame. Just reshape results.
1237- if tsampsperframe == nsig :
1238- sig = sigbytes .reshape (readlen , nsig ).astype ('int' )
1239- # At least one channel has multiple samples per frame. Extra samples are averaged.
1240- else :
1241- # Keep the first sample in each frame for each channel
1242- sig = np .zeros ([readlen , nsig ])
1243- for ch in range (0 , nsig ):
1244- if sampsperframe [ch ] == 1 :
1245- sig [:, ch ] = sigbytes [sum (([0 ] + sampsperframe )[:ch + 1 ])::tsampsperframe ]
1246- else :
1247- for frame in range (0 , sampsperframe [ch ]):
1248- sig [:, ch ] += sigbytes [sum (([0 ] + sampsperframe )
1249- [:ch + 1 ]) + frame ::tsampsperframe ]
1250- sig = (sig / sampsperframe ).astype ('int' )
1251-
1252- # Adjust for byte offset formats
1253- if fmt == '80' :
1254- sig = sig - 128
1255- elif fmt == '160' :
1256- sig = sig - 32768
1257-
1258- return sig , bytesloaded
1259-
1260-
1261-
1262976# Bytes required to hold each sample (including wasted space) for
1263977# different wfdb formats
1264978bytespersample = {'8' : 1 , '16' : 2 , '24' : 3 , '32' : 4 , '61' : 2 ,
0 commit comments