Skip to content

Commit 1ae8294

Browse files
committed
Logarithm scale view
1 parent b37019d commit 1ae8294

File tree

8 files changed

+149
-40
lines changed

8 files changed

+149
-40
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ android {
1212
applicationId = "io.github.vikulin.opengammakit"
1313
minSdk = 24
1414
targetSdk = 35
15-
versionCode = 13
16-
versionName = "1.1.3"
15+
versionCode = 14
16+
versionName = "1.1.4"
1717
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
1818
setProperty("archivesBaseName", "ogk-inspector-$versionName")
1919
}

app/src/main/kotlin/io/github/vikulin/opengammakit/SpectrumFragment.kt

Lines changed: 88 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,15 @@ import java.io.InputStreamReader
5959
import kotlin.text.iterator
6060
import androidx.core.net.toUri
6161
import com.github.mikephil.charting.components.Legend
62-
import io.github.vikulin.opengammakit.math.SpectrumModifier.applySavitzkyGolayFilter
63-
import io.github.vikulin.opengammakit.math.SpectrumModifier.detectCWTPeaks
62+
import io.github.vikulin.opengammakit.math.SpectrumModifier
6463
import io.github.vikulin.opengammakit.math.SpectrumModifier.smartPeakDetect
64+
import io.github.vikulin.opengammakit.model.EnergySpectrum
6565
import io.github.vikulin.opengammakit.model.GammaKitEntry
66-
import io.github.vikulin.opengammakit.model.PeakInfo
6766
import io.github.vikulin.opengammakit.view.FwhmSpectrumSelectionDialogFragment
6867
import io.github.vikulin.opengammakit.view.SaveSelectedSpectrumDialogFragment
6968
import io.github.vikulin.opengammakit.view.SpectrumFileChooserDialogFragment
69+
import kotlin.math.log10
70+
import kotlin.math.pow
7071

7172
class SpectrumFragment : SerialConnectionFragment(),
7273
CalibrationUpdateOrRemoveDialogFragment.CalibrationDialogListener,
@@ -89,6 +90,7 @@ class SpectrumFragment : SerialConnectionFragment(),
8990
private lateinit var btnSaveSpectrum: ImageButton
9091
private lateinit var btnToggleFilter: ImageButton
9192
private lateinit var btnToggleDetectPeak: ImageButton
93+
private lateinit var btnToggleLogScale: ImageButton
9294
private lateinit var clockProgressView: ClockProgressView
9395
private lateinit var spectrumDataSet: OpenGammaKitData
9496
// Indicates which graph is currently active for measurements such as Calibration and FWHM
@@ -151,6 +153,7 @@ class SpectrumFragment : SerialConnectionFragment(),
151153
btnSaveSpectrum = view.findViewById(R.id.btnSaveSpectrumFile)
152154
btnToggleFilter = view.findViewById(R.id.btnToggleFilter)
153155
btnToggleDetectPeak = view.findViewById(R.id.btnToggleDetectPeak)
156+
btnToggleLogScale = view.findViewById(R.id.btnToggleLogScale)
154157
clockProgressView = view.findViewById(R.id.clockProgressView)
155158

156159
gestureDetector = GestureDetector(requireContext(), object : GestureDetector.SimpleOnGestureListener() {
@@ -335,6 +338,11 @@ class SpectrumFragment : SerialConnectionFragment(),
335338
}
336339
updateChartSpectrumData()
337340
}
341+
342+
btnToggleLogScale.setOnClickListener {
343+
toggleLogScaleFilter()
344+
updateChartSpectrumData()
345+
}
338346
}
339347

340348
fun drawPeakLimitLines() {
@@ -526,10 +534,13 @@ class SpectrumFragment : SerialConnectionFragment(),
526534

527535
private fun setupChart() {
528536
val primaryColor = resources.getColor(R.color.colorPrimaryText, null)
529-
537+
//copy data to outputSpectrum
538+
spectrumDataSet.data.mapIndexed { index, entry ->
539+
resetSpectrumData(entry.resultData.energySpectrum)
540+
}
530541
// Create LineDataSets from each GammaKitEntry in spectrumDataSet
531542
val dataSets = spectrumDataSet.data.mapIndexed { index, entry ->
532-
val spectrum = entry.resultData.energySpectrum.spectrum
543+
val spectrum = entry.resultData.energySpectrum.outputSpectrum
533544
val entries = spectrum.mapIndexed { ch, count ->
534545
Entry(ch.toFloat(), count.toFloat())
535546
}
@@ -591,7 +602,7 @@ class SpectrumFragment : SerialConnectionFragment(),
591602
private fun updateChartSpectrumData() {
592603

593604
val dataSets = spectrumDataSet.data.mapIndexed { index, entry ->
594-
val spectrum = entry.resultData.energySpectrum.spectrum
605+
val spectrum = entry.resultData.energySpectrum.outputSpectrum
595606
val entries = spectrum.mapIndexed { ch, count ->
596607
Entry(ch.toFloat(), count.toFloat())
597608
}
@@ -620,7 +631,6 @@ class SpectrumFragment : SerialConnectionFragment(),
620631
setDrawInside(false)
621632
xEntrySpace = 20f
622633
}
623-
624634
spectrumChart.data.notifyDataChanged()
625635
spectrumChart.notifyDataSetChanged()
626636
spectrumChart.invalidate()
@@ -793,16 +803,17 @@ class SpectrumFragment : SerialConnectionFragment(),
793803
"Test",
794804
"Spectrum size: ${spectrum.size}, counts: $counts"
795805
)
796-
spectrumDataSet.data[deviceSpectrumIndex].
797-
resultData.energySpectrum.spectrum = spectrum
798-
spectrumDataSet.data[deviceSpectrumIndex].
799-
resultData.energySpectrum.validPulseCount =
806+
var energySpectrum = spectrumDataSet.data[deviceSpectrumIndex].
807+
resultData.energySpectrum
808+
energySpectrum.spectrum = spectrum
809+
energySpectrum.validPulseCount =
800810
spectrum.fold(0L) { acc, num -> acc + num }
801-
spectrumDataSet.data[deviceSpectrumIndex].
802-
resultData.energySpectrum.numberOfChannels = spectrum.size
803-
spectrumDataSet.data[deviceSpectrumIndex].
804-
resultData.energySpectrum.measurementTime =
811+
energySpectrum.numberOfChannels = spectrum.size
812+
energySpectrum.measurementTime =
805813
(SystemClock.elapsedRealtime() - measureTimer.base)/1000
814+
// copy spectrum. TODO apply filters and peaks detection
815+
resetSpectrumData(energySpectrum)
816+
806817
updateChartSpectrumData()
807818
} catch (e: Exception) {
808819
Log.e("Test", "Failed to parse data: ${e.message}")
@@ -840,6 +851,10 @@ class SpectrumFragment : SerialConnectionFragment(),
840851
"Parsed scheduled spectrum number: ${openGammaKitData.data.size}"
841852
)
842853
spectrumDataSet.data[deviceSpectrumIndex] = openGammaKitData.data[deviceSpectrumIndex]
854+
var energySpectrum = spectrumDataSet.data[deviceSpectrumIndex].
855+
resultData.energySpectrum
856+
// copy spectrum. TODO apply filters and peaks detection
857+
resetSpectrumData(energySpectrum)
843858
updateChartSpectrumData()
844859
} catch (e: Exception) {
845860
Log.e("Test", "Failed to parse data: ${e.message}")
@@ -1477,40 +1492,82 @@ class SpectrumFragment : SerialConnectionFragment(),
14771492
for (entry in spectrumDataSet.data) {
14781493
val energy = entry.resultData.energySpectrum
14791494
if (!energy.filters.contains("SavitzkyGolay")) {
1480-
//create a copy for next recovery
1481-
energy.rawSpectrum = energy.spectrum.toList()
14821495
// Apply filter and add tag
1483-
applySavitzkyGolayFilter(entry)
1496+
SpectrumModifier.applySavitzkyGolayFilter(entry)
14841497
entry.resultData.energySpectrum.filters.add("SavitzkyGolay")
14851498
} else {
1486-
if (energy.filters.contains("SavitzkyGolay")) {
1487-
// Restore raw spectrum and remove tag
1488-
energy.spectrum = energy.rawSpectrum ?: energy.spectrum
1489-
energy.filters.removeIf { it=="SavitzkyGolay" }
1490-
}
1499+
energy.filters.clear()
1500+
resetSpectrumData(energy)
14911501
}
14921502
}
14931503
}
14941504

14951505
private fun applySavitzkyGolayFilter(apply: Boolean) {
14961506
for (entry in spectrumDataSet.data) {
14971507
val energy = entry.resultData.energySpectrum
1498-
14991508
if (apply) {
1509+
for(filter in energy.filters){
1510+
when(filter) {
1511+
"LogScale" -> {
1512+
applyLogScale(entry, true)
1513+
}
1514+
}
1515+
}
15001516
if (!energy.filters.contains("SavitzkyGolay")) {
1501-
//create a copy for next recovery
1502-
energy.rawSpectrum = energy.spectrum.toList()
15031517
// Apply filter and add tag
1504-
applySavitzkyGolayFilter(entry)
1518+
SpectrumModifier.applySavitzkyGolayFilter(entry)
15051519
entry.resultData.energySpectrum.filters.add("SavitzkyGolay")
15061520
}
15071521
} else {
1508-
if (energy.filters.contains("SavitzkyGolay")) {
1509-
// Restore raw spectrum and remove tag
1510-
energy.spectrum = energy.rawSpectrum ?: energy.spectrum
1511-
energy.filters.removeIf { it=="SavitzkyGolay" }
1522+
energy.filters.clear()
1523+
resetSpectrumData(energy)
1524+
}
1525+
}
1526+
}
1527+
1528+
private fun resetSpectrumData(energySpectrum: EnergySpectrum){
1529+
energySpectrum.outputSpectrum =
1530+
energySpectrum.spectrum.map { count ->
1531+
count.toDouble()
1532+
}.toMutableList()
1533+
// TODO apply it here when filters left
1534+
}
1535+
1536+
private fun toggleLogScaleFilter(){
1537+
for (entry in spectrumDataSet.data) {
1538+
val energy = entry.resultData.energySpectrum
1539+
if (!energy.filters.contains("LogScale")) {
1540+
// Apply filter and add tag
1541+
applyLogScale(entry, true)
1542+
} else {
1543+
applyLogScale(entry, false)
1544+
}
1545+
}
1546+
}
1547+
1548+
fun applyLogScale(entry: GammaKitEntry, apply: Boolean) {
1549+
entry.resultData.energySpectrum.applyLogScale(apply)
1550+
}
1551+
1552+
fun EnergySpectrum.applyLogScale(apply: Boolean) {
1553+
if (apply) {
1554+
for(filter in filters){
1555+
when(filter) {
1556+
"SavitzkyGolay" -> {
1557+
applySavitzkyGolayFilter(true)
1558+
}
15121559
}
15131560
}
1561+
if (!filters.contains("LogScale")) {
1562+
outputSpectrum = outputSpectrum.map { count ->
1563+
val adjusted = if (count > 1L) count.toDouble() else 1.0
1564+
log10(adjusted)
1565+
}.toMutableList()
1566+
filters.add("LogScale")
1567+
}
1568+
} else {
1569+
filters.clear()
1570+
resetSpectrumData(this)
15141571
}
15151572
}
15161573

app/src/main/kotlin/io/github/vikulin/opengammakit/math/SpectrumModifier.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import kotlin.math.abs
1010
import kotlin.math.cbrt
1111
import kotlin.math.exp
1212
import kotlin.math.pow
13-
import kotlin.math.roundToLong
1413
import kotlin.math.sqrt
1514

1615
object SpectrumModifier {
@@ -63,7 +62,7 @@ object SpectrumModifier {
6362
val spectrum = entry.resultData.energySpectrum.spectrum.map { it.toDouble() }
6463
if (spectrum.size < 31) return // Too small for filtering
6564
val smoothed = savitzkyGolay(spectrum.toDoubleArray(), windowSize = 31, polyOrder = 3)
66-
entry.resultData.energySpectrum.spectrum = smoothed.map { it.roundToLong() }
65+
entry.resultData.energySpectrum.outputSpectrum = smoothed.map { it }.toMutableList()
6766
}
6867

6968
// Public method to detect peaks in selected spectrums of a dataset
@@ -78,7 +77,7 @@ object SpectrumModifier {
7877
val detectedPeaks = mutableListOf<PeakInfo>()
7978

8079
for (spectrumIndex in indexesToAnalyze) {
81-
val spectrum = dataSet.data[spectrumIndex].resultData.energySpectrum.spectrum.map { it.toDouble() }
80+
val spectrum = dataSet.data[spectrumIndex].resultData.energySpectrum.outputSpectrum.map { it.toDouble() }
8281
val correctedSpectrum = if (estimateBaseline) removeBaseline(spectrum) else spectrum
8382

8483
val waveletWidthList = waveletWidths.toList()

app/src/main/kotlin/io/github/vikulin/opengammakit/model/OpenGammaKitData.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ data class ResultData(
3030
data class EnergySpectrum(
3131
var numberOfChannels: Int,
3232
var measurementTime: Long,
33-
var spectrum: List<Long>,
33+
var spectrum: List<Long>, // raw integer counts (original measurement)
3434
var validPulseCount: Long,
35-
var rawSpectrum: List<Long>? = null,
36-
var filters: MutableList<String> = mutableListOf<String>(),
37-
var peaks: MutableList<PeakInfo> = mutableListOf<PeakInfo>()
35+
var outputSpectrum: MutableList<Double> = mutableListOf<Double>(), // transformed data for display
36+
var filters: MutableList<String> = mutableListOf<String>(), // list of applied filters (like "LogScale")
37+
var peaks: MutableList<PeakInfo> = mutableListOf<PeakInfo>() // detected peaks
3838
) : JavaSerializable
3939

4040
@Serializable
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="50dp" android:viewportHeight="1024" android:viewportWidth="1024" android:width="50dp">
2+
3+
<path android:fillColor="#000000" android:pathData="M164.5,16.1c-30.5,0.8 -35.3,1.5 -50.9,7 -22.3,7.9 -37.2,17.4 -53.4,33.8 -11.6,11.8 -17.2,19.6 -25.2,35.2 -7.5,14.7 -10.3,23.5 -12,36.9 -1.9,15.9 -3.2,99.8 -2.8,179 0.5,71.9 0.6,78.9 2.3,82.7 1.4,3.4 2.4,4.5 5.2,5.2 4.5,1.3 8.3,0.5 11.8,-2.3l2.8,-2.2 0.3,-53c1.4,-198.8 1.4,-202.8 4.9,-216.9 2.1,-8.5 11.4,-26.9 18.3,-36.1 9.2,-12.3 24,-25.3 37.7,-33 10,-5.5 26.3,-11.2 35.6,-12.4 5.2,-0.7 54,-1.5 126.9,-2 65.2,-0.5 121.6,-1.3 125.3,-1.9 7.3,-1 10,-2.6 11.5,-7 1.3,-3.6 -0.7,-8.3 -4.4,-10.8 -2.3,-1.4 -5.9,-1.9 -21.3,-2.4 -24,-0.9 -177.5,-0.8 -212.6,0.2z" android:strokeColor="#00000000"/>
4+
5+
<path android:fillColor="#000000" android:pathData="M647,16c-9.1,0.4 -17.2,1 -18.1,1.4 -4.5,2 -5.8,12.2 -2.1,15.9 1.7,1.6 4,2.2 11.4,2.9 5.1,0.4 55,1 110.8,1.3 105.8,0.6 134,1.4 148.7,4.5 20.5,4.2 44.4,19.5 59.6,38.2 11.3,13.8 20.3,31.1 23.3,44.8 1.8,8.1 3.3,66.3 3.4,131.5 0,63.4 1.7,130.3 3.3,135.1 1,3.2 1.8,3.9 4.7,4.5 6.1,1.3 10.3,-0.2 12.3,-4.3 2.9,-6 4,-55.6 3.3,-146.3 -0.8,-94.8 -1.5,-111.5 -5.2,-125.7 -4.7,-18.1 -10,-29.9 -19.8,-44.2 -19.2,-28.2 -46.6,-47.4 -79.4,-55.7 -10.7,-2.8 -13.8,-3.1 -37.7,-3.9 -29,-1 -192.8,-1 -218.5,-0z" android:strokeColor="#00000000"/>
6+
7+
<path android:fillColor="#000000" android:pathData="M347.2,456.2l0.3,160.3 2.2,7.8c6.5,22.8 20.2,36.7 41,41.3 8.5,1.9 27.5,1.6 37.1,-0.6l5.2,-1.2 0,-18 0,-18 -2.2,0.7c-1.3,0.3 -6.9,0.9 -12.6,1.2 -12.3,0.7 -17.2,-0.8 -22.6,-6.7 -4.6,-5.1 -6.2,-9.2 -7.5,-18.6 -0.7,-5 -1.1,-58 -1.1,-158l0,-150.4 -20,-0 -20.1,-0 0.3,160.2z" android:strokeColor="#00000000"/>
8+
9+
<path android:fillColor="#000000" android:pathData="M554.4,411.5c-23.7,3.6 -42.1,13.1 -58.4,30.1 -17.1,17.8 -28.2,41.3 -33.6,70.9 -2.5,13.9 -3.1,48.1 -1,62.3 1.9,12.6 5.2,25.1 9.7,35.7 9.8,23.5 30,44.5 51.6,53.4 30.1,12.4 70,9.4 95.3,-7.1 8.4,-5.5 18.5,-15.1 24.1,-22.9 8.8,-12.3 8.1,-13.7 7.6,14.1 -0.3,16.7 -1,26.9 -2,32 -7.6,36.8 -25.6,56.9 -58.4,65.7 -8.9,2.4 -11.6,2.6 -29.3,2.7 -15.3,0.1 -21.3,-0.3 -28,-1.7 -16,-3.4 -35.1,-10.6 -54.2,-20.5 -0.5,-0.2 -0.8,8.6 -0.8,19.5l0,19.9 3.8,1.9c20.1,9.7 41.8,14.5 70.5,15.2 39.4,1.1 66.5,-5.1 89.3,-20.2 25,-16.7 39.2,-40.7 46.6,-79 2.1,-10.8 2.2,-13.2 2.5,-139.3l0.4,-128.2 -20.1,-0 -20,-0 0,17c0,9.3 -0.3,17 -0.7,17 -0.5,-0 -2.1,-2.1 -3.8,-4.8 -4.6,-7.4 -17.2,-19.2 -25.6,-23.9 -17.9,-10.1 -41.2,-13.6 -65.5,-9.8zM597.4,446c12.5,3.2 20.8,8.1 31.1,18.4 9.8,9.8 14.5,17.4 18.6,30.1 2.1,6.5 2.3,9.2 2.7,35.8 0.4,33 -0.4,41.7 -5.2,55.9 -8.5,25.1 -26.8,43 -50.6,49.4 -8.1,2.2 -29,2.5 -37,0.5 -23.5,-5.7 -42.8,-25.3 -50.9,-51.5 -5.1,-16.5 -6.6,-43.3 -3.6,-64.1 5.9,-41.2 27,-68 59.3,-75 9.2,-2.1 26.6,-1.8 35.6,0.5z" android:strokeColor="#00000000"/>
10+
11+
<path android:fillColor="#000000" android:pathData="M27.9,622.4c-6.7,2.2 -6.4,-4.5 -6.4,132.1 0.1,129.7 0.2,135.4 4.7,151.8 4.3,16.2 17.4,37.9 31.9,53.2 12.3,12.9 26.2,23.2 41.3,30.5 21.6,10.5 29.2,11.6 92.1,13.1 51.8,1.2 186.6,0.6 199.3,-1 7.9,-0.9 10.4,-2.5 12.1,-7.1 1.4,-4.1 -1.3,-9 -6.3,-11.4 -3.8,-1.9 -8.4,-2 -121.5,-2.7 -64.7,-0.5 -123.2,-1.3 -130.1,-1.8 -13.8,-1.1 -23,-3.6 -35.3,-9.7 -24.7,-12.4 -43.8,-31.5 -56,-55.9 -9.5,-19.2 -9.4,-18.6 -10.8,-164.5 -0.5,-58 -1.3,-109.2 -1.8,-113.8 -1.1,-11.6 -5.1,-15.4 -13.2,-12.8z" android:strokeColor="#00000000"/>
12+
13+
<path android:fillColor="#000000" android:pathData="M992.3,622.5c-1.7,0.7 -3.7,2.3 -4.3,3.5 -2.4,4.5 -3,24 -4,132 -0.5,60.8 -1.4,116.3 -2,123.3 -2,23.8 -11.5,43.6 -30.8,63.8 -12,12.7 -31.8,25.5 -46.7,30.2 -14.3,4.5 -44.1,5.7 -151,5.8 -90.5,-0 -121.5,0.7 -125.2,2.7 -3.9,2.1 -5.1,11.1 -2,15.1 2.2,2.7 6.8,3.3 32.7,4.1 33.5,1 221.3,-0.6 233.9,-2 31.4,-3.4 69.8,-28 89.7,-57.5 9.8,-14.4 14.7,-25.4 20,-45 3.8,-13.9 4.7,-38.1 4.6,-128 -0.1,-83.4 -1.3,-139.1 -3.1,-143.8 -0.7,-1.7 -2.4,-3.4 -4.6,-4.2 -4,-1.8 -3.2,-1.8 -7.2,-0z" android:strokeColor="#00000000"/>
14+
15+
</vector>

app/src/main/res/layout-land/fragment_spectrum.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,25 @@
240240
app:tint="@color/colorPrimaryText"
241241
app:srcCompat="@drawable/ic_peak_detection" />
242242
</com.google.android.material.card.MaterialCardView>
243+
244+
<com.google.android.material.card.MaterialCardView
245+
android:layout_width="wrap_content"
246+
android:layout_height="wrap_content"
247+
android:layout_marginVertical="6dp"
248+
app:cardElevation="4dp"
249+
app:cardBackgroundColor="@android:color/transparent"
250+
app:strokeWidth="0dp">
251+
252+
<ImageButton
253+
android:id="@+id/btnToggleLogScale"
254+
android:layout_width="@dimen/buttons_size"
255+
android:layout_height="@dimen/buttons_size"
256+
android:background="?selectableItemBackgroundBorderless"
257+
android:contentDescription="@string/log_scale"
258+
app:tint="@color/colorPrimaryText"
259+
app:srcCompat="@drawable/ic_logarithm" />
260+
</com.google.android.material.card.MaterialCardView>
261+
243262
</LinearLayout>
244263
</ScrollView>
245264

app/src/main/res/layout/fragment_spectrum.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,24 @@
240240
app:srcCompat="@drawable/ic_peak_detection" />
241241
</com.google.android.material.card.MaterialCardView>
242242

243+
<com.google.android.material.card.MaterialCardView
244+
android:layout_width="wrap_content"
245+
android:layout_height="wrap_content"
246+
android:layout_marginVertical="6dp"
247+
app:cardElevation="4dp"
248+
app:cardBackgroundColor="@android:color/transparent"
249+
app:strokeWidth="0dp">
250+
251+
<ImageButton
252+
android:id="@+id/btnToggleLogScale"
253+
android:layout_width="@dimen/buttons_size"
254+
android:layout_height="@dimen/buttons_size"
255+
android:background="?selectableItemBackgroundBorderless"
256+
android:contentDescription="@string/log_scale"
257+
app:tint="@color/colorPrimaryText"
258+
app:srcCompat="@drawable/ic_logarithm" />
259+
</com.google.android.material.card.MaterialCardView>
260+
243261
</LinearLayout>
244262
</ScrollView>
245263

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
<string name="save_spectrum_file">Save spectrum file</string>
1717
<string name="apply_savitzky_golay_filter">Apply Savitzky-Golay filter</string>
1818
<string name="detect_peak">Detect peak</string>
19+
<string name="log_scale">Logarithmic scale</string>
1920
</resources>

0 commit comments

Comments
 (0)