@@ -434,6 +434,8 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
434
434
# Then continue to process the read values into proper samples
435
435
if fmt == '212' :
436
436
437
+ # Clear memory???
438
+
437
439
# No extra samples/frame. Obtain original uniform numpy array
438
440
if tsampsperframe == nsig :
439
441
@@ -445,17 +447,56 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
445
447
sig = sig [blockfloorsamples :]
446
448
447
449
# Reshape into multiple channels
448
- sig = sig .reshape (- 1 , nsig )
450
+ sig = sig .reshape (- 1 , nsig )
449
451
450
452
# Skew the signal
451
453
sig = skewsig (sig , skew , nsig , readlen )
452
454
453
455
# Extra frames present to be smoothed. Obtain averaged uniform numpy array
454
456
elif smoothframes :
455
- pass
457
+
458
+ # Turn the bytes into actual samples. Flat 1d array. All samples for all frames.
459
+ sigflat = bytes2samples (sigbytes , totalprocesssamples , fmt )
460
+
461
+ # Remove extra leading sample read within the byte block if any
462
+ if blockfloorsamples :
463
+ sigflat = sigflat [blockfloorsamples :]
464
+
465
+ # Smoothed signal
466
+ sig = np .zeros (int (len (sigflat )/ tsampsperframe ) , nsig )
467
+
468
+ # Transfer and average samples
469
+ for ch in range (nsig ):
470
+ if sampsperframe [ch ] == 1 :
471
+ sig [:, ch ] = sigflat [sum (([0 ] + sampsperframe )[:ch + 1 ])::tsampsperframe ]
472
+ else :
473
+ for frame in range (sampsperframe [ch ]):
474
+ sig [:, ch ] += sigflat [sum (([0 ] + sampsperframe )[:ch + 1 ]) + frame ::tsampsperframe ]
475
+ sig = (sig / sampsperframe )
476
+
477
+ # Skew the signal
478
+ sig = skewsig (sig , skew , nsig , readlen )
479
+
456
480
# Extra frames present without wanting smoothing. Return all expanded samples.
457
481
else :
458
- pass
482
+ # Turn the bytes into actual samples. Flat 1d array. All samples for all frames.
483
+ sigflat = bytes2samples (sigbytes , totalprocesssamples , fmt )
484
+
485
+ # Remove extra leading sample read within the byte block if any
486
+ if blockfloorsamples :
487
+ sigflat = sigflat [blockfloorsamples :]
488
+
489
+ # Arranged signals
490
+ sig = []
491
+
492
+ # Transfer over samples
493
+ for ch in range (nsig ):
494
+ # Indices of the flat signal that belong to the channel
495
+ ch_indices = np .concatenate ([np .array (range (sampsperframe [ch ])) + tsampsperframe * framenum for framenum in range (int (len (sigflat )/ tsampsperframe ))])
496
+ sig .append (sigflat [ch_indices ])
497
+
498
+ # Skew the signal
499
+ sig = skewsig (sig , skew , nsig , readlen , sampsperframe )
459
500
460
501
elif fmt == '310' :
461
502
pass
@@ -465,12 +506,16 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
465
506
else :
466
507
# Adjust for skew, reshape, and consider sampsperframe.
467
508
509
+ # Adjust for byte offset formats
510
+ if fmt == '80' :
511
+ sigbytes = sigbytes - 128
512
+ elif fmt == '160' :
513
+ sigbytes = sigbytes - 32768
514
+
468
515
# No extra samples/frame. Obtain original uniform numpy array
469
516
if tsampsperframe == nsig :
470
517
471
- # Reshape the array into the correct number of channels
472
- # At this point, cannot reshape(readlen, nsig) because there might
473
- # be extra skew samples
518
+ # Reshape into multiple channels
474
519
sig = sigbytes .reshape (- 1 , nsig ).astype ('int' )
475
520
476
521
# Skew the signal
@@ -496,23 +541,25 @@ def rddat(filename, dirname, pbdir, fmt, nsig,
496
541
else :
497
542
# List of 1d numpy arrays
498
543
sig = []
544
+
545
+ # Transfer over samples
499
546
for ch in range (nsig ):
500
- chansig = np .zeros (readlen * sampsperframe [ch ], dtype = 'int' )
501
- for frame in range (sampsperframe [ch ]):
502
- chansig [frame ::sampsperframe [ch ]] = sigbytes [skew [ch ]* tsampsperframe + sum (([0 ] + sampsperframe )[:ch + 1 ]) + frame ::tsampsperframe ]
547
+ # chansig = np.zeros(readlen*sampsperframe[ch], dtype='int')
548
+ # for frame in range(sampsperframe[ch]):
549
+ # chansig[frame::sampsperframe[ch]] = sigbytes[skew[ch]*tsampsperframe+sum(([0] + sampsperframe)[:ch + 1]) + frame::tsampsperframe]
550
+ # sig.append(chansig)
503
551
504
- sig .append (chansig )
552
+ ch_indices = np .concatenate ([np .array (range (sampsperframe [ch ])) + tsampsperframe * framenum for framenum in range (int (len (sigflat )/ tsampsperframe ))])
553
+ sig .append (sigbytes [ch_indices ])
505
554
506
- # Adjust for byte offset formats
507
- if fmt == '80' :
508
- sig = sig - 128
509
- elif fmt == '160' :
510
- sig = sig - 32768
555
+ # Skew the signal
556
+ sig = skewsig (sig , skew , nsig , readlen , sampsperframe )
511
557
558
+ # Integrity check of signal shape after reading
559
+ checksigdims (sig , readlen , nsig , sampsperframe )
512
560
513
561
return sig
514
562
515
-
516
563
def calc_read_params (fmt , siglen , byteoffset , skew , tsampsperframe , sampfrom , sampto ):
517
564
"""
518
565
Calculate parameters used to read and process the dat file
@@ -579,6 +626,44 @@ def calc_read_params(fmt, siglen, byteoffset, skew, tsampsperframe, sampfrom, sa
579
626
580
627
return (startbyte , nreadsamples , blockfloorsamples , extraflatsamples , nanreplace )
581
628
629
+ def requiredbytenum (mode , fmt , nsamp ):
630
+ """
631
+ Determine how many signal bytes are needed to read a file, or now many
632
+ should be written to a file, for special formats.
633
+
634
+ Input arguments:
635
+ - mode: 'read' or 'write'
636
+ - fmt: format
637
+ - nsamp: number of samples
638
+
639
+ It would be nice if read and write were the same, but fmt 311 for
640
+ n_extra == 2 ruins it.
641
+ """
642
+
643
+ if fmt == '212' :
644
+ nbytes = math .ceil (nsamp * 1.5 )
645
+ elif fmt in ['310' , '311' ]:
646
+ n_extra = nsamp % 3
647
+
648
+ if n_extra == 2 :
649
+ if fmt == '310' :
650
+ nbytes = upround (nsamp * 4 / 3 , 4 )
651
+ # 311
652
+ else :
653
+ if mode == 'read' :
654
+ nbytes = math .ceil (nsamp * 4 / 3 )
655
+ # Have to write more bytes for wfdb c to work
656
+ else :
657
+ nbytes = upround (nsamp * 4 / 3 , 4 )
658
+ # 0 or 1
659
+ else :
660
+ nbytes = math .ceil (nsamp * 4 / 3 )
661
+ else :
662
+ nbytes = nsamp * bytespersample [fmt ]
663
+
664
+ return int (nbytes )
665
+
666
+
582
667
def getdatbytes (filename , dirname , pbdir , fmt , startbyte , nsamp ):
583
668
"""
584
669
Read bytes from a dat file, either local or remote, into a numpy array.
@@ -658,63 +743,29 @@ def bytes2samples(sigbytes, nsamp, fmt):
658
743
sig [sig > 2047 ] -= 4096
659
744
sig [sig > 2047 ] -= 4096
660
745
661
- elif fmt == '310' :
746
+ elif fmt == '310' :
747
+ pass
662
748
663
749
elif fmt == '311' :
664
-
750
+ pass
665
751
return sig
666
752
667
753
668
-
669
- def requiredbytenum (mode , fmt , nsamp ):
670
- """
671
- Determine how many signal bytes are needed to read a file, or now many
672
- should be written to a file, for special formats.
673
-
674
- Input arguments:
675
- - mode: 'read' or 'write'
676
- - fmt: format
677
- - nsamp: number of samples
678
-
679
- It would be nice if read and write were the same, but fmt 311 for
680
- n_extra == 2 ruins it.
681
- """
682
-
683
- if fmt == '212' :
684
- nbytes = math .ceil (nsamp * 1.5 )
685
- elif fmt in ['310' , '311' ]:
686
- n_extra = nsamp % 3
687
-
688
- if n_extra == 2 :
689
- if fmt == '310' :
690
- nbytes = upround (nsamp * 4 / 3 , 4 )
691
- # 311
692
- else :
693
- if mode == 'read' :
694
- nbytes = math .ceil (nsamp * 4 / 3 )
695
- # Have to write more bytes for wfdb c to work
696
- else :
697
- nbytes = upround (nsamp * 4 / 3 , 4 )
698
- # 0 or 1
699
- else :
700
- nbytes = math .ceil (nsamp * 4 / 3 )
701
- else :
702
- nbytes = nsamp * bytespersample [fmt ]
703
-
704
- return int (nbytes )
705
-
706
754
# Skew the signal and shave off extra samples
707
- def skewsig (sig , skew , nsig , readlen ):
755
+ def skewsig (sig , skew , nsig , readlen , sampsperframe ):
708
756
709
757
if max (skew )> 0 :
710
758
711
759
# Expanded frame samples. List of arrays.
712
760
if type (sig ) == list :
713
761
# Shift the channel samples
714
-
762
+ for ch in range (nsig ):
763
+ if skew [ch ]> 0 :
764
+ sig [ch ][:readlen * sampsperframe [ch ]] = sig [ch ][skew [ch ]* sampsperframe [ch ]:]
715
765
716
766
# Shave off the extra signal length at the end
717
-
767
+ for ch in range (nsig ):
768
+ sig [ch ] = sig [ch ][:readlen * sampsperframe [ch ]]
718
769
719
770
# Insert nans where skewed signal overran dat file
720
771
for ch in range (nsig ):
@@ -737,7 +788,17 @@ def skewsig(sig, skew, nsig, readlen):
737
788
return sig
738
789
739
790
740
-
791
+ # Integrity check of signal shape after reading
792
+ def checksigdims (sig , readlen , nsig , sampsperframe ):
793
+ if type (sig ) == np .ndarray :
794
+ if sig .shape != (readlen , nsig ):
795
+ raise ValueError ('Samples were not loaded correctly' )
796
+ else :
797
+ if len (sig ) != nsig :
798
+ raise ValueError ('Samples were not loaded correctly' )
799
+ for ch in range (nsig ):
800
+ if len (sig [ch ]) != sampsperframe [ch ] * readlen
801
+ raise ValueError ('Samples were not loaded correctly' )
741
802
742
803
743
804
0 commit comments