Esempio n. 1
0
 def _read_frame(self, signo = -1):
 #---------------------------------
   if signo < 0 or signo in self.data_signals:
     v = wfdb.WFDB_SampleArray(self._framesize)
     while wfdb.getframe(v.cast()) == self._nsignals:
       if signo < 0: yield [v[i] for i in xrange(self._framesize) if self._sigpoints[i]]
       else:         yield [v[i] for i in xrange(*self._offsets[n])]
Esempio n. 2
0
  def read(self, interval=None, segment=None, maxduration=None, maxpoints=None):
  #----------------------------------------------------------------------------
    """
    Read data from a Signal.

    :param interval: The portion of the signal to read.
    :type interval: :class:`~biosignaml.time.Interval`
    :param segment: A 2-tuple with start and finishing data indices, with the end
      point not included in the returned range.
    :param maxduration: The maximum duration, in seconds, of a single returned segment.
    :param maxpoints: The maximum length, in samples, of a single returned segment.
    :return: An `iterator` returning :class:`~biosignalml.data.DataSegment` segments
      of the signal data.

    If both ``maxduration`` and ``maxpoints`` are given their minimum value is used.
    """

    ## Read is of a record's vector/frame...

    ## So check state of rec.vector or rec.frame and reposition record as needs be...

    ## Ideally read frame into 2D np.array and take appropriate slice when
    ## creating TimeSeries...

    if   interval is not None and segment is not None:
      raise Exception("'interval' and 'segment' cannot both be specified")

    if maxduration:
      pts = int(self.rate*maxduration + 0.5)
      if maxpoints: maxpoints = min(maxpoints, pts)
      else: maxpoints = pts
    if maxpoints is None or not (0 < maxpoints <= BSMLSignal.MAXPOINTS):
      maxpoints = BSMLSignal.MAXPOINTS

    # We need to be consistent as to what an interval is....
    # Use model.Interval ??
    if interval is not None:
      segment = (self.rate*interval.start, self.rate*(interval.start+interval.duration))
    if segment is None:
      startpos = 0
      length = len(self)
    else:
      if segment[0] <= segment[1]: seg = segment
      else:                        seg = (segment[1], segment[0])
      startpos = max(0, int(math.floor(seg[0])))
      length = min(len(self), int(math.ceil(seg[1])) - startpos)

    # Setup offsets into frame for each signal
    siginfo = self._record._siginfo
    offsets = [ (0, siginfo[0].spf) ]    ## This is record wide data...
    samplesperframe = siginfo[0].spf
    for s in xrange(1, self._record._nsignals):
      offsets.append((samplesperframe, siginfo[s].spf))
      samplesperframe += siginfo[s].spf

    v = wfdb.WFDB_SampleArray(samplesperframe)
    s = self._signum
    while length > 0:
      if maxpoints > length: maxpoints = length
      d = []
      i = maxpoints
      rpos = startpos
      while i > 0:
        global _WFDBLock
        with _WFDBLock:
          wfdb.tnextvec(s, rpos)
          r = wfdb.getframe(v.cast())
        if r <= 0: i = 0
        else:
          for n in xrange(offsets[s][0], offsets[s][0]+offsets[s][1]):
            d.append(v[n])
            i -= 1
            rpos += 1
      data = (np.array(d)-self._baseline)/self._gain
      if len(data) <= 0: break
      yield DataSegment(float(startpos)/self.rate, UniformTimeSeries(data, self.rate))
      startpos += len(data)
      length -= len(data)