def _p_tconst(pattern, pwave): """P waves temporal constraints""" BASIC_TCONST(pattern, pwave) tnet = pattern.last_tnet tnet.add_constraint(pwave.start, pwave.end, C.PW_DURATION) #We find the associated QRS. beats = pattern.evidence[o.QRS] qidx = qrsidx + len(beats) if qrsidx < 0 else qrsidx qrs = beats[qidx] if qidx > 0: tnet.set_before(beats[qidx - 1].end, pwave.start) tnet.add_constraint(pwave.start, qrs.start, C.N_PR_INTERVAL) tnet.set_before(pwave.end, qrs.start) if len(pattern.evidence[o.PWave]) > 10: #The mean and standard deviation of the PQ measurements will #influence the following observations. if qidx % 2 == 0: pqmean, pqstd = pattern.hypothesis.meas.pq else: pqs = _get_measures(pattern, True)[2] pqmean, pqstd = np.mean(pqs), np.std(pqs) if not np.isnan(pqmean) and not np.isnan(pqstd): interv = Iv(int(pqmean - 2 * pqstd), int(pqmean + 2 * pqstd)) if interv.overlap(C.N_PR_INTERVAL): tnet.add_constraint(pwave.start, qrs.start, interv)
def eval_vflut(anns, _): """Evaluates the ventricular flutter presence""" lth, uth, dth = ms2sp( (4 * 60 + 45) * 1000), ms2sp(5 * 60 * 1000), ms2sp(3500) #We remove separations between consecutive flutter fragments i = 0 while i < len(anns): if anns[i].code is ECGCodes.VFOFF: onset = next((j for j in range(i, len(anns)) if anns[j].code is ECGCodes.VFON), None) if onset is not None and anns[i].time == anns[onset].time: anns.pop(onset) anns.pop(i) i -= 1 i += 1 vflim = (a for a in anns if a.code in (ECGCodes.VFON, ECGCodes.VFOFF)) vfluts = [] while True: try: beg = next(vflim) end = next(vflim) vfluts.append(Iv(beg.time, end.time)) except StopIteration: break #If the record shows many flutter fragments, we simply check some flutter #waves in the last 15 seconds. if sum(fl.length for fl in vfluts) > ms2sp(20000): vfw = [ a.time for a in anns if a.code is ECGCodes.FLWAV and lth <= a.time <= uth ] return len(vfw) > 5 interv = Iv(lth, uth) return any([interv.intersection(vflut).length > dth for vflut in vfluts])
def test_equal(self): v0 = Interval(0, 10) v1 = Interval(7, 15) nw = ConstraintNetwork() nw.set_equal(v0, v1) nw.minimize_network() assert v0 == v1
def test_hashable(self): var = Interval(10, 150) assert isinstance(var, Hashable) var = [Interval(0, x) for x in range(100)] varset = set(var) assert len(varset) == 100 assert all(v in varset for v in var)
def test_move(self): inter = Interval(0, 10) inter = inter.move(5) assert isinstance(inter, Interval) assert inter.start == 5 assert inter.end == 15 inter = inter.move(-5) assert inter.start == 0 assert inter.end == 10
def _t_tconst(pattern, twave): """ Temporal constraints of the T Waves wrt the corresponding QRS complex. """ BASIC_TCONST(pattern, twave) tnet = pattern.last_tnet obseq = pattern.obs_seq idx = pattern.get_step(twave) beats = pattern.evidence[o.QRS] qidx = qrsidx + len(beats) if qrsidx < 0 else qrsidx qrs = beats[qidx] if qidx > 1: refsq = beats[qidx - 1].earlystart - beats[qidx - 2].lateend tnet.add_constraint(qrs.time, twave.end, Iv(0, max(0, refsq - C.TQ_INTERVAL_MIN))) if idx > 0 and isinstance(obseq[idx - 1], o.PWave): pwave = obseq[idx - 1] tnet.add_constraint( pwave.end, twave.start, Iv(C.ST_INTERVAL.start, C.PQ_INTERVAL.end + C.QRS_DUR.end)) if qidx < len(beats) - 1: tnet.set_before(twave.end, beats[qidx + 1].start) #ST interval tnet.add_constraint(qrs.end, twave.start, C.ST_INTERVAL) #QT duration tnet.add_constraint(qrs.start, twave.end, C.N_QT_INTERVAL) #RT variation if qidx % 2 == 0: rtmean, rtstd = pattern.hypothesis.meas.rt #We also define a constraint on T wave end based on the last #distance between normal and ectopic QRS. if qidx > 0: tnet.add_constraint( qrs.end, twave.end, Iv(0, beats[qidx - 1].earlystart - beats[qidx - 2].lateend)) else: rts = _get_measures(pattern, 1)[2] rtmean, rtstd = np.mean(rts), np.std(rts) if rtmean > 0: #The mean and standard deviation of the PQ measurements will #influence the following observations. maxdiff = (C.QT_ERR_STD if len(pattern.evidence[o.TWave]) < 10 else rtstd) maxdiff = max(maxdiff, C.MIN_QT_STD) interv = Iv(int(rtmean - 2.5 * maxdiff), int(rtmean + 2.5 * maxdiff)) #We avoid possible inconsistencies with constraint introduced by #the rhythm information. try: existing = tnet.get_constraint(qrs.time, twave.end).constraint except KeyError: existing = Iv(-np.inf, np.inf) if interv.overlap(existing): tnet.add_constraint(qrs.time, twave.end, interv)
def test_hash(self): inter = Interval(2, 20) assert hash(inter) == (2 ^ 20) x = [1, 7, 1, 23, 1, 7, 1, 23, 1, 7, 1, 23, 1, 7] for m in x: inter = inter.move(m) assert hash(inter) == (2 ^ 20) inter = Interval(float("-inf"), float("inf")) assert hash(inter) == hash(float("-inf")) ^ hash(float("inf"))
def test_ordering(self): inter = Interval(0, 15) var1 = Variable(inter) var2 = Variable(inter.move(5)) assert var1 < var2 assert var1 != var2 var2 = Variable(inter.move(-5)) assert var1 > var2 assert var1 != var2 var2 = Variable(Interval(0, 5)) assert var1 > var2 assert var1 != var2 var2 = Variable(Interval(0, 20)) assert var1 < var2 assert var1 != var2 var2 = Variable(Interval(0, 15)) assert var1 == var2 assert not var1 < var2 assert not var1 > var2 var2 = Variable(None) assert var1 != var2 assert var1 > var2 assert not var1 < var2 var2 = Variable() assert var1 != var2 assert var1 > var2
def _p_qrs_tconst(pattern, pwave): """ Temporal constraints of the P Waves wrt the corresponding QRS complex """ tnet = pattern.tnet tnet.add_constraint(pwave.start, pwave.end, C.PW_DURATION) #We find the QRS observed just before that P wave. idx = pattern.get_step(pwave) if idx > 0 and isinstance(pattern.trseq[idx - 1][1], o.QRS): qrs = pattern.trseq[idx - 1][1] #PR interval tnet.add_constraint(pwave.start, qrs.start, C.N_PR_INTERVAL) tnet.set_before(pwave.end, qrs.start) if len(pattern.evidence[o.PWave]) > 10: #The mean and standard deviation of the PQ measurements will #influence the following observations. pqmean, pqstd = pattern.hypothesis.meas.pq interv = Iv(int(pqmean - 2 * pqstd), int(pqmean + 2 * pqstd)) if interv.overlap(C.N_PR_INTERVAL): tnet.add_constraint(pwave.start, qrs.start, interv)
def _t_tconst(pattern, twave): """ Temporal constraints of the T Waves wrt the corresponding QRS complex. """ BASIC_TCONST(pattern, twave) tnet = pattern.last_tnet #We find the associated QRS. beats = pattern.evidence[o.QRS] qidx = qrsidx + len(beats) if qrsidx < 0 else qrsidx qrs = beats[qidx] if qidx < len(beats) - 1: tnet.set_before(twave.end, beats[qidx + 1].start) #ST interval tnet.add_constraint(qrs.end, twave.start, C.ST_INTERVAL) #QT duration tnet.add_constraint(qrs.start, twave.end, C.N_QT_INTERVAL) #RT variation if not _is_ectopic(qidx): rtmean, rtstd = pattern.hypothesis.meas.rt else: rts = _get_measures(pattern, True)[2] rtmean, rtstd = np.mean(rts), np.std(rts) if rtmean > 0: #The mean and standard deviation of the PQ measurements will #influence the following observations. maxdiff = (C.QT_ERR_STD if len(pattern.evidence[o.TWave]) < 10 else rtstd) maxdiff = max(maxdiff, C.MIN_QT_STD) interv = Iv(int(rtmean - 2.5 * maxdiff), int(rtmean + 2.5 * maxdiff)) #We avoid possible inconsistencies with constraint introduced by #the rhythm information. try: existing = tnet.get_constraint(qrs.time, twave.end).constraint except KeyError: existing = Iv(-np.inf, np.inf) if interv.overlap(existing): tnet.add_constraint(qrs.time, twave.end, interv)
def test_set_before(self): v0, v1 = [Interval(-1, x) for x in range(2)] nw = ConstraintNetwork() nw.set_before(v0, v1) nw.minimize_network() assert v0 < v1 assert v0.start == v1.start assert v0.start == -1 nw.set_before(v1, v0) nw.minimize_network() assert v0 == v1 assert v0 == v1 assert v0.start == -1
def test_deep_copy(self): var1 = Interval(10, 150) var2 = copy.deepcopy(var1) var3 = copy.deepcopy(var1) assert var1 is not var2 and var1 is not var3 assert var1 == var2 and var1 == var3 assert var1 == var2 == var3 assert var2 is not var3 assert var2 == var3 assert var1 is not var2 and var1 is not var3 assert var1 == var2 and var1 == var3 assert var2 is not var3 assert var2 == var3
def test_hull(self): inter1 = Interval(0, 10) inter2 = Interval(15, 20) inter = inter1.hull(inter2) assert inter.start == 0 assert inter.end == 20 inter = inter2.hull(inter1) assert inter.start == 0 assert inter.end == 20
def test_deep_copy(self): var1 = Variable(Interval(10, 150)) var2 = copy.deepcopy(var1) var3 = copy.deepcopy(var1) assert var1 is not var2 and var1 is not var3 assert var1 == var2 and var1 == var3 assert var2 is not var3 assert var2 == var3 assert var1.value is not var2.value and var1.value is not var3.value assert var1.value == var2.value and var1.value == var3.value assert var2.value is not var3.value assert var2.value == var3.value assert hash(var1.value) == hash(var2.value) == hash(var3.value) assert hash(var1.value) is hash(var1.value) is hash(var3.value) assert hash(var1) != hash(var2) and hash(var1) != hash(var3) assert hash(var2) != hash(var3)
def test_between(self): v0 = Interval(0, 10) v1 = Interval(7, 15) v2 = Interval(4, 10) nw = ConstraintNetwork() nw.set_between(v0, v1, v2) nw.minimize_network() assert v0 <= v1 <= v2 v0 = Interval(0, 10) v1 = Interval(7, 15) v2 = Interval(4, 10) nw = ConstraintNetwork() nw.set_between(v2, v1, v0) nw.minimize_network() assert v2 <= v1 <= v0
def test_zero_in(self): inter1 = Interval(-6, 2) assert inter1.zero_in inter1 = Interval(0, 2) assert inter1.zero_in inter1 = Interval(-4, 0) assert inter1.zero_in inter1 = Interval(6, 10) assert not inter1.zero_in inter1 = Interval(-10, -3) assert not inter1.zero_in inter1 = Interval(float("-inf"), float("inf")) assert inter1.zero_in
def test_ordering(self): var1 = Interval(0, 15) var2 = var1.move(5) assert var1 < var2 assert var1 != var2 var2 = var1.move(-5) assert var1 > var2 assert var1 != var2 var2 = Interval(0, 5) assert var1 > var2 assert var1 != var2 var2 = Interval(0, 20) assert var1 < var2 assert var1 != var2 var2 = Interval(0, 15) assert var1 == var2 assert tuple(var1) == tuple(var2) assert not var1 < var2 assert not var1 > var2
def test_properties(self): inter = Interval(0, 15) var = Variable(inter) assert var.start == 0 assert var.end == 15
def test_add_constraint(self): # Known example assertion (Detcher STP example in TCN paper) v0, v1, v2, v3, v4 = [Interval(-np.inf, np.inf) for _ in range(5)] v0.set(0, 0) nw = ConstraintNetwork() nw.add_constraint(v0, v1, Interval(10, 20)) nw.add_constraint(v1, v2, Interval(30, 40)) nw.add_constraint(v3, v2, Interval(10, 20)) nw.add_constraint(v3, v4, Interval(40, 50)) nw.add_constraint(v0, v4, Interval(60, 70)) nw.minimize_network() assert v0 == Interval(0, 0) assert v1 == Interval(10, 20) assert v2 == Interval(40, 50) assert v3 == Interval(20, 30) assert v4 == Interval(60, 70) assert tuple(v0) == (0, 0) assert tuple(v1) == (10, 20) assert tuple(v2) == (40, 50) assert tuple(v3) == (20, 30) assert tuple(v4) == (60, 70) # Testing if a stricker constraint is applied v0, v1, v2, v3, v4 = [Interval(-np.inf, np.inf) for _ in range(5)] v0.set(0, 0) nw = ConstraintNetwork() nw.add_constraint(v0, v1, Interval(10, 20)) nw.add_constraint(v1, v2, Interval(30, 40)) nw.add_constraint(v3, v2, Interval(10, 20)) nw.add_constraint(v3, v4, Interval(40, 50)) nw.add_constraint(v0, v4, Interval(60, 70)) nw.add_constraint(v0, v1, Interval(10, 15)) nw.add_constraint(v1, v2, Interval(30, 35)) nw.add_constraint(v3, v2, Interval(10, 15)) nw.add_constraint(v3, v4, Interval(40, 45)) nw.add_constraint(v0, v4, Interval(60, 65)) nw.minimize_network() assert v0 == Interval(0, 0) assert v1 == Interval(10, 10) assert v2 == Interval(40, 40) assert v3 == Interval(25, 25) assert v4 == Interval(65, 65)
def test_add_constraint(self): # Known example assertion (Detcher STP example in TCN paper) v0, v1, v2, v3, v4 = [Variable() for _ in range(5)] v0.value = Interval(0, 0) nw = ConstraintNetwork() nw.add_constraint(v0, v1, Interval(10, 20)) nw.add_constraint(v1, v2, Interval(30, 40)) nw.add_constraint(v3, v2, Interval(10, 20)) nw.add_constraint(v3, v4, Interval(40, 50)) nw.add_constraint(v0, v4, Interval(60, 70)) nw.minimize_network() assert v0.value == Interval(0, 0) assert v1.value == Interval(10, 20) assert v2.value == Interval(40, 50) assert v3.value == Interval(20, 30) assert v4.value == Interval(60, 70) # Testing if a stricker constraint is applied v0, v1, v2, v3, v4 = [Variable() for _ in range(5)] v0.value = Interval(0, 0) nw = ConstraintNetwork() nw.add_constraint(v0, v1, Interval(10, 20)) nw.add_constraint(v1, v2, Interval(30, 40)) nw.add_constraint(v3, v2, Interval(10, 20)) nw.add_constraint(v3, v4, Interval(40, 50)) nw.add_constraint(v0, v4, Interval(60, 70)) nw.add_constraint(v0, v1, Interval(10, 15)) nw.add_constraint(v1, v2, Interval(30, 35)) nw.add_constraint(v3, v2, Interval(10, 15)) nw.add_constraint(v3, v4, Interval(40, 45)) nw.add_constraint(v0, v4, Interval(60, 65)) nw.minimize_network() assert v0.value == Interval(0, 0) assert v1.value == Interval(10, 10) assert v2.value == Interval(40, 40) assert v3.value == Interval(25, 25) assert v4.value == Interval(65, 65)
def test_overlapm(self): inter1 = Interval(0, 10) inter2 = Interval(15, 20) assert not inter1.overlapm(inter2) assert not inter2.overlapm(inter1) assert inter1.overlapm(inter1) assert inter2.overlapm(inter2) inter2 = Interval(-6, 0) assert inter1.overlapm(inter2) assert inter2.overlapm(inter1) inter2 = Interval(-6, 5) assert inter1.overlapm(inter2) assert inter2.overlapm(inter1) inter2 = Interval(10, 15) assert inter1.overlapm(inter2) assert inter2.overlapm(inter1) inter2 = Interval(4, 15) assert inter1.overlapm(inter2) assert inter2.overlapm(inter1)
def test_contains(self): inter = Interval(0, 100) x = list(range(101)) assert all([k in inter for k in x])
def test_properties(self): var = Interval(0, 15) assert var.start == 0 assert var.end == 15
def test_ordering(self): inter1 = Interval(0, 10) inter2 = Interval(10, 15) assert inter1 < inter2 assert not inter1 > inter2 assert inter1 != inter2 inter2 = Interval(0, 10) assert inter1 == inter2 assert not inter1 < inter2 assert not inter1 > inter2 inter2 = Interval(0, 5) assert inter1 > inter2 assert inter1 != inter2 assert not inter1 < inter2 inter2 = Interval(0, 15) assert inter1 < inter2 assert inter1 != inter2 assert tuple(inter1) != tuple(inter2) assert not inter1 > inter2 inter2 = Interval(-5, 10) assert inter1 > inter2 assert not inter1 < inter2 assert inter1 != inter2 inter2 = Interval(5, 10) assert inter1 < inter2 assert not inter1 > inter2 assert inter1 != inter2 inter2 = Interval(-5, 6) assert inter1 > inter2 assert not inter1 < inter2 assert inter1 != inter2 inter2 = Interval(5, 6) assert inter1 < inter2 assert not inter1 > inter2 assert inter1 != inter2 inter2 = Interval(-5, 15) assert inter1 > inter2 assert not inter1 < inter2 assert inter1 != inter2 inter2 = Interval(5, 15) assert inter1 < inter2 assert not inter1 > inter2 assert inter1 != inter2 inter2 = None assert not inter1 < inter2 assert inter1 != inter2
def test_separation(self): inter1 = Interval(0, 3) inter2 = Interval(7, 10) assert inter1.separation(inter2) == 4 assert inter2.separation(inter1) == 4 inter1 = Interval(3, 5) inter2 = Interval(3, 7) assert inter1.separation(inter2) == 0 assert inter2.separation(inter1) == 0 inter1 = Interval(3, 5) inter2 = Interval(0, 5) assert inter1.separation(inter2) == 0 assert inter2.separation(inter1) == 0 inter1 = Interval(3, 5) inter2 = Interval(float("inf"), float("inf")) assert inter1.separation(inter2) == float("inf") assert inter2.separation(inter1) == float("inf") inter1 = Interval(3, 5) inter2 = Interval(float("-inf"), float("-inf")) assert inter1.separation(inter2) == float("inf") assert inter2.separation(inter1) == float("inf")
def test_singleton(self): inter = Interval(0, 1) assert inter.singleton inter = Interval(1, 3) assert not inter.singleton
def test_empty(self): inter = Interval(1, 1) assert inter.empty inter = Interval(-1, 1) assert not inter.empty
def test_basic_properties(self): inter = Interval(-1, 1) assert inter.start == -1 assert inter.end == 1 assert inter.length == 2
def test_intersection(self): inter1 = Interval(0, 10) inter2 = Interval(15, 20) inter = inter1.intersection(inter2) assert inter.empty assert inter.start == 0 inter = inter2.intersection(inter1) assert inter.empty assert inter.start == 0 inter2 = Interval(5, 15) inter = inter2.intersection(inter1) assert inter.start == 5 assert inter.end == 10 inter = inter1.intersection(inter2) assert inter.start == 5 assert inter.end == 10 inter2 = Interval(10, 15) inter = inter1.intersection(inter2) assert inter.empty inter = inter2.intersection(inter1) assert inter.empty inter2 = Interval(-1, 0) inter = inter1.intersection(inter2) assert inter.empty inter = inter2.intersection(inter1) assert inter.empty
def test_proper_subset(self): inter1 = Interval(0, 10) inter2 = Interval(4, 6) assert not inter1.proper_subset(inter2) assert inter2.proper_subset(inter1) inter2 = Interval(6, 12) assert not inter2.proper_subset(inter1) inter2 = Interval(-6, 5) assert not inter2.proper_subset(inter1) inter1 = Interval(float("-inf"), float("inf")) assert inter2.proper_subset(inter1)