-
Notifications
You must be signed in to change notification settings - Fork 27
Description
Dear George,
I am studying the code in the rxr.c app, and in particularly the find_longest_run function, which includes the following while-loop to "find the first annotation at or beyond t0":
find_longest_run(a, t0, t1, type)
unsigned int a;
WFDB_Time t0, t1;
int type; /* 0: find VE run; 1: find SVE run */
{
int am, len = 0, len0 = 0;
/* If a VF (AF) episode started before t0 and ends after t0, simply return
6 (the maximum run length considered by this program). */
if (f_end < 0L || f_end > t0) return (6);
/* If there are no more annotations for annotator a, simply return 0. */
if (annot[a].time < 0L) return (0);
/* Otherwise, find the first annotation at or beyond t0. */
while (annot[a].time < t0) {
if ((type == 0 && amap(annot[a], a) == '[') ||
(type == 1 && amap(annot[a], a) == '{')) { /* VF (AF) begins */
do {
if (getann(a, &annot[a]) < 0) {
/* If the annotation file ends without an annotation to
indicate the end of VF (AF), assume that the VF (AF)
continues to the end of the record (setting the value
of f_end less than zero signals this), and return 6
(the maximum run length) since the VF (AF) overlaps the
window. */
f_end = -1L;
return (6);
}
am = amap(annot[a], a);
} while ((type == 0 && am != ']' && am != '{' && am != 'U') ||
(type == 1 && am != '}' && am != '[' && am != 'U'));
if (annot[a].time > t0) {
/* If the episode overlaps the window, record when it ends
and return the maximum run length. */
f_end = annot[a].time;
return (6);
}
}
/* Now count consecutive (S)VEBs in the window. */
while (annot[a].time <= t1) {
switch(amap(annot[a], a)) {
...
Consider a SVEB (type=1) scenario iterating an AF episode involving the following steps:
-
The loop has started iterating in the AF episode but is interrupted by
am=='U'(unreadable) due to a localised disturbance. The time up till the shutdown is recorded inf_endand theinaf[a]is still 1 when the loop returns a SVEB run length of (6). -
Next time
find_longest_runis called again witht0 > f_end(hencet0is after the disturbance), the rhythm is still AF (andinaf[a]is 1), but there is no AF start marker{so the loop exits whenannot[a].time >= t0and continues below. Howevert1 < t0because therun_startin the other annotation set is defined by an AF start marker (and norun_endvalue is set). Hence, thefind_longest_runfunction will return a (0) length run.
The implication is that the SVEB run length is reported as six before the disturbance/shutdown and zero thereafter, throughout the length of the AF episode, even though the rhythm is still AF after the disturbance.
Of course, same goes for a VEB (type=0) scenario when iterating an VF episode.
The above described scenario is a rather common and happens in multiple MIT-BIH records.
Maybe it would be better to apply the same approach before and after the disturbance (as the fibrillation rhythm remains), so just ignore the unreadable annotations and continue when the disturbance has passed, i.e., when amap(annot[a], a) == 'C'.
Hence, the condition
if ((type == 0 && amap(annot[a], a) == '[') ||
(type == 1 && amap(annot[a], a) == '{')) { /* VF (AF) begins */
is extended to
if ((type == 0 && amap(annot[a], a) == '[') ||
(type == 1 && amap(annot[a], a) == '{') ||
(amap(annot[a], a) == 'C' && (invf[a] || inaf[a]))) { /* VF (AF) begins or continues */
I hope that you can follow my reasoning, otherwise I may be able to provide a more detailed example.
Sincerely,
Jacob