Improving the Quality of ECGs Collected using Mobile Phones: The PhysioNet/Computing in Cardiology Challenge 2011 1.0.0
(3,357 bytes)
package org.physionet.challenge2011;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import android.util.Log;
/* Computing in Cardiology Challenge Entry 2011
* Dieter Hayn, Bernhard Jammerbund, Guenter Schreier
* AIT Austrian Institute of Technology GmbH
* Reininghausstr. 13, 8020 Graz, Austria
* Tel.: +43 664 8157858
* EMail: dieter.hayn@ait.ac.at
*/
public class ChallengeEntry {
public static final String DEBUGTAG = ChallengeEntry.class.toString();
final static int FS= 500; //Sampling Frequency
final static int CH= 12;
final static int WIN=FS*10;
final static int START = FS*1;
//Threshold values
final static int MAX_AMP = 2000;
final static short MAX_DIFF = 400;
final static short BAD_AROUND_SPIKE = 5;
final static short MAX_WRONG_AMP = 1800;
final static short MAX_WRONG_DIFF = 1800;
final static short MAX_CONSTANT = 3600;
final static short MAX_BAD = 4000;
final static short N_X_MAX = 49;
final static short CHAN_DIST = 2000;
//Define Quality values (could also be defined as enum...)
final static int GOOD = 0;
final static int BAD = 1;
final static int AMP = 2;
final static int DIFF = 3;
final static int CONST = 4;
final static int CROSS = 5;
short[] data=new short[WIN*CH];
boolean[] good_samples = new boolean[WIN-START];
synchronized public int get_result(
InputStream iFile,
final ECG_MetaData m_MetaData)
throws IOException
{
ObjectInputStream in = new ObjectInputStream(iFile);
int result = GOOD;
try {
data = (short[])in.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e(DEBUGTAG,"Could not open data file.");
}
iFile.close();
for (int chan_i=0; chan_i<CH; chan_i++){
int n_wrong_amp = 0;
int n_wrong_diff = 0;
int n_constant = 0;
int n_bad = 0;
short n_x_this_chan = 0;
for (int i=0; i<WIN-START; i++){
good_samples[i] = true;
}
for (int i=0; i<WIN-START; i++){
short val = data[CH*(i + START) + chan_i];
short prev_val = data[CH*(i + START - 1) + chan_i];
if (Math.abs(val - prev_val) > MAX_DIFF){
for ( int j=Math.max(i-BAD_AROUND_SPIKE,0);
j<i+BAD_AROUND_SPIKE+1 && j<WIN-START;
j++)
{
if (good_samples[j]){
n_wrong_diff++;
good_samples[j] = false;
n_bad++;
}
}
} else if (Math.abs(val) > MAX_AMP){
n_wrong_amp++;
good_samples[i] = false;
n_bad++;
} else if (val == prev_val){
n_constant++;
good_samples[i] = false;
n_bad++;
}
if (n_bad > MAX_BAD){
return BAD;
}
if (n_wrong_amp > MAX_WRONG_AMP){
return AMP;
}
if (n_wrong_diff > MAX_WRONG_DIFF){
return DIFF;
}
if (n_constant > MAX_CONSTANT){
return CONST;
}
for (int sec_chan_i = chan_i+1; sec_chan_i < CH; sec_chan_i++){
int sec_val = -CHAN_DIST * (sec_chan_i-chan_i) + data[CH*(i + START) + sec_chan_i];
int sec_prev_val = -CHAN_DIST * (sec_chan_i-chan_i) + data[CH*(i + START -1) + sec_chan_i];
if (
val == sec_val ||
((prev_val < sec_prev_val) == (val > sec_val))
){
n_x_this_chan++;
}
}
if (n_x_this_chan > N_X_MAX){
return CROSS;
}
} // for i
} // for chan_i
return result;
}
}