3434 _signal_stream_dtype ,
3535 _spike_channel_dtype ,
3636 _event_channel_dtype ,
37- _common_sig_characteristics ,
3837)
3938
4039
@@ -58,11 +57,13 @@ class IntanRawIO(BaseRawIO):
5857 'one-file-per-channel' which have a header file called 'info.rhd' or 'info.rhs' and a series
5958 of binary files with the '.dat' suffix
6059
60+ * The reader can handle three file formats 'header-attached', 'one-file-per-signal' and
61+ 'one-file-per-channel'.
62+
6163 * Intan files contain amplifier channels labeled 'A', 'B' 'C' or 'D'
6264 depending on the port in which they were recorded along with the following
63- additional channels for RHD:
64-
65- 0: 'RHD2000 amplifier channel'
65+ additional streams.
66+ 0: 'RHD2000' amplifier channel
6667 1: 'RHD2000 auxiliary input channel',
6768 2: 'RHD2000 supply voltage channel',
6869 3: 'USB board ADC input channel',
@@ -79,9 +80,9 @@ class IntanRawIO(BaseRawIO):
7980 10: 'DC Amplifier channel',
8081 11: 'Stim channel',
8182
82- * Due to the structure of the digital input and output channels these can be accessed
83- as one long vector, which must be post-processed in the case of 'header-attached' or
84- 'one-file-per-stream' formats .
83+ * For the "header-attached" and "one-file-per-signal" formats, the structure of the digital input and output channels is
84+ one long vector, which must be post-processed to extract individual digital channel information.
85+ See the intantech website for more information on performing this post-processing .
8586
8687 Examples
8788 --------
@@ -585,7 +586,6 @@ def read_rhs(filename, file_format: str):
585586
586587 # 0: RHS2000 amplifier channel.
587588 for chan_info in channels_by_type [0 ]:
588- name = chan_info ["native_channel_name" ]
589589 chan_info ["sampling_rate" ] = sr
590590 chan_info ["units" ] = "uV"
591591 chan_info ["gain" ] = 0.195
@@ -599,6 +599,7 @@ def read_rhs(filename, file_format: str):
599599 chan_info ["dtype" ] = "int16"
600600 ordered_channel_info .append (chan_info )
601601 if file_format == "header-attached" :
602+ name = chan_info ["native_channel_name" ]
602603 data_dtype += [(name , "uint16" , BLOCK_SIZE )]
603604 else :
604605 data_dtype [0 ] = "int16"
@@ -607,8 +608,8 @@ def read_rhs(filename, file_format: str):
607608 # if we have dc amp we need to grab the correct number of channels
608609 channel_number_dict [10 ] = channel_number_dict [0 ]
609610 for chan_info in channels_by_type [0 ]:
610- name = chan_info ["native_channel_name" ]
611611 chan_info_dc = dict (chan_info )
612+ name = chan_info ["native_channel_name" ]
612613 chan_info_dc ["native_channel_name" ] = name + "_DC"
613614 chan_info_dc ["sampling_rate" ] = sr
614615 chan_info_dc ["units" ] = "mV"
@@ -627,8 +628,8 @@ def read_rhs(filename, file_format: str):
627628 if file_format != "one-file-per-channel" :
628629 channel_number_dict [11 ] = channel_number_dict [0 ] # should be one stim / amplifier channel
629630 for chan_info in channels_by_type [0 ]:
630- name = chan_info ["native_channel_name" ]
631631 chan_info_stim = dict (chan_info )
632+ name = chan_info ["native_channel_name" ]
632633 chan_info_stim ["native_channel_name" ] = name + "_STIM"
633634 chan_info_stim ["sampling_rate" ] = sr
634635 # stim channel are complicated because they are coded
@@ -650,43 +651,51 @@ def read_rhs(filename, file_format: str):
650651
651652 # 3: Analog input channel.
652653 # 4: Analog output channel.
653- for sig_type in [
654- 3 ,
655- 4 ,
656- ]:
654+ for sig_type in [3 , 4 ]:
657655 for chan_info in channels_by_type [sig_type ]:
658- name = chan_info ["native_channel_name" ]
659656 chan_info ["sampling_rate" ] = sr
660657 chan_info ["units" ] = "V"
661658 chan_info ["gain" ] = 0.0003125
662659 chan_info ["offset" ] = - 32768 * 0.0003125
663660 chan_info ["dtype" ] = "uint16"
664661 ordered_channel_info .append (chan_info )
665662 if file_format == "header-attached" :
663+ name = chan_info ["native_channel_name" ]
666664 data_dtype += [(name , "uint16" , BLOCK_SIZE )]
667665 else :
668666 data_dtype [sig_type ] = "uint16"
669667
670668 # 5: Digital input channel.
671669 # 6: Digital output channel.
672670 for sig_type in [5 , 6 ]:
673- if len (channels_by_type [sig_type ]) > 0 :
674- name = {5 : "DIGITAL-IN" , 6 : "DIGITAL-OUT" }[sig_type ]
675- chan_info = channels_by_type [sig_type ][0 ]
676- # So currently until we have get_digitalsignal_chunk we need to do a tiny hack to
677- # make this memory map work correctly. So since our digital data is not organized
678- # by channel like analog/ADC are we have to overwrite the native name to create
679- # a single permanent name that we can find with channel id
680- chan_info ["native_channel_name" ] = name # overwite to allow memmap to work
681- chan_info ["sampling_rate" ] = sr
682- chan_info ["units" ] = "TTL" # arbitrary units TTL for logic
683- chan_info ["gain" ] = 1.0
684- chan_info ["offset" ] = 0.0
685- chan_info ["dtype" ] = "uint16"
686- ordered_channel_info .append (chan_info )
687- if file_format == "header-attached" :
688- data_dtype += [(name , "uint16" , BLOCK_SIZE )]
689- else :
671+ if file_format in ["header-attached" , "one-file-per-signal" ]:
672+ if len (channels_by_type [sig_type ]) > 0 :
673+ name = {5 : "DIGITAL-IN" , 6 : "DIGITAL-OUT" }[sig_type ]
674+ chan_info = channels_by_type [sig_type ][0 ]
675+ # So currently until we have get_digitalsignal_chunk we need to do a tiny hack to
676+ # make this memory map work correctly. So since our digital data is not organized
677+ # by channel like analog/ADC are we have to overwrite the native name to create
678+ # a single permanent name that we can find with channel id
679+ chan_info ["native_channel_name" ] = name
680+ chan_info ["sampling_rate" ] = sr
681+ chan_info ["units" ] = "TTL" # arbitrary units TTL for logic
682+ chan_info ["gain" ] = 1.0
683+ chan_info ["offset" ] = 0.0
684+ chan_info ["dtype" ] = "uint16"
685+ ordered_channel_info .append (chan_info )
686+ if file_format == "header-attached" :
687+ data_dtype += [(name , "uint16" , BLOCK_SIZE )]
688+ else :
689+ data_dtype [sig_type ] = "uint16"
690+ # This case behaves as a binary with 0 and 1 coded as uint16
691+ elif file_format == "one-file-per-channel" :
692+ for chan_info in channels_by_type [sig_type ]:
693+ chan_info ["sampling_rate" ] = sr
694+ chan_info ["units" ] = "TTL"
695+ chan_info ["gain" ] = 1.0
696+ chan_info ["offset" ] = 0.0
697+ chan_info ["dtype" ] = "uint16"
698+ ordered_channels_info .append (chan_info )
690699 data_dtype [sig_type ] = "uint16"
691700
692701 # per discussion with Intan developers before version 3 of their software the 'notch_filter_mode'
@@ -866,7 +875,6 @@ def read_rhd(filename, file_format: str):
866875
867876 # 0: RHD2000 amplifier channel
868877 for chan_info in channels_by_type [0 ]:
869- name = chan_info ["native_channel_name" ]
870878 chan_info ["sampling_rate" ] = sr
871879 chan_info ["units" ] = "uV"
872880 chan_info ["gain" ] = 0.195
@@ -879,34 +887,35 @@ def read_rhd(filename, file_format: str):
879887 ordered_channel_info .append (chan_info )
880888
881889 if file_format == "header-attached" :
890+ name = chan_info ["native_channel_name" ]
882891 data_dtype += [(name , "uint16" , BLOCK_SIZE )]
883892 else :
884893 data_dtype [0 ] = "int16"
885894
886895 # 1: RHD2000 auxiliary input channel
887896 for chan_info in channels_by_type [1 ]:
888- name = chan_info ["native_channel_name" ]
889897 chan_info ["sampling_rate" ] = sr / 4.0
890898 chan_info ["units" ] = "V"
891899 chan_info ["gain" ] = 0.0000374
892900 chan_info ["offset" ] = 0.0
893901 chan_info ["dtype" ] = "uint16"
894902 ordered_channel_info .append (chan_info )
895903 if file_format == "header-attached" :
904+ name = chan_info ["native_channel_name" ]
896905 data_dtype += [(name , "uint16" , BLOCK_SIZE // 4 )]
897906 else :
898907 data_dtype [1 ] = "uint16"
899908
900909 # 2: RHD2000 supply voltage channel
901910 for chan_info in channels_by_type [2 ]:
902- name = chan_info ["native_channel_name" ]
903911 chan_info ["sampling_rate" ] = sr / BLOCK_SIZE
904912 chan_info ["units" ] = "V"
905913 chan_info ["gain" ] = 0.0000748
906914 chan_info ["offset" ] = 0.0
907915 chan_info ["dtype" ] = "uint16"
908916 ordered_channel_info .append (chan_info )
909917 if file_format == "header-attached" :
918+ name = chan_info ["native_channel_name" ]
910919 data_dtype += [(name , "uint16" )]
911920 else :
912921 data_dtype [2 ] = "uint16"
@@ -925,7 +934,6 @@ def read_rhd(filename, file_format: str):
925934
926935 # 3: USB board ADC input channel
927936 for chan_info in channels_by_type [3 ]:
928- name = chan_info ["native_channel_name" ]
929937 chan_info ["sampling_rate" ] = sr
930938 chan_info ["units" ] = "V"
931939 if global_info ["eval_board_mode" ] == 0 :
@@ -940,32 +948,41 @@ def read_rhd(filename, file_format: str):
940948 chan_info ["dtype" ] = "uint16"
941949 ordered_channel_info .append (chan_info )
942950 if file_format == "header-attached" :
951+ name = chan_info ["native_channel_name" ]
943952 data_dtype += [(name , "uint16" , BLOCK_SIZE )]
944953 else :
945954 data_dtype [3 ] = "uint16"
946955
947956 # 4: USB board digital input channel
948957 # 5: USB board digital output channel
949958 for sig_type in [4 , 5 ]:
950- # Now these are included so that user can obtain the
951- # dig signals and process them at the same time
952- if len (channels_by_type [sig_type ]) > 0 :
953- name = {4 : "DIGITAL-IN" , 5 : "DIGITAL-OUT" }[sig_type ]
954- chan_info = channels_by_type [sig_type ][0 ]
955- # So currently until we have get_digitalsignal_chunk we need to do a tiny hack to
956- # make this memory map work correctly. So since our digital data is not organized
957- # by channel like analog/ADC are we have to overwrite the native name to create
958- # a single permanent name that we can find with channel id
959- chan_info ["native_channel_name" ] = name # overwite to allow memmap to work
960- chan_info ["sampling_rate" ] = sr
961- chan_info ["units" ] = "TTL" # arbitrary units TTL for logic
962- chan_info ["gain" ] = 1.0
963- chan_info ["offset" ] = 0.0
964- chan_info ["dtype" ] = "uint16"
965- ordered_channel_info .append (chan_info )
966- if file_format == "header-attached" :
967- data_dtype += [(name , "uint16" , BLOCK_SIZE )]
968- else :
959+ if file_format in ["header-attached" , "one-file-per-signal" ]:
960+ if len (channels_by_type [sig_type ]) > 0 :
961+ name = {4 : "DIGITAL-IN" , 5 : "DIGITAL-OUT" }[sig_type ]
962+ chan_info = channels_by_type [sig_type ][0 ]
963+ # So currently until we have get_digitalsignal_chunk we need to do a tiny hack to
964+ # make this memory map work correctly. So since our digital data is not organized
965+ # by channel like analog/ADC are we have to overwrite the native name to create
966+ # a single permanent name that we can find with channel id
967+ chan_info ["native_channel_name" ] = name
968+ chan_info ["sampling_rate" ] = sr
969+ chan_info ["units" ] = "TTL" # arbitrary units TTL for logic
970+ chan_info ["gain" ] = 1.0
971+ chan_info ["offset" ] = 0.0
972+ chan_info ["dtype" ] = "uint16"
973+ ordered_channel_info .append (chan_info )
974+ if file_format == "header-attached" :
975+ data_dtype += [(name , "uint16" , BLOCK_SIZE )]
976+ else :
977+ data_dtype [sig_type ] = "uint16"
978+ elif file_format == "one-file-per-channel" :
979+ for chan_info in channels_by_type [sig_type ]:
980+ chan_info ["sampling_rate" ] = sr
981+ chan_info ["units" ] = "TTL"
982+ chan_info ["gain" ] = 1.0
983+ chan_info ["offset" ] = 0.0
984+ chan_info ["dtype" ] = "uint16"
985+ ordered_channels_info .append (chan_info )
969986 data_dtype [sig_type ] = "uint16"
970987
971988 # per discussion with Intan developers before version 3 of their software the 'notch_filter_mode'
0 commit comments