updated preprod changes added
This commit is contained in:
@@ -74,4 +74,40 @@ object Constants {
|
||||
const val BUFFER_VALUE_3 = "BufferValue3"
|
||||
const val BUFFER_VALUE_4 = "BufferValue4"
|
||||
const val DEVICE_ID = "DEVICE_ID"
|
||||
|
||||
const val BUFFER_LED_LOWER_BOUND = 21000
|
||||
const val BUFFER_LED_UPPER_BOUND = 24500
|
||||
|
||||
val DEVICE_CONFIGURATION: Map<String, List<List<Double>>> = mapOf<String, List<List<Double>>>(
|
||||
"HCV-000-3001" to listOf(
|
||||
listOf(1.264817, -0.85965), // LED1, 435nm
|
||||
listOf(0.581462456, -0.58502), // LED2, 415nm
|
||||
listOf(0.184991, 0.001704), // LED3, 555nm
|
||||
listOf(1.0, 0.0) // LED4
|
||||
),
|
||||
"HCV-000-3002" to listOf(
|
||||
listOf(1.264817, -0.85965),
|
||||
listOf(0.581462456, -0.58502),
|
||||
listOf(0.184991, 0.001704),
|
||||
listOf(1.0, 0.0)
|
||||
),
|
||||
)
|
||||
|
||||
const val INCUBATION_TIME_MIN = 15
|
||||
const val INCUBATION_TIME_MAX = 30
|
||||
|
||||
val BUFFER_INTENSITY_THRESHOLDS: Map<String, List<List<Int>>> = mapOf<String, List<List<Int>>>(
|
||||
"HCV-000-3001" to listOf(
|
||||
listOf(24000, 24500),
|
||||
listOf(21000, 24500),
|
||||
listOf(21000, 24500),
|
||||
listOf(21000, 24500),
|
||||
),
|
||||
"HCV-000-3002" to listOf(
|
||||
listOf(21000, 24500),
|
||||
listOf(21000, 24500),
|
||||
listOf(21000, 24500),
|
||||
listOf(21000, 24500),
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -20,7 +19,6 @@ import com.example.hpostesting.data.model.patient.DeviceData
|
||||
import com.example.hpostesting.data.model.patient.toHemoCubeTestData
|
||||
import com.example.hpostesting.presentation.UsbServiceListener
|
||||
import com.example.hpostesting.presentation.dashboard.DashboardActivity
|
||||
import com.example.hpostesting.presentation.diagnostics.DiagnosticsActivity
|
||||
import com.example.hpostesting.presentation.utils.MyDialogListener
|
||||
import com.example.hpostesting.presentation.utils.UIUtils
|
||||
import com.google.firebase.crashlytics.ktx.crashlytics
|
||||
@@ -35,7 +33,7 @@ class HemoCubeFragment : Fragment() {
|
||||
private lateinit var binding: FragmentHemoCubeReferenceBinding
|
||||
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
|
||||
private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
|
||||
private var isOnline = false
|
||||
private var currentDeviceData: DeviceData? = null
|
||||
private var resultData: String = ""
|
||||
@@ -45,12 +43,19 @@ class HemoCubeFragment : Fragment() {
|
||||
private val testingTrace = Firebase.performance.newTrace("testing_trace")
|
||||
private var led1BufferForDevice = 0.0
|
||||
private var led2BufferForDevice = 0.0
|
||||
private var led3BufferForDevice = 0.0
|
||||
private var led3BufferForDevice = 0.0
|
||||
private var led4BufferForDevice = 0.0
|
||||
private var led1SampleForDevice = 0.0
|
||||
private var led2SampleForDevice = 0.0
|
||||
private var led3SampleForDevice = 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?,
|
||||
@@ -84,8 +89,8 @@ class HemoCubeFragment : Fragment() {
|
||||
binding.nameEditText.visibility = View.GONE
|
||||
binding.tvTitle.visibility = View.GONE
|
||||
binding.btnGo.visibility = View.GONE
|
||||
binding.btnSubmit.isEnabled = true
|
||||
binding.btnSubmit.isClickable = true
|
||||
binding.btnSubmit.isEnabled = false
|
||||
binding.btnSubmit.isClickable = false
|
||||
binding.btnPlacebuffer.visibility = View.GONE
|
||||
|
||||
binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}"
|
||||
@@ -94,10 +99,10 @@ class HemoCubeFragment : Fragment() {
|
||||
binding.btnSamplestart.setOnClickListener {
|
||||
activity?.runOnUiThread {
|
||||
binding.tvSubtitle4.visibility = View.VISIBLE
|
||||
binding.tvSubtitle4.text = "Sample Started"
|
||||
// binding.tvSubtitle4.text = "Sample Started"
|
||||
}
|
||||
startSampleProcess()
|
||||
it.visibility = View.GONE
|
||||
startSampleProcess()
|
||||
it.visibility = View.GONE
|
||||
}
|
||||
|
||||
binding.btnPlacebuffer.setOnClickListener {
|
||||
@@ -106,10 +111,13 @@ class HemoCubeFragment : Fragment() {
|
||||
} else {
|
||||
activity?.runOnUiThread {
|
||||
binding.tvSubtitle4.visibility = View.VISIBLE
|
||||
// binding.tvSubtitle4.text = "Buffer Started"
|
||||
}
|
||||
|
||||
checkAndStartProcess()
|
||||
it.visibility = View.GONE
|
||||
}
|
||||
it.visibility = View.GONE
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -118,18 +126,11 @@ class HemoCubeFragment : Fragment() {
|
||||
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
|
||||
if (result == "Success") {
|
||||
showToast("Test Results Uploaded Successfully")
|
||||
|
||||
val digitalCardFragment = DigitalCardFragment()
|
||||
val transaction = parentFragmentManager.beginTransaction()
|
||||
transaction.replace(R.id.fragment_container, digitalCardFragment)
|
||||
transaction.addToBackStack(null)
|
||||
transaction.commit()
|
||||
|
||||
// val i = Intent(
|
||||
// requireContext().applicationContext, DashboardActivity::class.java
|
||||
// )
|
||||
// startActivity(i)
|
||||
// (activity as HemocubeActivity).finish()
|
||||
val i = Intent(
|
||||
requireContext().applicationContext, DashboardActivity::class.java
|
||||
)
|
||||
startActivity(i)
|
||||
(activity as HemocubeActivity).finish()
|
||||
}
|
||||
if (result == "Local") {
|
||||
showToast("Internet not available, test details stored locally")
|
||||
@@ -290,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()
|
||||
@@ -320,12 +322,16 @@ class HemoCubeFragment : Fragment() {
|
||||
}
|
||||
|
||||
stringData.contains("#SC") -> {
|
||||
binding.tvSubtitle4.text = "Sample Completed"
|
||||
hemoCubeViewModel.messages.postValue("Sample Completed \nGathering data")
|
||||
fetchResult()
|
||||
testingTrace.stop()
|
||||
}
|
||||
|
||||
resultData.contains("REND") -> {
|
||||
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) {
|
||||
@@ -359,7 +365,8 @@ class HemoCubeFragment : Fragment() {
|
||||
sampleIntensity = resultLines[7].split(' ')[1].trim()
|
||||
led3SampleForDevice = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
|
||||
sampleIntensity = resultLines[8].split(' ')[1].split('\r')[0].trim()
|
||||
led4SampleForDevice = resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
|
||||
led4SampleForDevice =
|
||||
resultLines[8].split(' ')[1].split('\r')[0].trim().toDoubleOrNull()!!
|
||||
processResult()
|
||||
}
|
||||
}
|
||||
@@ -396,6 +403,7 @@ class HemoCubeFragment : Fragment() {
|
||||
|
||||
private fun processResult() {
|
||||
try {
|
||||
hemoCubeViewModel.messages.postValue("processing result")
|
||||
val deviceLog = resultData
|
||||
|
||||
val pInfo = requireActivity().packageManager.getPackageInfo(
|
||||
@@ -407,11 +415,63 @@ class HemoCubeFragment : Fragment() {
|
||||
val led2Average = log10(led2BufferForDevice?.div(led2SampleForDevice!!) ?: 0.0)
|
||||
val led3Average = log10(led3BufferForDevice?.div(led3SampleForDevice!!) ?: 0.0)
|
||||
val led4Average = log10(led4BufferForDevice?.div(led4SampleForDevice!!) ?: 0.0)
|
||||
val deviceRatio = led1Average / led3Average
|
||||
val deviceRatio = led3Average / led1Average
|
||||
|
||||
if (led1Average < 0 || led2Average < 0) {
|
||||
if (led1BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)?.get(0)!!
|
||||
|| led2BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(1)?.get(0)!!
|
||||
|| led3BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(2)?.get(0)!!
|
||||
|| led4BufferForDevice < Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(3)?.get(0)!!
|
||||
) {
|
||||
validationError = true
|
||||
activity?.runOnUiThread {
|
||||
binding.errorMessage.text = "Warning: Negative Abs. Retake Blank Reading"
|
||||
binding.errorMessage.text = "Error: Invalid Test. Improper buffer reading (low)"
|
||||
binding.errorMessage.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
if (led1BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(0)?.get(1)!!
|
||||
|| led2BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(1)?.get(1)!!
|
||||
|| led3BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(2)?.get(1)!!
|
||||
|| led4BufferForDevice > Constants.BUFFER_INTENSITY_THRESHOLDS[deviceHardwareId]?.get(3)?.get(1)!!
|
||||
) {
|
||||
validationError = true
|
||||
activity?.runOnUiThread {
|
||||
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 (fittedAbs1 < 0 || fittedAbs2 < 0 || fittedAbs3 < 0 || fittedAbs4 < 0) {
|
||||
validationError = true
|
||||
activity?.runOnUiThread {
|
||||
binding.errorMessage.text = "Error: Negative Abs. Retake Blank Reading"
|
||||
binding.errorMessage.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
@@ -431,28 +491,43 @@ 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)
|
||||
hemoCubeViewModel.messages.postValue(this.classificationResult)
|
||||
this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio)
|
||||
hemoCubeViewModel.messages.postValue(this.prdClassification)
|
||||
this.resultData = deviceLog
|
||||
if (!isUsingExistingBuffer) {
|
||||
with(sharedPreferences.edit()) {
|
||||
putString(Constants.BUFFER_VALUE_1, led1BufferForDevice.toString())
|
||||
putString(Constants.BUFFER_VALUE_2, led2BufferForDevice.toString())
|
||||
putString(Constants.BUFFER_VALUE_3, led3BufferForDevice.toString())
|
||||
putString(Constants.BUFFER_VALUE_4, led4BufferForDevice.toString())
|
||||
apply()
|
||||
}
|
||||
this.batteryLevel = hemoCubeViewModel.getBatteryLevel().toString()
|
||||
this.batteryCapacity = hemoCubeViewModel.getBatteryCapacity(requireContext()).toString()
|
||||
this.batteryMaxCapacity = hemoCubeViewModel.getBatteryMaxCapacity(requireContext()).toString()
|
||||
this.batteryTemperature = hemoCubeViewModel.getBatteryTemperature().toString()
|
||||
this.batteryVoltage = hemoCubeViewModel.getBatteryVoltage(requireContext()).toString()
|
||||
}
|
||||
|
||||
if (!isUsingExistingBuffer) {
|
||||
with(sharedPreferences.edit()) {
|
||||
putString(Constants.BUFFER_VALUE_1, led1BufferForDevice.toString())
|
||||
putString(Constants.BUFFER_VALUE_2, led2BufferForDevice.toString())
|
||||
putString(Constants.BUFFER_VALUE_3, led3BufferForDevice.toString())
|
||||
putString(Constants.BUFFER_VALUE_4, led4BufferForDevice.toString())
|
||||
apply()
|
||||
}
|
||||
activity?.runOnUiThread {
|
||||
binding.btnSubmit.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
if (!validationError) {
|
||||
activity?.runOnUiThread {
|
||||
binding.btnSubmit.visibility = View.VISIBLE
|
||||
binding.btnSubmit.isEnabled = true
|
||||
binding.btnSubmit.isClickable = true
|
||||
binding.clParent.setBackgroundColor(Color.parseColor("#edfffd"))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(
|
||||
@@ -464,8 +539,9 @@ class HemoCubeFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun findResult(calculatedRatio: Double?): String {
|
||||
fun findResult(calculatedRatio: Double?): String {
|
||||
try {
|
||||
hemoCubeViewModel.messages.postValue("result classification")
|
||||
if (calculatedRatio != null) {
|
||||
if (calculatedRatio < 0.05)
|
||||
return "Inconclusive. Very low Absorbance - Repeat test with Higher Blood Volume"
|
||||
@@ -482,14 +558,39 @@ class HemoCubeFragment : Fragment() {
|
||||
if (calculatedRatio > 0.35)
|
||||
return "Inconclusive. Repeat with test with lower volume of blood"
|
||||
} else {
|
||||
return "NULL"
|
||||
return "INVALID"
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
showToast("error while performing classification")
|
||||
Firebase.crashlytics.recordException(e)
|
||||
return "ERROR"
|
||||
}
|
||||
return "NULL"
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user