From 3c70142c155f0fcd6ed50cb690d7ba25217575a5 Mon Sep 17 00:00:00 2001 From: Pritimay Sarkar Date: Wed, 15 Nov 2023 14:18:01 +0530 Subject: [PATCH] check deoxygenation and classify with abs --- .../hpostesting/data/constant/Constants.kt | 15 ++++ .../hpostesting/data/dao/MyDataBase.kt | 2 +- .../data/model/patient/HemoCubeTestData.kt | 8 +- .../presentation/hemocube/HemoCubeFragment.kt | 89 ++++++++++++++++--- .../hemocube/HemoCubeViewModel.kt | 6 ++ 5 files changed, 107 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt index 3183d9e..0de92e7 100644 --- a/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt +++ b/app/src/main/java/com/example/hpostesting/data/constant/Constants.kt @@ -77,4 +77,19 @@ object Constants { const val BUFFER_LED_LOWER_BOUND = 21000 const val BUFFER_LED_UPPER_BOUND = 24500 + + val DEVICE_CONFIGURATION: Map>> = mapOf>>( + "HCV-000-3001" to listOf( + listOf(1.264817, -0.85965), // LED1 + listOf(0.581462456, -0.58502), // LED2 + listOf(0.184991, 0.184991), // LED3 + listOf(1.0, 0.0) // LED4 + ), + "HCV-000-3002" to listOf( + listOf(1.264817, -0.85965), // LED1 + listOf(0.581462456, -0.58502), // LED2 + listOf(0.184991, 0.184991), // LED3 + listOf(1.0, 0.0) // LED4 + ), + ) } \ No newline at end of file diff --git a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt index 339d58d..05de1a3 100644 --- a/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt +++ b/app/src/main/java/com/example/hpostesting/data/dao/MyDataBase.kt @@ -11,7 +11,7 @@ import com.example.hpostesting.data.model.patient.HemoCubeTestData import com.google.android.datatransport.runtime.dagger.Provides import javax.inject.Singleton -@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 5, exportSchema = false) +@Database(entities = [UserData::class, HemoCubeTestData::class, DeviceData::class], version = 8, exportSchema = false) @TypeConverters(Converters::class) abstract class MyDatabase : RoomDatabase() { abstract fun userDao(): UserDao diff --git a/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt b/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt index fc61162..ca9c9ad 100644 --- a/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt +++ b/app/src/main/java/com/example/hpostesting/data/model/patient/HemoCubeTestData.kt @@ -36,8 +36,14 @@ data class HemoCubeTestData( var led2Average: Double? = null, var led3Average: Double? = null, var led4Average: Double? = null, + var abs1: Double? = null, + var abs2: Double? = null, + var abs3: Double? = null, + var abs4: Double? = null, var deviceRatio: Double? = null, var calculatedRatio: Double? = null, + var predictedDenovixRatio: Double? = null, var coefficients: String? = "", - var classificationResult: String = "" + var classificationResult: String = "", + var prdClassification: String = "", ) diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt index 09ab5b1..bf6e7bf 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeFragment.kt @@ -49,7 +49,13 @@ class HemoCubeFragment : Fragment() { private var led2SampleForDevice = 0.0 private var led3SampleForDevice = 0.0 private var led4SampleForDevice = 0.0 + private var fittedAbs1 = 0.0 + private var fittedAbs2 = 0.0 + private var fittedAbs3 = 0.0 + private var fittedAbs4 = 0.0 + private var _predictedDenovixRatio = 0.0 private var validationError = false + private var deviceHardwareId = "" override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, @@ -285,6 +291,7 @@ class HemoCubeFragment : Fragment() { val slData = stringData.split(" ") if (slData.size > 1) { val hardwareId = slData[1].trim() + deviceHardwareId = hardwareId with(sharedPreferences.edit()) { putString(Constants.DEVICE_ID, hardwareId) apply() @@ -321,8 +328,10 @@ class HemoCubeFragment : Fragment() { } resultData.contains("REND") -> { - hemoCubeViewModel.messages.postValue("Data collected \n" + - " Processing data") + hemoCubeViewModel.messages.postValue( + "Data collected \n" + + " Processing data" + ) val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex()) var bufferIntensity = resultLines[1].split(' ')[1].trim() led1BufferForDevice = if (isUsingExistingBuffer) { @@ -408,14 +417,6 @@ class HemoCubeFragment : Fragment() { val led4Average = log10(led4BufferForDevice?.div(led4SampleForDevice!!) ?: 0.0) val deviceRatio = led3Average / led1Average - if (led1Average < 0 || led2Average < 0 || led3Average < 0 || led4Average < 0) { - validationError = true - activity?.runOnUiThread { - binding.errorMessage.text = "Error: Negative Abs. Retake Blank Reading" - binding.errorMessage.visibility = View.VISIBLE - } - } - if (led1BufferForDevice < Constants.BUFFER_LED_LOWER_BOUND || led2BufferForDevice < Constants.BUFFER_LED_LOWER_BOUND || led3BufferForDevice < Constants.BUFFER_LED_LOWER_BOUND @@ -435,7 +436,42 @@ class HemoCubeFragment : Fragment() { ) { validationError = true activity?.runOnUiThread { - binding.errorMessage.text = "Error: Invalid Test. Improper buffer reading (high)" + binding.errorMessage.text = + "Error: Invalid Test. Improper buffer reading (high)" + binding.errorMessage.visibility = View.VISIBLE + } + } + + var gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(0) + var constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(0)?.get(1) + fittedAbs1 = gradient?.times(led1Average)?.plus(constant!!)!! + + gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(1)?.get(0) + constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(1)?.get(1) + fittedAbs2 = gradient?.times(led2Average)?.plus(constant!!)!! + + gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(2)?.get(0) + constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(2)?.get(1) + fittedAbs3 = gradient?.times(led3Average)?.plus(constant!!)!! + + gradient = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(3)?.get(0) + constant = Constants.DEVICE_CONFIGURATION[deviceHardwareId]?.get(3)?.get(1) + fittedAbs4 = gradient?.times(led4Average)?.plus(constant!!)!! + + _predictedDenovixRatio = fittedAbs3?.div(fittedAbs1!!)!! + + if (fittedAbs1!! <= fittedAbs2!!) { + validationError = true + activity?.runOnUiThread { + binding.errorMessage.text = "Error: Invalid Test. Problem with de-oxygenation" + binding.errorMessage.visibility = View.VISIBLE + } + } + + if (led1Average < 0 || led2Average < 0 || led3Average < 0 || led4Average < 0) { + validationError = true + activity?.runOnUiThread { + binding.errorMessage.text = "Error: Negative Abs. Retake Blank Reading" binding.errorMessage.visibility = View.VISIBLE } } @@ -455,11 +491,17 @@ class HemoCubeFragment : Fragment() { this.led2Average = led2Average this.led3Average = led3Average this.led4Average = led4Average + this.abs1 = fittedAbs1 + this.abs2 = fittedAbs2 + this.abs3 = fittedAbs3 + this.abs4 = fittedAbs4 this.deviceRatio = deviceRatio this.calculatedRatio = calculateRatio(deviceRatio) + this.predictedDenovixRatio = _predictedDenovixRatio this.coefficients = currentDeviceData?.coefficients?.get(0) .toString() + ", " + currentDeviceData?.coefficients?.get(1).toString() this.classificationResult = findResult(calculatedRatio) + this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio) hemoCubeViewModel.messages.postValue(this.classificationResult) this.resultData = deviceLog if (!isUsingExistingBuffer) { @@ -519,6 +561,31 @@ class HemoCubeFragment : Fragment() { return "INVALID" } + private fun absorbanceBasedClassification(predictedDenovixRatio: Double?): String { + try { + hemoCubeViewModel.messages.postValue("result classification") + if (predictedDenovixRatio != null) { + if (predictedDenovixRatio in 0.0..0.16) + return "Normal" + if (predictedDenovixRatio in 0.16..0.165) + return "Negative Borderline" + if (predictedDenovixRatio in 0.165..0.235) + return "Sickle Cell Trait" + if (predictedDenovixRatio in 0.235..0.24) + return "Positive Borderline" + if (predictedDenovixRatio in 0.24..1.0) + return "Sickle Cell Disease" + } else { + return "INVALID" + } + } catch (e: Exception) { + showToast("error while performing classification") + Firebase.crashlytics.recordException(e) + return "ERROR" + } + return "INVALID" + } + private fun showToast(message: String) { Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() } diff --git a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt index f532276..7b9679f 100644 --- a/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt +++ b/app/src/main/java/com/example/hpostesting/presentation/hemocube/HemoCubeViewModel.kt @@ -106,10 +106,16 @@ class HemoCubeViewModel @Inject constructor( testDetails?.led2Average = DataHolder.hemoCubeTestData?.led2Average testDetails?.led3Average = DataHolder.hemoCubeTestData?.led3Average testDetails?.led4Average = DataHolder.hemoCubeTestData?.led4Average + testDetails?.abs1 = DataHolder.hemoCubeTestData?.abs1 + testDetails?.abs2 = DataHolder.hemoCubeTestData?.abs2 + testDetails?.abs3 = DataHolder.hemoCubeTestData?.abs3 + testDetails?.abs4 = DataHolder.hemoCubeTestData?.abs4 testDetails?.deviceRatio = DataHolder.hemoCubeTestData?.deviceRatio + testDetails?.predictedDenovixRatio = DataHolder.hemoCubeTestData?.predictedDenovixRatio testDetails?.calculatedRatio = DataHolder.hemoCubeTestData?.calculatedRatio testDetails?.coefficients = DataHolder.hemoCubeTestData?.coefficients testDetails?.classificationResult = DataHolder.hemoCubeTestData?.classificationResult!! + testDetails?.prdClassification = DataHolder.hemoCubeTestData?.prdClassification.toString() } private fun addResultTestToDb() {