/* Entry for the Physionet/CinC 2011 Challenge Benjamin E Moody */ 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; } }