Added settings to enable the original OSD or the new neural network algorithms (or both). Display the seizure probability from the neural network on the main screen. Add seizure probability to the data stored with the datapoints in the database.
This commit is contained in:
@@ -709,10 +709,14 @@ public class MainActivity extends AppCompatActivity {
|
||||
} else
|
||||
specRatio = 0;
|
||||
|
||||
long pSeizurePc;
|
||||
pSeizurePc = (long)(mConnection.mSdServer.mSdData.mPseizure * 100);
|
||||
Log.d(TAG,"pSeizurePc="+pSeizurePc+", mPseizure="+mConnection.mSdServer.mSdData.mPseizure);
|
||||
((TextView) findViewById(R.id.powerTv)).setText(getString(R.string.PowerEquals) + mConnection.mSdServer.mSdData.roiPower +
|
||||
" (" + getString(R.string.Threshold) + "=" + mConnection.mSdServer.mSdData.alarmThresh + ")");
|
||||
((TextView) findViewById(R.id.spectrumTv)).setText(getString(R.string.SpectrumRatioEquals) + specRatio +
|
||||
" (" + getString(R.string.Threshold) + "=" + mConnection.mSdServer.mSdData.alarmRatioThresh + ")");
|
||||
((TextView) findViewById(R.id.pSeizureTv)).setText("Seizure Probability = "+pSeizurePc+"%");
|
||||
|
||||
ProgressBar pb;
|
||||
Drawable pbDrawable;
|
||||
@@ -740,6 +744,18 @@ public class MainActivity extends AppCompatActivity {
|
||||
//pb.getProgressDrawable().setColorFilter(colour, PorterDuff.Mode.SRC_IN);
|
||||
pb.setProgressDrawable(pbDrawable);
|
||||
|
||||
pb = ((ProgressBar) findViewById(R.id.pSeizureProgressBar));
|
||||
pb.setMax(100);
|
||||
pb.setProgress((int) pSeizurePc);
|
||||
pbDrawable = getResources().getDrawable(R.drawable.progress_bar_blue);
|
||||
if (pSeizurePc > 30)
|
||||
pbDrawable = getResources().getDrawable(R.drawable.progress_bar_yellow);
|
||||
if (pSeizurePc > 50)
|
||||
pbDrawable = getResources().getDrawable(R.drawable.progress_bar_red);
|
||||
//pb.getProgressDrawable().setColorFilter(colour, PorterDuff.Mode.SRC_IN);
|
||||
pb.setProgressDrawable(pbDrawable);
|
||||
|
||||
|
||||
|
||||
// Fault Conditions - We override the values in the UI because we do not know
|
||||
// if the stored ones are correct or not with a fault present.
|
||||
|
||||
@@ -66,7 +66,7 @@ public class SdAlgNn {
|
||||
interpreter.close();
|
||||
}
|
||||
|
||||
public int run(SdData sdData) {
|
||||
public float getPseizure(SdData sdData) {
|
||||
int i;
|
||||
float[][][] modelInput = new float[1][125][1];
|
||||
float[][] modelOutput = new float[1][2];
|
||||
@@ -75,9 +75,6 @@ public class SdAlgNn {
|
||||
}
|
||||
interpreter.run(modelInput, modelOutput);
|
||||
Log.d(TAG,"run - pSeizure="+modelOutput[0][1]);
|
||||
if (modelOutput[0][1]>0.5)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return(modelOutput[0][1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,11 @@ import org.json.JSONArray;
|
||||
public class SdData implements Parcelable {
|
||||
private final static String TAG = "SdData";
|
||||
private final static int N_RAW_DATA = 500; // 5 seconds at 100 Hz.
|
||||
|
||||
// Seizure Detection Algorithm Selection
|
||||
public boolean mOsdAlarmActive;
|
||||
public boolean mCnnAlarmActive;
|
||||
|
||||
/* Analysis settings */
|
||||
public String phoneAppVersion = "";
|
||||
public boolean haveSettings = false; // flag to say if we have received settings or not.
|
||||
@@ -107,6 +112,7 @@ public class SdData implements Parcelable {
|
||||
public boolean mO2SatFaultStanding = false;
|
||||
public double mO2Sat = 0;
|
||||
|
||||
public double mPseizure = 0.;
|
||||
|
||||
public SdData() {
|
||||
simpleSpec = new int[10];
|
||||
@@ -196,6 +202,7 @@ public class SdData implements Parcelable {
|
||||
jsonObj.put("alarmPhrase", alarmPhrase);
|
||||
jsonObj.put("hr", mHR);
|
||||
jsonObj.put("o2Sat", mO2Sat);
|
||||
jsonObj.put("pSeizure", mPseizure);
|
||||
JSONArray arr = new JSONArray();
|
||||
for (int i = 0; i < simpleSpec.length; i++) {
|
||||
arr.put(simpleSpec[i]);
|
||||
@@ -247,6 +254,8 @@ public class SdData implements Parcelable {
|
||||
jsonObj.put("alarmFreqMax", alarmFreqMax);
|
||||
jsonObj.put("alarmThresh", alarmThresh);
|
||||
jsonObj.put("alarmRatioThresh", alarmRatioThresh);
|
||||
jsonObj.put("osdAlarmActive", mOsdAlarmActive);
|
||||
jsonObj.put("cnnAlarmActive", mCnnAlarmActive);
|
||||
jsonObj.put("hrAlarmActive", mHRAlarmActive);
|
||||
jsonObj.put("hrAlarmStanding", mHRAlarmStanding);
|
||||
jsonObj.put("hrThreshMin", mHRThreshMin);
|
||||
|
||||
@@ -220,6 +220,8 @@ public abstract class SdDataSource {
|
||||
mUtil.writeToSysLogFile("SDDataSource.stop() - error - " + e.toString());
|
||||
}
|
||||
|
||||
mSdAlgNn.close();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -485,9 +487,12 @@ public abstract class SdDataSource {
|
||||
mWatchAppRunningCheck = false;
|
||||
}
|
||||
|
||||
// Use the neural network algorithm to calculate the probability of the data
|
||||
// being representative of a seizure (sets mSdData.mPseizure)
|
||||
nnAnalysis();
|
||||
|
||||
// Check this data to see if it represents an alarm state.
|
||||
alarmCheck();
|
||||
nnCheck();
|
||||
hrCheck();
|
||||
o2SatCheck();
|
||||
fallCheck();
|
||||
@@ -505,16 +510,23 @@ public abstract class SdDataSource {
|
||||
* Sets mSdData.alarmState and mSdData.hrAlarmStanding
|
||||
*/
|
||||
private void alarmCheck() {
|
||||
boolean inAlarm;
|
||||
boolean inAlarm = false;
|
||||
// Avoid potential divide by zero issue
|
||||
if (mSdData.specPower == 0)
|
||||
mSdData.specPower = 1;
|
||||
Log.v(TAG, "alarmCheck() - roiPower="+mSdData.roiPower+" specPower="+ mSdData.specPower+" ratio="+10*mSdData.roiPower/ mSdData.specPower);
|
||||
|
||||
if (mSdData.mOsdAlarmActive) {
|
||||
// Is the current set of data representing an alarm state?
|
||||
if ((mSdData.roiPower > mAlarmThresh) && ((10 * mSdData.roiPower / mSdData.specPower) > mAlarmRatioThresh)) {
|
||||
inAlarm = true;
|
||||
} else {
|
||||
inAlarm = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mSdData.mCnnAlarmActive) {
|
||||
if (mSdData.mPseizure > 0.5) {
|
||||
inAlarm = true;
|
||||
}
|
||||
}
|
||||
|
||||
// set the alarmState to Alarm, Warning or OK, depending on the current state and previous ones.
|
||||
@@ -728,11 +740,12 @@ public abstract class SdDataSource {
|
||||
}
|
||||
}
|
||||
|
||||
void nnCheck() {
|
||||
void nnAnalysis() {
|
||||
//Check the current set of data using the neural network model to look for alarms.
|
||||
Log.d(TAG,"nnCheck");
|
||||
int nnResult = mSdAlgNn.run(mSdData);
|
||||
Log.d(TAG,"nnCheck - nnResult="+nnResult);
|
||||
Log.d(TAG,"nnAnalysis");
|
||||
float pSeizure = mSdAlgNn.getPseizure(mSdData);
|
||||
Log.d(TAG,"nnAnalysis - nnResult="+pSeizure);
|
||||
mSdData.mPseizure = pSeizure;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -873,6 +886,15 @@ public abstract class SdDataSource {
|
||||
Log.v(TAG, "updatePrefs() FallWindow = " + mFallWindow);
|
||||
mUtil.writeToSysLogFile( "updatePrefs() FallWindow = " + mFallWindow);
|
||||
|
||||
mSdData.mOsdAlarmActive = SP.getBoolean("OsdAlarmActive", false);
|
||||
Log.v(TAG, "updatePrefs() OsdAlarmActive = " + mSdData.mOsdAlarmActive);
|
||||
mUtil.writeToSysLogFile( "updatePrefs() OsdAlarmActive = " + mSdData.mOsdAlarmActive);
|
||||
|
||||
mSdData.mCnnAlarmActive = SP.getBoolean("CnnAlarmActive", false);
|
||||
Log.v(TAG, "updatePrefs() CnnAlarmActive = " + mSdData.mCnnAlarmActive);
|
||||
mUtil.writeToSysLogFile( "updatePrefs() CnnAlarmActive = " + mSdData.mCnnAlarmActive);
|
||||
|
||||
|
||||
mSdData.mHRAlarmActive = SP.getBoolean("HRAlarmActive", false);
|
||||
Log.v(TAG, "updatePrefs() HRAlarmActive = " + mSdData.mHRAlarmActive);
|
||||
mUtil.writeToSysLogFile( "updatePrefs() HRAlarmActive = " + mSdData.mHRAlarmActive);
|
||||
|
||||
@@ -119,6 +119,21 @@
|
||||
android:indeterminate="false"
|
||||
android:minHeight="20dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pSeizureTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Seizure Probability (%)" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pSeizureProgressBar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="false"
|
||||
android:minHeight="20dp" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -438,4 +438,8 @@
|
||||
<string name="not_logged_in_dialog_title">Not Logged in to Data Sharing</string>
|
||||
<string name="not_logged_in_dialog_message">You must be logged in to the Data Sharing system to be able to report seizures.</string>
|
||||
<string name="include_warnings">Include Warnings</string>
|
||||
<string name="OsdAlarmEnabledSummary">Enable the original deterministic OpenSeizureDetector Algorithm to generate alarms.</string>
|
||||
<string name="OsdAlarmEnabledTitle">Enable Original OSD Algorithm</string>
|
||||
<string name="CnnAlarmEnabledTitle">Enable AI (Neural Network) Algorithm</string>
|
||||
<string name="CnnAlarmEnabledSummary">Enable the Artificial Intelligence (Neural Network) algorithm to generate alarms.</string>
|
||||
</resources>
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory android:title="@string/SeizureDetectorSettingsTitle">
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="OsdAlarmActive"
|
||||
android:summary="@string/OsdAlarmEnabledSummary"
|
||||
android:title="@string/OsdAlarmEnabledTitle" />
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="CnnAlarmActive"
|
||||
android:summary="@string/CnnAlarmEnabledSummary"
|
||||
android:title="@string/CnnAlarmEnabledTitle" />
|
||||
<EditTextPreference
|
||||
android:defaultValue="5"
|
||||
android:key="WarnTime"
|
||||
|
||||
Reference in New Issue
Block a user