@@ -538,3 +538,88 @@ def load_gep(filename):
538538 timeseries = [t_ch , trigger ]
539539 timeseries .extend (data )
540540 return BlueprintInput (timeseries , freq , names , units , 1 )
541+
542+
543+ def load_smr (filename , chtrig = 0 ):
544+ """Load Spike2 smr file and populate object phys_input.
545+
546+ Parameters
547+ ----------
548+ filename: str
549+ Path to the spike smr or smrx file.
550+
551+ chtrig : int
552+ Index of trigger channel.
553+
554+ Returns
555+ -------
556+ BlueprintInput
557+
558+ Note
559+ ----
560+ Index of chtrig is 1-index (i.e. spike2 channel number).
561+
562+ See Also
563+ --------
564+ physio_obj.BlueprintInput
565+ """
566+ import sonpy
567+
568+ # taken from sonpy demo
569+ read_data = {
570+ sonpy .lib .DataType .Adc : sonpy .lib .SonFile .ReadInts ,
571+ sonpy .lib .DataType .EventFall : sonpy .lib .SonFile .ReadEvents ,
572+ sonpy .lib .DataType .EventRise : sonpy .lib .SonFile .ReadEvents ,
573+ sonpy .lib .DataType .EventBoth : sonpy .lib .SonFile .ReadEvents ,
574+ sonpy .lib .DataType .Marker : sonpy .lib .SonFile .ReadMarkers ,
575+ sonpy .lib .DataType .AdcMark : sonpy .lib .SonFile .ReadWaveMarks ,
576+ sonpy .lib .DataType .RealMark : sonpy .lib .SonFile .ReadRealMarks ,
577+ sonpy .lib .DataType .TextMark : sonpy .lib .SonFile .ReadTextMarks ,
578+ sonpy .lib .DataType .RealWave : sonpy .lib .SonFile .ReadFloats ,
579+ }
580+
581+ smrfile = sonpy .lib .SonFile (filename , True )
582+ time_base = smrfile .GetTimeBase ()
583+ n_channels = smrfile .MaxChannels ()
584+ freq , names , units , timeseries = [], [], [], []
585+ for i in range (n_channels ):
586+ current_channel = smrfile .ChannelType (i )
587+ max_n_tick = smrfile .ChannelMaxTime (i )
588+ if current_channel != sonpy .lib .DataType .Off and max_n_tick > 0 :
589+ max_n_tick = smrfile .ChannelMaxTime (i )
590+ sample_rate = smrfile .GetIdealRate (i )
591+ if current_channel == sonpy .lib .DataType .Adc :
592+ divide = smrfile .ChannelDivide (i )
593+ else : # marker channels
594+ divide = 1 / (time_base * sample_rate )
595+ # conversion factor from CED spike2 doc
596+ # http://ced.co.uk/img/Spike9.pdf
597+ gain = smrfile .GetChannelScale (i ) / 6553.6
598+ offset = smrfile .GetChannelOffset (i )
599+ name = smrfile .GetChannelTitle (chan = i )
600+ unit = smrfile .GetChannelUnits (chan = i )
601+
602+ n_samples = int (np .floor ((max_n_tick ) / divide ))
603+ raw_signal = read_data [current_channel ](
604+ smrfile , chan = i , nMax = n_samples , tFrom = 0 , tUpto = max_n_tick
605+ )
606+
607+ signal = np .array (raw_signal ) * gain + offset
608+
609+ # save the data
610+ freq .append (sample_rate )
611+ names .append (name )
612+ units .append (unit )
613+ timeseries .append (signal )
614+
615+ # use the channel with highest sample rate to create time stamps
616+ idx_max = np .argmax (freq )
617+ n_timepoints = len (timeseries [idx_max ]) # end point included
618+ time = np .arange (n_timepoints ) * freq [idx_max ]
619+
620+ # prepend to the existing list
621+ freq = [freq [idx_max ]] + freq
622+ timeseries = [time ] + timeseries
623+ units = ["s" ] + units
624+ names = ["time" ] + names
625+ return BlueprintInput (timeseries , freq , names , units , chtrig )
0 commit comments