Improving the Quality of ECGs Collected using Mobile Phones: The PhysioNet/Computing in Cardiology Challenge 2011 1.0.0
(5,161 bytes)
/*
Entry for the Physionet/CinC 2011 Challenge
Benjamin E Moody <benjaminmoody@gmail.com>
*/
package org.physionet.challenge2011;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
public class ChallengeEntry
{
/* Number of signals */
private static final int NUMSIG = 12;
/* Length of input record (number of samples) */
private static final int NUMSAMP = 5000;
/* Maximum number of consecutive constant samples */
private static final int MAX_CONSTANT_INTERVAL = 100;
/* Maximum overall range of each signal */
private static final int MAX_SIGNAL_PEAK = 3000;
/* Minimum overall range of each signal */
private static final int MIN_SIGNAL_PEAK = 40;
/* Size of window to check for "quiet" sections */
private static final int QUIET_WINDOW_SIZE = 32;
/* Largest change within a window considered "quiet" */
private static final int QUIET_THRESHOLD = 20;
/* Minimum number of quiet windows */
private static final int MIN_QUIET_WINDOWS = 200;
/* Maximum number of quiet windows */
private static final int MAX_QUIET_WINDOWS = 300;
synchronized public int get_result(InputStream iFile, final ECG_MetaData m_MetaData)
throws IOException
{
ObjectInputStream in = new ObjectInputStream(iFile);
short data[];
try {
data = (short[]) in.readObject();
}
catch (ClassNotFoundException e) {
throw new IOException("bad input file");
}
short cur_local_min[] = new short[NUMSIG];
short cur_local_max[] = new short[NUMSIG];
short next_local_min[] = new short[NUMSIG];
short next_local_max[] = new short[NUMSIG];
short global_min[] = new short[NUMSIG];
short global_max[] = new short[NUMSIG];
short nconst[] = new short[NUMSIG];
short nquiet[] = new short[NUMSIG];
int badsignal = -1;
int t, i, w;
short cur_sample, prev_sample;
for (i = 0; i < NUMSIG; i++) {
cur_local_min[i] = next_local_min[i] = global_min[i] = 32767;
cur_local_max[i] = next_local_max[i] = global_max[i] = -32768;
}
w = QUIET_WINDOW_SIZE / 2;
for (t = 0; t < NUMSAMP; t++) {
w--;
for (i = 0; i < NUMSIG; i++) {
/* if signal alreay marked as bad, ignore it */
if (i == badsignal)
continue;
cur_sample = data[t * NUMSIG + i];
/* check for constant signal */
if (t > 0) {
prev_sample = data[(t-1) * NUMSIG + i];
if (cur_sample == prev_sample) {
nconst[i]++;
if (nconst[i] > MAX_CONSTANT_INTERVAL) {
if (badsignal >= 0)
return 1;
badsignal = i;
continue;
}
}
else {
nconst[i] = 0;
}
}
/* check global min/max */
if (cur_sample > global_max[i])
global_max[i] = cur_sample;
if (cur_sample < global_min[i])
global_min[i] = cur_sample;
/* local min/max */
if (cur_sample > cur_local_max[i])
cur_local_max[i] = next_local_max[i] = cur_sample;
else if (cur_sample > next_local_max[i])
next_local_max[i] = cur_sample;
if (cur_sample < cur_local_min[i])
cur_local_min[i] = next_local_min[i] = cur_sample;
else if (cur_sample < next_local_min[i])
next_local_min[i] = cur_sample;
if (w == 0) {
if (cur_local_max[i] - cur_local_min[i] <= QUIET_THRESHOLD)
nquiet[i]++;
cur_local_min[i] = 32767;
cur_local_max[i] = -32768;
}
}
if (w == 0) {
w = QUIET_WINDOW_SIZE / 2;
short tmp[] = cur_local_min;
cur_local_min = next_local_min;
next_local_min = tmp;
tmp = cur_local_max;
cur_local_max = next_local_max;
next_local_max = tmp;
}
}
for (i = 0; i < NUMSIG; i++) {
if (i == badsignal)
continue;
if (nquiet[i] < MIN_QUIET_WINDOWS || nquiet[i] > MAX_QUIET_WINDOWS)
break;
}
if (i == NUMSIG)
return 0;
for (i = 0; i < NUMSIG; i++) {
if (i == badsignal)
continue;
if (global_max[i] - global_min[i] > MAX_SIGNAL_PEAK
|| global_max[i] - global_min[i] < MIN_SIGNAL_PEAK) {
if (badsignal >= 0)
return 1;
badsignal = i;
}
}
return 0;
}
}