updated preprod changes added

This commit is contained in:
Mariya
2023-11-21 14:15:55 +05:30
parent e92a80caec
commit f26f3098bb
2 changed files with 180 additions and 43 deletions

View File

@@ -74,4 +74,40 @@ object Constants {
const val BUFFER_VALUE_3 = "BufferValue3" const val BUFFER_VALUE_3 = "BufferValue3"
const val BUFFER_VALUE_4 = "BufferValue4" const val BUFFER_VALUE_4 = "BufferValue4"
const val DEVICE_ID = "DEVICE_ID" 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),
)
)
} }

View File

@@ -5,7 +5,6 @@ import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup 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.data.model.patient.toHemoCubeTestData
import com.example.hpostesting.presentation.UsbServiceListener import com.example.hpostesting.presentation.UsbServiceListener
import com.example.hpostesting.presentation.dashboard.DashboardActivity 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.MyDialogListener
import com.example.hpostesting.presentation.utils.UIUtils import com.example.hpostesting.presentation.utils.UIUtils
import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.crashlytics.ktx.crashlytics
@@ -35,7 +33,7 @@ class HemoCubeFragment : Fragment() {
private lateinit var binding: FragmentHemoCubeReferenceBinding private lateinit var binding: FragmentHemoCubeReferenceBinding
private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels() private val hemoCubeViewModel: HemoCubeViewModel by activityViewModels()
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
val testDetails = DataHolder.selectedTest?.toHemoCubeTestData() private val testDetails = DataHolder.selectedTest?.toHemoCubeTestData()
private var isOnline = false private var isOnline = false
private var currentDeviceData: DeviceData? = null private var currentDeviceData: DeviceData? = null
private var resultData: String = "" private var resultData: String = ""
@@ -45,12 +43,19 @@ class HemoCubeFragment : Fragment() {
private val testingTrace = Firebase.performance.newTrace("testing_trace") private val testingTrace = Firebase.performance.newTrace("testing_trace")
private var led1BufferForDevice = 0.0 private var led1BufferForDevice = 0.0
private var led2BufferForDevice = 0.0 private var led2BufferForDevice = 0.0
private var led3BufferForDevice = 0.0 private var led3BufferForDevice = 0.0
private var led4BufferForDevice = 0.0 private var led4BufferForDevice = 0.0
private var led1SampleForDevice = 0.0 private var led1SampleForDevice = 0.0
private var led2SampleForDevice = 0.0 private var led2SampleForDevice = 0.0
private var led3SampleForDevice = 0.0 private var led3SampleForDevice = 0.0
private var led4SampleForDevice = 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( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?,
@@ -84,8 +89,8 @@ class HemoCubeFragment : Fragment() {
binding.nameEditText.visibility = View.GONE binding.nameEditText.visibility = View.GONE
binding.tvTitle.visibility = View.GONE binding.tvTitle.visibility = View.GONE
binding.btnGo.visibility = View.GONE binding.btnGo.visibility = View.GONE
binding.btnSubmit.isEnabled = true binding.btnSubmit.isEnabled = false
binding.btnSubmit.isClickable = true binding.btnSubmit.isClickable = false
binding.btnPlacebuffer.visibility = View.GONE binding.btnPlacebuffer.visibility = View.GONE
binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}" binding.tvName.text = "Name: ${testDetails?.name}\n ID: ${testDetails?._id}"
@@ -94,10 +99,10 @@ class HemoCubeFragment : Fragment() {
binding.btnSamplestart.setOnClickListener { binding.btnSamplestart.setOnClickListener {
activity?.runOnUiThread { activity?.runOnUiThread {
binding.tvSubtitle4.visibility = View.VISIBLE binding.tvSubtitle4.visibility = View.VISIBLE
binding.tvSubtitle4.text = "Sample Started" // binding.tvSubtitle4.text = "Sample Started"
} }
startSampleProcess() startSampleProcess()
it.visibility = View.GONE it.visibility = View.GONE
} }
binding.btnPlacebuffer.setOnClickListener { binding.btnPlacebuffer.setOnClickListener {
@@ -106,10 +111,13 @@ class HemoCubeFragment : Fragment() {
} else { } else {
activity?.runOnUiThread { activity?.runOnUiThread {
binding.tvSubtitle4.visibility = View.VISIBLE binding.tvSubtitle4.visibility = View.VISIBLE
// binding.tvSubtitle4.text = "Buffer Started"
} }
checkAndStartProcess() checkAndStartProcess()
it.visibility = View.GONE
} }
it.visibility = View.GONE
} }
} }
@@ -118,18 +126,11 @@ class HemoCubeFragment : Fragment() {
hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result -> hemoCubeViewModel.fireBaseUpload.observe(viewLifecycleOwner) { result ->
if (result == "Success") { if (result == "Success") {
showToast("Test Results Uploaded Successfully") showToast("Test Results Uploaded Successfully")
val i = Intent(
val digitalCardFragment = DigitalCardFragment() requireContext().applicationContext, DashboardActivity::class.java
val transaction = parentFragmentManager.beginTransaction() )
transaction.replace(R.id.fragment_container, digitalCardFragment) startActivity(i)
transaction.addToBackStack(null) (activity as HemocubeActivity).finish()
transaction.commit()
// val i = Intent(
// requireContext().applicationContext, DashboardActivity::class.java
// )
// startActivity(i)
// (activity as HemocubeActivity).finish()
} }
if (result == "Local") { if (result == "Local") {
showToast("Internet not available, test details stored locally") showToast("Internet not available, test details stored locally")
@@ -290,6 +291,7 @@ class HemoCubeFragment : Fragment() {
val slData = stringData.split(" ") val slData = stringData.split(" ")
if (slData.size > 1) { if (slData.size > 1) {
val hardwareId = slData[1].trim() val hardwareId = slData[1].trim()
deviceHardwareId = hardwareId
with(sharedPreferences.edit()) { with(sharedPreferences.edit()) {
putString(Constants.DEVICE_ID, hardwareId) putString(Constants.DEVICE_ID, hardwareId)
apply() apply()
@@ -320,12 +322,16 @@ class HemoCubeFragment : Fragment() {
} }
stringData.contains("#SC") -> { stringData.contains("#SC") -> {
binding.tvSubtitle4.text = "Sample Completed" hemoCubeViewModel.messages.postValue("Sample Completed \nGathering data")
fetchResult() fetchResult()
testingTrace.stop() testingTrace.stop()
} }
resultData.contains("REND") -> { resultData.contains("REND") -> {
hemoCubeViewModel.messages.postValue(
"Data collected \n" +
" Processing data"
)
val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex()) val resultLines = resultData.split("\\s+(?=LB|LS)".toRegex())
var bufferIntensity = resultLines[1].split(' ')[1].trim() var bufferIntensity = resultLines[1].split(' ')[1].trim()
led1BufferForDevice = if (isUsingExistingBuffer) { led1BufferForDevice = if (isUsingExistingBuffer) {
@@ -359,7 +365,8 @@ class HemoCubeFragment : Fragment() {
sampleIntensity = resultLines[7].split(' ')[1].trim() sampleIntensity = resultLines[7].split(' ')[1].trim()
led3SampleForDevice = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!! led3SampleForDevice = resultLines[7].split(' ')[1].trim().toDoubleOrNull()!!
sampleIntensity = resultLines[8].split(' ')[1].split('\r')[0].trim() 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() processResult()
} }
} }
@@ -396,6 +403,7 @@ class HemoCubeFragment : Fragment() {
private fun processResult() { private fun processResult() {
try { try {
hemoCubeViewModel.messages.postValue("processing result")
val deviceLog = resultData val deviceLog = resultData
val pInfo = requireActivity().packageManager.getPackageInfo( val pInfo = requireActivity().packageManager.getPackageInfo(
@@ -407,11 +415,63 @@ class HemoCubeFragment : Fragment() {
val led2Average = log10(led2BufferForDevice?.div(led2SampleForDevice!!) ?: 0.0) val led2Average = log10(led2BufferForDevice?.div(led2SampleForDevice!!) ?: 0.0)
val led3Average = log10(led3BufferForDevice?.div(led3SampleForDevice!!) ?: 0.0) val led3Average = log10(led3BufferForDevice?.div(led3SampleForDevice!!) ?: 0.0)
val led4Average = log10(led4BufferForDevice?.div(led4SampleForDevice!!) ?: 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 { 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 binding.errorMessage.visibility = View.VISIBLE
} }
} }
@@ -431,28 +491,43 @@ class HemoCubeFragment : Fragment() {
this.led2Average = led2Average this.led2Average = led2Average
this.led3Average = led3Average this.led3Average = led3Average
this.led4Average = led4Average this.led4Average = led4Average
this.abs1 = fittedAbs1
this.abs2 = fittedAbs2
this.abs3 = fittedAbs3
this.abs4 = fittedAbs4
this.deviceRatio = deviceRatio this.deviceRatio = deviceRatio
this.calculatedRatio = calculateRatio(deviceRatio) this.calculatedRatio = calculateRatio(deviceRatio)
this.predictedDenovixRatio = _predictedDenovixRatio
this.coefficients = currentDeviceData?.coefficients?.get(0) this.coefficients = currentDeviceData?.coefficients?.get(0)
.toString() + ", " + currentDeviceData?.coefficients?.get(1).toString() .toString() + ", " + currentDeviceData?.coefficients?.get(1).toString()
this.classificationResult = findResult(calculatedRatio) this.classificationResult = findResult(calculatedRatio)
hemoCubeViewModel.messages.postValue(this.classificationResult) this.prdClassification = absorbanceBasedClassification(predictedDenovixRatio)
hemoCubeViewModel.messages.postValue(this.prdClassification)
this.resultData = deviceLog this.resultData = deviceLog
if (!isUsingExistingBuffer) { this.batteryLevel = hemoCubeViewModel.getBatteryLevel().toString()
with(sharedPreferences.edit()) { this.batteryCapacity = hemoCubeViewModel.getBatteryCapacity(requireContext()).toString()
putString(Constants.BUFFER_VALUE_1, led1BufferForDevice.toString()) this.batteryMaxCapacity = hemoCubeViewModel.getBatteryMaxCapacity(requireContext()).toString()
putString(Constants.BUFFER_VALUE_2, led2BufferForDevice.toString()) this.batteryTemperature = hemoCubeViewModel.getBatteryTemperature().toString()
putString(Constants.BUFFER_VALUE_3, led3BufferForDevice.toString()) this.batteryVoltage = hemoCubeViewModel.getBatteryVoltage(requireContext()).toString()
putString(Constants.BUFFER_VALUE_4, led4BufferForDevice.toString()) }
apply()
} 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.isEnabled = true
binding.btnSubmit.isClickable = true binding.btnSubmit.isClickable = true
binding.clParent.setBackgroundColor(Color.parseColor("#edfffd")) binding.clParent.setBackgroundColor(Color.parseColor("#edfffd"))
}
} }
} catch (e: Exception) { } catch (e: Exception) {
Toast.makeText( Toast.makeText(
@@ -464,8 +539,9 @@ class HemoCubeFragment : Fragment() {
} }
} }
private fun findResult(calculatedRatio: Double?): String { fun findResult(calculatedRatio: Double?): String {
try { try {
hemoCubeViewModel.messages.postValue("result classification")
if (calculatedRatio != null) { if (calculatedRatio != null) {
if (calculatedRatio < 0.05) if (calculatedRatio < 0.05)
return "Inconclusive. Very low Absorbance - Repeat test with Higher Blood Volume" return "Inconclusive. Very low Absorbance - Repeat test with Higher Blood Volume"
@@ -482,14 +558,39 @@ class HemoCubeFragment : Fragment() {
if (calculatedRatio > 0.35) if (calculatedRatio > 0.35)
return "Inconclusive. Repeat with test with lower volume of blood" return "Inconclusive. Repeat with test with lower volume of blood"
} else { } else {
return "NULL" return "INVALID"
} }
} catch (e: Exception) { } catch (e: Exception) {
showToast("error while performing classification") showToast("error while performing classification")
Firebase.crashlytics.recordException(e) Firebase.crashlytics.recordException(e)
return "ERROR" 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) { private fun showToast(message: String) {