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)
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))
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))
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)
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)