@@ -467,7 +467,7 @@ def rdsegment(filename, dirname, pbdir, nsig, fmt, siglen, byteoffset,
467467 if smoothframes or sum (sampsperframe )== nsig :
468468
469469 # Allocate signal array
470- signals = np .empty ([sampto - sampfrom , len (channels )], dtype = 'int64' )
470+ signals = np .zeros ([sampto - sampfrom , len (channels )], dtype = 'int64' )
471471
472472 # Read each wanted dat file and store signals
473473 for fn in w_filename :
@@ -539,7 +539,6 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
539539
540540 # Total number of bytes to be processed in intermediate step.
541541 totalprocessbytes = requiredbytenum ('read' , fmt , totalprocesssamples )
542-
543542
544543 # Get the intermediate bytes or samples to process. Bit of a discrepancy. Recall special formats
545544 # load uint8 bytes, other formats already load samples.
@@ -560,9 +559,9 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
560559
561560 # Read the required bytes from the dat file.
562561 # Then continue to process the read values into proper samples
563- if fmt == '212' :
564-
565- # Clear memory???
562+
563+ # Special formats
564+ if fmt in [ '212' , '310' , '311' ]:
566565
567566 # No extra samples/frame. Obtain original uniform numpy array
568567 if tsampsperframe == nsig :
@@ -584,22 +583,22 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
584583 elif smoothframes :
585584
586585 # Turn the bytes into actual samples. Flat 1d array. All samples for all frames.
587- sigflat = bytes2samples (sigbytes , totalprocesssamples , fmt )
586+ sigbytes = bytes2samples (sigbytes , totalprocesssamples , fmt )
588587
589588 # Remove extra leading sample read within the byte block if any
590589 if blockfloorsamples :
591- sigflat = sigflat [blockfloorsamples :]
590+ sigbytes = sigbytes [blockfloorsamples :]
592591
593- # Smoothed signal
594- sig = np .zeros ((int (len (sigflat )/ tsampsperframe ) , nsig ))
592+ # Allocate memory for smoothed signal
593+ sig = np .zeros ((int (len (sigbytes )/ tsampsperframe ) , nsig ), dtype = 'int64' )
595594
596595 # Transfer and average samples
597596 for ch in range (nsig ):
598597 if sampsperframe [ch ] == 1 :
599- sig [:, ch ] = sigflat [sum (([0 ] + sampsperframe )[:ch + 1 ])::tsampsperframe ]
598+ sig [:, ch ] = sigbytes [sum (([0 ] + sampsperframe )[:ch + 1 ])::tsampsperframe ]
600599 else :
601600 for frame in range (sampsperframe [ch ]):
602- sig [:, ch ] += sigflat [sum (([0 ] + sampsperframe )[:ch + 1 ]) + frame ::tsampsperframe ]
601+ sig [:, ch ] += sigbytes [sum (([0 ] + sampsperframe )[:ch + 1 ]) + frame ::tsampsperframe ]
603602 sig = (sig / sampsperframe )
604603
605604 # Skew the signal
@@ -608,28 +607,23 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
608607 # Extra frames present without wanting smoothing. Return all expanded samples.
609608 else :
610609 # Turn the bytes into actual samples. Flat 1d array. All samples for all frames.
611- sigflat = bytes2samples (sigbytes , totalprocesssamples , fmt )
610+ sigbytes = bytes2samples (sigbytes , totalprocesssamples , fmt )
612611
613612 # Remove extra leading sample read within the byte block if any
614613 if blockfloorsamples :
615- sigflat = sigflat [blockfloorsamples :]
614+ sigbytes = sigbytes [blockfloorsamples :]
616615
617616 # Arranged signals
618617 sig = []
619618
620619 # Transfer over samples
621620 for ch in range (nsig ):
622621 # Indices of the flat signal that belong to the channel
623- ch_indices = np .concatenate (([np .array (range (sampsperframe [ch ])) + sum ([0 ]+ sampsperframe [:ch ]) + tsampsperframe * framenum for framenum in range (int (len (sigflat )/ tsampsperframe ))]))
624- sig .append (sigflat [ch_indices ])
622+ ch_indices = np .concatenate (([np .array (range (sampsperframe [ch ])) + sum ([0 ]+ sampsperframe [:ch ]) + tsampsperframe * framenum for framenum in range (int (len (sigbytes )/ tsampsperframe ))]))
623+ sig .append (sigbytes [ch_indices ])
625624
626625 # Skew the signal
627626 sig = skewsig (sig , skew , nsig , readlen , fmt , nanreplace , sampsperframe )
628-
629- elif fmt == '310' :
630- pass
631- elif fmt == '311' :
632- pass
633627 # Simple format signals that are loaded as they are stored.
634628 else :
635629 # Adjust for skew, reshape, and consider sampsperframe.
@@ -640,9 +634,6 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
640634 elif fmt == '160' :
641635 sigbytes = sigbytes - 32768
642636
643- #print('sigbytes:', sigbytes)
644-
645-
646637 # No extra samples/frame. Obtain original uniform numpy array
647638 if tsampsperframe == nsig :
648639
@@ -656,19 +647,20 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
656647 # Extra frames present to be smoothed. Obtain averaged uniform numpy array
657648 elif smoothframes :
658649
659- # Allocate memory for signal
660- sig = np .empty ([ readlen , nsig ] , dtype = 'int ' )
650+ # Allocate memory for smoothed signal
651+ sig = np .zeros (( int ( len ( sigbytes ) / tsampsperframe ) , nsig ) , dtype = 'int64 ' )
661652
662- # Samples are averaged within frames
663- # Obtain the correct samples, factoring in skew
653+ # Transfer and average samples
664654 for ch in range (nsig ):
665655 if sampsperframe [ch ] == 1 :
666- sig [:, ch ] = sigbytes [skew [ ch ] * tsampsperframe + sum (([0 ] + sampsperframe )[:ch + 1 ])::tsampsperframe ]
656+ sig [:, ch ] = sigbytes [sum (([0 ] + sampsperframe )[:ch + 1 ])::tsampsperframe ]
667657 else :
668658 for frame in range (sampsperframe [ch ]):
669- sig [:, ch ] += sigbytes [skew [ ch ] * tsampsperframe + sum (([0 ] + sampsperframe )[:ch + 1 ]) + frame ::tsampsperframe ]
659+ sig [:, ch ] += sigbytes [sum (([0 ] + sampsperframe )[:ch + 1 ]) + frame ::tsampsperframe ]
670660 sig = (sig / sampsperframe )
671661
662+ # Skew the signal
663+ sig = skewsig (sig , skew , nsig , readlen , fmt , nanreplace )
672664
673665 # Extra frames present without wanting smoothing. Return all expanded samples.
674666 else :
@@ -677,14 +669,8 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
677669
678670 # Transfer over samples
679671 for ch in range (nsig ):
680- # chansig = np.zeros(readlen*sampsperframe[ch], dtype='int')
681- # for frame in range(sampsperframe[ch]):
682- # chansig[frame::sampsperframe[ch]] = sigbytes[skew[ch]*tsampsperframe+sum(([0] + sampsperframe)[:ch + 1]) + frame::tsampsperframe]
683- # sig.append(chansig)
684-
685- # Get the sample indices of the channel samples to transfer over
672+ # Indices of the flat signal that belong to the channel
686673 ch_indices = np .concatenate ([np .array (range (sampsperframe [ch ])) + sum ([0 ]+ sampsperframe [:ch ]) + tsampsperframe * framenum for framenum in range (int (len (sigbytes )/ tsampsperframe ))])
687-
688674 sig .append (sigbytes [ch_indices ])
689675
690676 # Skew the signal
@@ -848,11 +834,12 @@ def getdatbytes(filename, dirname, pbdir, fmt, startbyte, nsamp):
848834 return sigbytes
849835
850836
851- # Converts loaded uint8 blocks into samples for special formats
852- def bytes2samples (sigbytes , nsamp , fmt ):
853837
838+ def bytes2samples (sigbytes , nsamp , fmt ):
839+ """
840+ Converts loaded uint8 blocks into samples for special formats
841+ """
854842 if fmt == '212' :
855-
856843 # Easier to process when dealing with whole blocks
857844 if nsamp % 2 :
858845 nsamp = nsamp + 1
@@ -877,19 +864,69 @@ def bytes2samples(sigbytes, nsamp, fmt):
877864 # Loaded values as unsigned. Convert to 2's complement form:
878865 # values > 2^11-1 are negative.
879866 sig [sig > 2047 ] -= 4096
880- sig [sig > 2047 ] -= 4096
881867
882868 elif fmt == '310' :
883- pass
869+ # Easier to process when dealing with whole blocks
870+ if nsamp % 3 :
871+ nsamp = upround (nsamp ,3 )
872+ addedsamps = nsamp % 3
873+ sigbytes = np .append (sigbytes , np .zeros (addedsamps , dtype = 'uint8' ))
874+ else :
875+ addedsamps = 0
876+
877+ # 1d array of actual samples. Fill the individual triplets.
878+ sig = np .zeros (nsamp , dtype = 'int64' )
879+
880+ # One sample triplet is stored in one byte quartet
881+ # First sample is 7 msb of first byte and 3 lsb of second byte.
882+ sig [0 ::3 ] = (sigbytes [0 ::4 ] >> 1 )[0 :len (sig [0 ::3 ])] + 128 * np .bitwise_and (sigbytes [1 ::4 ], 0x07 )[0 :len (sig [0 ::3 ])]
883+ # Second signal is 7 msb of third byte and 3 lsb of forth byte
884+ sig [1 ::3 ] = (sigbytes [2 ::4 ] >> 1 )[0 :len (sig [1 ::3 ])] + 128 * np .bitwise_and (sigbytes [3 ::4 ], 0x07 )[0 :len (sig [1 ::3 ])]
885+ # Third signal is 5 msb of second byte and 5 msb of forth byte
886+ sig [2 ::3 ] = np .bitwise_and ((sigbytes [1 ::4 ] >> 3 ), 0x1f )[0 :len (sig [2 ::3 ])] + 32 * np .bitwise_and (sigbytes [3 ::4 ] >> 3 , 0x1f )[0 :len (sig [2 ::3 ])]
887+
888+ # Remove trailing samples read within the byte block if originally not 3n sampled
889+ if addedsamps :
890+ sig = sig [:- addedsamps ]
891+
892+ # Loaded values as unsigned. Convert to 2's complement form:
893+ # values > 2^9-1 are negative.
894+ sig [sig > 511 ] -= 1024
884895
885896 elif fmt == '311' :
886- pass
897+ # Easier to process when dealing with whole blocks
898+ if nsamp % 3 :
899+ nsamp = upround (nsamp ,3 )
900+ addedsamps = nsamp % 3
901+ sigbytes = np .append (sigbytes , np .zeros (addedsamps , dtype = 'uint8' ))
902+ else :
903+ addedsamps = 0
904+
905+ # 1d array of actual samples. Fill the individual triplets.
906+ sig = np .zeros (nsamp , dtype = 'int64' )
907+
908+ # One sample triplet is stored in one byte quartet
909+ # First sample is first byte and 2 lsb of second byte.
910+ sig [0 ::3 ] = sigbytes [0 ::4 ][0 :len (sig [0 ::3 ])] + 256 * np .bitwise_and (sigbytes [1 ::4 ], 0x03 )[0 :len (sig [0 ::3 ])]
911+ # Second sample is 6 msb of second byte and 4 lsb of third byte
912+ sig [1 ::3 ] = (sigbytes [1 ::4 ] >> 2 )[0 :len (sig [1 ::3 ])] + 64 * np .bitwise_and (sigbytes [2 ::4 ], 0x0f )[0 :len (sig [1 ::3 ])]
913+ # Third sample is 4 msb of third byte and 6 msb of forth byte
914+ sig [2 ::3 ] = (sigbytes [2 ::4 ] >> 4 )[0 :len (sig [2 ::3 ])] + 16 * np .bitwise_and (sigbytes [3 ::4 ], 0x7f )[0 :len (sig [2 ::3 ])]
915+
916+ # Remove trailing samples read within the byte block if originally not 3n sampled
917+ if addedsamps :
918+ sig = sig [:- addedsamps ]
919+
920+ # Loaded values as unsigned. Convert to 2's complement form:
921+ # values > 2^9-1 are negative.
922+ sig [sig > 511 ] -= 1024
887923 return sig
888924
889925
890- # Skew the signal and shave off extra samples
891926def skewsig (sig , skew , nsig , readlen , fmt , nanreplace , sampsperframe = None ):
892927 """
928+ Skew the signal, insert nans and shave off end of array if needed.
929+
893930 fmt is just for the correct nan value.
894931 sampsperframe is only used for skewing expanded signals.
895932 """
@@ -1202,7 +1239,7 @@ def processwfdbbytes(filename, dirname, pbdir, fmt, startbyte, readlen, nsig, sa
12021239 # At least one channel has multiple samples per frame. Extra samples are averaged.
12031240 else :
12041241 # Keep the first sample in each frame for each channel
1205- sig = np .empty ([readlen , nsig ])
1242+ sig = np .zeros ([readlen , nsig ])
12061243 for ch in range (0 , nsig ):
12071244 if sampsperframe [ch ] == 1 :
12081245 sig [:, ch ] = sigbytes [sum (([0 ] + sampsperframe )[:ch + 1 ])::tsampsperframe ]
@@ -1222,68 +1259,6 @@ def processwfdbbytes(filename, dirname, pbdir, fmt, startbyte, readlen, nsig, sa
12221259
12231260
12241261
1225-
1226-
1227-
1228-
1229-
1230-
1231-
1232-
1233-
1234-
1235-
1236- # OLD! DO NOT USE
1237- def skewsignal (sig , skew , filename , dirname , pbdir , nsig , fmt , siglen , sampfrom , sampto , startbyte ,
1238- bytesloaded , byteoffset , sampsperframe ):
1239-
1240- # Total number of samples per frame.
1241- tsampsperframe = sum (sampsperframe )
1242-
1243- if max (skew ) > 0 :
1244- # Array of samples to fill in the final samples of the skewed channels.
1245- extrasig = np .empty ([max (skew ), nsig ])
1246- extrasig .fill (digi_nan (fmt ))
1247-
1248- # Load the extra samples if the end of the file hasn't been reached.
1249- if siglen - (sampto - sampfrom ):
1250- startbyte = startbyte + bytesloaded
1251- # Point the the file pointer to the start of a block of 3 or 4 and
1252- # keep track of how many samples to discard after reading. For
1253- # regular formats the file pointer is already at the correct
1254- # location.
1255- if fmt == '212' :
1256- # Extra samples to read
1257- floorsamp = (startbyte - byteoffset ) % 3
1258- # Now the byte pointed to is the first of a byte triplet
1259- # storing 2 samples. It happens that the extra samples match
1260- # the extra bytes for fmt 212
1261- startbyte = startbyte - floorsamp
1262- elif (fmt == '310' ) | (fmt == '311' ):
1263- floorsamp = (startbyte - byteoffset ) % 4
1264- # Now the byte pointed to is the first of a byte quartet
1265- # storing 3 samples.
1266- startbyte = startbyte - floorsamp
1267-
1268- # The length of extra signals to be loaded
1269- extraloadlen = min (siglen - (sampto - sampfrom ), max (skew ))
1270-
1271- # Array of extra loaded samples
1272- extraloadedsig = processwfdbbytes (filename , dirname , pbdir ,
1273- fmt , startbyte , extraloadlen , nsig , sampsperframe , floorsamp )[0 ]
1274-
1275- # Fill in the extra loaded samples
1276- extrasig [:extraloadedsig .shape [0 ], :] = extraloadedsig
1277-
1278- # Fill in the skewed channels with the appropriate values.
1279- for ch in range (0 , nsig ):
1280- if skew [ch ] > 0 :
1281- sig [:- skew [ch ], ch ] = sig [skew [ch ]:, ch ]
1282- sig [- skew [ch ]:, ch ] = extrasig [:skew [ch ], ch ]
1283- return sig
1284-
1285-
1286-
12871262# Bytes required to hold each sample (including wasted space) for
12881263# different wfdb formats
12891264bytespersample = {'8' : 1 , '16' : 2 , '24' : 3 , '32' : 4 , '61' : 2 ,
@@ -1458,10 +1433,6 @@ def wrdatfile(filename, fmt, d_signals, byteoffset, expanded=False, e_d_signals=
14581433 for framenum in range (spf ):
14591434 d_signals [:, expand_ch ] = e_d_signals [ch ][framenum ::spf ]
14601435 expand_ch = expand_ch + 1
1461-
1462- # ch_indices = np.concatenate(([np.array(range(sampsperframe[ch])) + sum([0]+sampsperframe[:ch]) + tsampsperframe*framenum for framenum in range(int(len(sigflat)/tsampsperframe))]))
1463- # sig.append(sigflat[ch_indices])
1464- # d_signals[] = e_d_signals[ch]
14651436
14661437 # This nsig is used for making list items.
14671438 # Does not necessarily represent number of signals (ie. for expanded=True)
0 commit comments