Пример #1
0
def _qrs_gconst(pattern, _):
    """
    General constraints to be added when a new cycle is observed, which
    currently coincides with the observation of the T waves or a QRS complex
    not followed by an observed T wave.
    """
    #We check that there are no missed beat forms.
    _check_missed_beats(pattern)
    beats = pattern.evidence[o.QRS]
    #Morphology check. We require the rhythm morphology to be matched
    #by the new beat in the sequence.
    ref = pattern.hypothesis.morph
    #We initialize the morphology with the first beat.
    if not ref:
        ref = copy.deepcopy(beats[0].shape)
        pattern.hypothesis.morph = ref
    verify(signal_match(ref, beats[-1].shape))
    #This comparison avoids positive matchings with extrasystoles,
    #but we only check it if the beat before the first block is advanced.
    if len(beats) == 3:
        refrr, stdrr = pattern.hypothesis.meas.rr
        if (beats[1].time.start - beats[0].time.start <
                                                min(0.9 * refrr, refrr-stdrr)):
            verify(beats[2].time.start - beats[0].time.start >
                                                      refrr * C.COMPAUSE_MAX_F)
            verify(beats[2].time.start - beats[1].time.start >
                                                    refrr + C.COMPAUSE_MIN_DUR)
    #We require a significant change in consecutive RR intervals.
    if len(beats) >= 3:
        rr = beats[-1].time.start - beats[-2].time.start
        prevrr = beats[-2].time.start - beats[-3].time.start
        verify(abs(prevrr-rr) >= C.RR_MAX_DIFF)
Пример #2
0
def _cycle_finished_gconst(pattern, _):
    """
    General constraints to be added when a trigeminy cycle is finished, this is,
    with the normal beat following an ectopy.
    """
    #We check that there are no missed beats.
    _check_missed_beats(pattern)
    #We update the measurements of the rhythm taking the measures of the
    #regular cycles.
    rrs, pqs, rts = _get_measures(pattern, False)
    if len(pqs) == 0:
        pqm, pqst = 0, 0
    elif len(pqs) == 1:
        #TODO use specific deviations for PQ rather than QT
        pqm, pqst = pqs[0], C.QT_ERR_STD
    else:
        pqm, pqst = np.mean(pqs), max(np.std(pqs), C.MIN_QT_STD)
    if len(rts) == 0:
        rtm, rtst = 0, 0
    elif len(rts) == 1:
        rtm, rtst = rts[0], C.QT_ERR_STD
    else:
        rtm, rtst = np.mean(rts), max(np.std(rts), C.MIN_QT_STD)
    pattern.hypothesis.meas = o.CycleMeasurements((np.mean(rrs), np.std(rrs)),
                                                  (rtm, rtst), (pqm, pqst))
Пример #3
0
def _extrasyst_gconst(pattern, _):
    """
    General constraints of the pattern that are checked when the last T wave
    has been observed.
    """
    beats = pattern.evidence[o.QRS]
    if pattern.istate == 0:
        #We ensure that there are no missed beats.
        _check_missed_beats(pattern)
        #We must ensure that the first two beats and the last one have the
        #same shape.
        verify((beats[-3].paced and beats[-1].paced) or
                                signal_match(beats[-3].shape, beats[-1].shape))
Пример #4
0
def _couplet_gconst(pattern, _):
    """
    General constraints to be checked when the couplet finishes.
    """
    _check_missed_beats(pattern)
    #The second extrasystole cannot be in rhythm with contextual beats, or in
    #such case it must have a different shape.
    beats = pattern.evidence[o.QRS]
    mpt = beats[0].time.start + (beats[-1].time.start -
                                 beats[0].time.start) / 2.
    verify(
        abs(mpt - beats[2].time.start) >= C.ICOUPLET_RCHANGE
        or signal_unmatch(beats[2].shape, beats[-1].shape))
    pattern.hypothesis.meas = copy.copy(
        pattern.evidence[o.Cardiac_Rhythm][0].meas)
Пример #5
0
def _qrs_gconst(pattern, _):
    """
    General constraints to be added when a new cycle is observed, which
    currently coincides with the observation of the T waves or a QRS complex
    not followed by an observed T wave.
    """
    #We update the measurements of the rhythm.
    _update_measures(pattern)
    #And check that there are no missed beat forms.
    _check_missed_beats(pattern)
    beats = pattern.evidence[o.QRS]
    #Morphology check. We require the rhythm morphology to be matched
    #by the new beat in the sequence.
    ref = pattern.hypothesis.morph
    #We initialize the morphology with the first beat.
    if not ref:
        ref = copy.deepcopy(beats[0].shape)
        pattern.hypothesis.morph = ref
    verify(signal_match(ref, beats[-1].shape))
    #TODO improve morphology updating.
    #_update_morphology(pattern)
    envrhythms = pattern.evidence[o.Cardiac_Rhythm]
    prevafib = envrhythms and isinstance(envrhythms[0], o.Atrial_Fibrillation)
    if len(beats) == 2 and envrhythms:
        refrr, stdrr = envrhythms[-1].meas.rr
        #The first RR cannot be within the mean +- 2*std of the previous RR.
        #There must be a rhythm change.
        verify(not refrr - 2*stdrr <= beats[1].time.start - beats[0].time.start
                                                            <= refrr + 2*stdrr)
    if len(beats) >= 3:
        verify(not beats[-1].paced)
        rpks = np.array([b.time.start for b in beats])
        rrs = np.diff(rpks)
        _verify_afib_rhythm(rrs)
        #With this check, we avoid false positives with bigeminies, checking
        #the RR constraints with even and odd rrs.
        if len(beats) >= 6:
            _verify_afib_rhythm(rrs[0::2])
            _verify_afib_rhythm(rrs[1::2])
            _verify_afib_rhythm(np.diff(rpks[0::2]))
    #Atrial activity is only checked at the beginning of the pattern and if
    #there are not previous atrial fibrillation episodes.
    if 1 < len(beats) < 32 and not prevafib:
        _verify_atrial_activity(pattern)