'Activity module
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Type Point(X As String, Y As Double, ShowTick As Boolean)
Type Data(Points As List, LinesColor As Int, Target As Panel, Interval As Double, YMin As Double, YMax As Double, Board As Canvas)
Type DataEnvelop(Points As List)
Type GraphInternal (originX As Int, originY As Int, maxY As Int, intervalX As Float, gw As Int, gh As Int)
Type Graph (GI As GraphInternal, Title As String, YAxis As String, XAxis As String, YStart As Float, _
YEnd As Float, YInterval As Float, AxisColor As Int)
End Sub
Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
Dim ButtonShoulder As Button
Dim PanelShoulderI As Panel
Dim PanelShoulderR As Panel
Dim PanelShoulderIfft As Panel
Dim PanelShoulderRfft As Panel
Dim TabHostGraph As TabHost
Dim HShoulder As HorizontalScrollView
Dim VShoulder As ScrollView
Dim HfftS As HorizontalScrollView
Dim ShoulderI, ShoulderR As Data
'Dim ShoulderIfft As Data
Dim ShoulderRfft As Data
Dim ShoulderREnvelopUpper As DataEnvelop
Dim ShoulderREnvelopLower As DataEnvelop
Dim FFT As FFT
'file picker
Dim fd As FileDialog
Dim ret As Int
Dim GIfft, GRfft As Graph
End Sub
Sub Activity_Create(FirstTime As Boolean)
'Load Layout
Activity.LoadLayout("STACLayout")
TabHostGraph.Initialize("")
Activity.AddView(TabHostGraph, 200, 10, 1100dip, 700dip)
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub ButtonShoulder_Click
If ButtonShoulder.Text = "Load Shoulder" Then
PanelShoulderI.Initialize("Shoulder I Time")
PanelShoulderR.Initialize("Shoulder R Time")
PanelShoulderRfft.Initialize("Shoulder R FFT")
HShoulder.Initialize(10000dip, "")
HShoulder.Panel.AddView(PanelShoulderR, 0,0,10000dip, 300dip)
HShoulder.Panel.AddView(PanelShoulderRfft, 0,305,10000dip, 300dip)
TabHostGraph.AddTab2("Shoulder", HShoulder)
HfftS.Initialize(5000dip, "")
TabHostGraph.AddTab2("FFT", HfftS)
'''''''''''''''
ShoulderI.Initialize
ShoulderI.Target = PanelShoulderI
ShoulderI.LinesColor = Colors.Blue
ShoulderR.Initialize
ShoulderR.Target = PanelShoulderR
ShoulderR.LinesColor = Colors.Blue
ShoulderREnvelopUpper.Initialize
ShoulderREnvelopLower.Initialize
LoadFile("/mnt/external_sd", "Shoulder_5_18_11.txt", ShoulderI, ShoulderR, ShoulderREnvelopUpper, ShoulderREnvelopLower)
ButtonShoulder.Text = "Graph Shoulder"
ButtonShoulder.TextColor = Colors.Blue
Else If ButtonShoulder.Text = "Graph Shoulder" Then
'Dim GItime, GRtime, GIp As Graph
Dim GRtime As Graph
'GItime.Initialize
GRtime.Initialize
'InitializeGraph(GItime, "Shoulder Chart I", "Time(s)", "mmHg", ShoulderI.YMin, ShoulderI.YMax, (ShoulderI.YMax - ShoulderI.YMin)/5, Colors.Black)
'DrawLineChart(GItime, ShoulderI, Colors.White, PanelShoulderI)
InitializeGraph(GRtime, "Shoulder Chart R", "Time(s)", "AU", ShoulderR.YMin, ShoulderR.YMax, (ShoulderR.YMax - ShoulderR.YMin)/5, Colors.Black)
DrawLineChart(GRtime, ShoulderR, Colors.White, PanelShoulderR, ShoulderR.Points.Size)
'''''''''''''''''''Calculate FFT
' ShoulderIfft.Initialize
' ShoulderIfft.Target = PanelShoulderIfft
' ShoulderIfft.LinesColor = Colors.Green
ShoulderRfft.Initialize
ShoulderRfft.Target = PanelShoulderRfft
ShoulderRfft.LinesColor = Colors.Green
'CalcFFT(ShoulderI, ShoulderIfft, PanelShoulderIfft)
CalcFFT(ShoulderR, ShoulderRfft, PanelShoulderRfft)
''''''''''''''''''Jan 09 Graph FFT
'Dim GIfft, GRfft As Graph
'GIfft.Initialize
'InitializeGraph(GIfft, "Shoulder I FFT", "Hz", " ", ShoulderIfft.YMin, ShoulderIfft.YMax, (ShoulderIfft.YMax - ShoulderIfft.YMin)/5, Colors.Black)
'DrawLineChart(GIfft, ShoulderIfft, Colors.White, PanelShoulderIfft)
GRfft.Initialize
'InitializeGraph(GRfft, "Shoulder R FFT", "Hz", " ", ShoulderRfft.YMin, ShoulderRfft.YMax, (ShoulderRfft.YMax - ShoulderRfft.YMin)/5, Colors.Black)
InitializeGraph(GRfft, "Shoulder R FFT", "Hz", " ", ShoulderRfft.YMin, ShoulderRfft.YMax, (ShoulderRfft.YMax - ShoulderRfft.YMin)/5, Colors.Black)
'InitializeGraph(GRfft, "Shoulder R FFT", "Hz", " ", ShoulderRfft.YMin, ShoulderRfft.YMax, (ShoulderRfft.YMax - ShoulderRfft.YMin)/5, Colors.Black)
DrawLineChart(GRfft, ShoulderRfft, Colors.White, PanelShoulderRfft, ShoulderRfft.Points.Size)
End If
End Sub
Sub CalcFFT(DataArray As Data, DataFFT As Data, Panels As Panel)
Dim Points As Point
'Dim TimeRealY(DataArray.Points.Size), TimeImagY(DataArray.Points.Size), FFTReal(DataArray.Points.Size/2), FFTImag(DataArray.Points.Size/2) As Double
''''''Identify the size of array and delete the size to conform with FFT rule => point size power of 2
Dim FFTPointSize As Double
'FFTPointSize = Power(2, NumberFormat(Logarithm(DataArray.Points.Size, 2), 1, 0) - 1)
FFTPointSize = Power(2, NumberFormat(Logarithm(DataArray.Points.Size, 2), 1, 0))
'Msgbox(FFTPointSize & ", " & DataArray.Points.Size, "")
Dim TimeRealY(FFTPointSize), TimeImagY(FFTPointSize), FFTReal(FFTPointSize/2), FFTImag(FFTPointSize/2) As Double
'For i=0 To DataArray.Points.Size - 1
'For i= (DataArray.Points.Size - FFTPointSize) To DataArray.Points.Size - 1
For i = 0 To FFTPointSize - 1
If i < DataArray.Points.Size Then
Points = DataArray.Points.Get(i)
TimeRealY(i) = Points.Y
Else
TimeRealY(i) = 0
'TimeRealY(i - (DataArray.Points.Size - FFTPointSize)) = Points.Y
End If
Next
Dim FFTReal(TimeRealY.Length/2) As Double
Dim FFTImag(TimeRealY.Length/2) As Double
FFT.Transform2(TimeRealY, FFTReal, FFTImag)
Dim Ampl(0) As Double
Ampl = FFT.ToAmplitude(FFTReal, FFTImag)
Msgbox(Ampl.Length, "")
If DataFFT.IsInitialized = False Then
DataFFT.Initialize
End If
'DataFFT.Target.Initialize("FFT")
DataFFT.Points.Initialize
Dim PointFFT As Point
Dim interval As Double
Dim MaxY, MinY As Double
interval = DataArray.Interval
For i=0 To Ampl.Length - 1
Dim PointFFT As Point
If i = 0 Then
MaxY = Ampl(i)
'MaxY = FFTReal(i)
MinY = MaxY
End If
PointFFT.X = (i+1)/(2*interval*Ampl.Length)
PointFFT.Y = Ampl(i)
'PointFFT.Y = FFTReal(i)
PointFFT.ShowTick = (i Mod 100 = 0)
'If PointFFT.Y < 1.5 Then
DataFFT.Points.Add(PointFFT)
'End If
If Ampl(i) > MaxY Then
MaxY = Ampl(i)
End If
If MinY > Ampl(i) Then
MinY = Ampl(i)
End If
Next
DataFFT.YMax = MaxY
DataFFT.YMin = MinY
End Sub
Sub BandPassFilter(FFTData As Data, UpperBound As Double, LowerBound As Double)
ShoulderR.Points.Clear
'Reset minimum and maximum value
Dim numReset As Boolean :numReset = False
For i=0 To FFTData.Points.Size - 1
Dim tmpPoint As Point
tmpPoint = FFTData.Points.Get(i)
If tmpPoint.X < LowerBound OR tmpPoint.X > UpperBound Then
FFTData.Points.RemoveAt(i)
tmpPoint.Y = 0
FFTData.Points.InsertAt(i, tmpPoint)
'Msgbox(i & ": " & FFTData.Points.Size,"")
If FFTData.YMin > 0 Then
FFTData.YMin = 0
End If
Else
If numReset = False Then
FFTData.YMax = tmpPoint.Y
FFTData.YMin = tmpPoint.Y
numReset = True
Else
If tmpPoint.Y > FFTData.YMax Then
FFTData.YMax = tmpPoint.Y
End If
If tmpPoint.Y < FFTData.YMin Then
FFTData.YMin = tmpPoint.Y
End If
End If
End If
Next
End Sub
Sub LoadFile(FilePath As String, FileName As String, DataI As Data, DataR As Data, DataEnveUpper As DataEnvelop, DataEnveLower As DataEnvelop)
fd.FastScroll = True
fd.FilePath = FilePath
fd.FileFilter=".txt"
fd.ChosenName=FileName
'Choose file
ret = fd.Show("Choose a file to load:", "OKay", "Cancel", "", Null)
If ret = -3 OR fd.ChosenName = "" Then
Return
End If
If File.Exists(fd.FilePath, fd.ChosenName) = False Then
Msgbox(fd.ChosenName & " does not exist.", "")
Return
Else
'Identify File
Dim FileType() As String
Dim BeginOfData As Double
FileType = Regex.Split("_",FileName)
'Initialize Panel and DataSet
DataI.Initialize
DataI.Points.Initialize
DataI.Target.Initialize(FileType & "I")
DataR.Initialize
DataR.Points.Initialize
DataR.Target.Initialize(FileType & "R")
'Determine the beginning of data index of specific data type
If FileType(0) = "Shoulder" Then
BeginOfData = 9
Else
BeginOfData = 6
End If
'Read file
Dim ListTmp As List
ListTmp = File.ReadList(fd.FilePath, fd.ChosenName)
'Extract Interval value
Dim Tmp1 As Matcher
Tmp1 = Regex.Matcher("\d.\d+", ListTmp.Get(0))
Do While Tmp1.Find = True
Log(Tmp1.Match)
DataI.Interval = Tmp1.Match
DataR.Interval = Tmp1.Match
Loop
'Store max/min value
Dim MaxMin(4) As Double
'Store signal envelop trend
Dim lastSign As Boolean
Dim prevPoint As Double
DataEnveUpper.Initialize
DataEnveUpper.Points.Initialize
DataEnveLower.Initialize
DataEnveLower.Points.Initialize
'Extract I and R data and store into DataSet
For a = BeginOfData To ListTmp.Size - 1
Log(ListTmp.Get(a))
'extract data from string
Dim Tmp3(2) As String
Dim p,q As Point
p.Initialize
q.Initialize
Tmp3 = Regex.Split(" ",ListTmp.Get(a))
'Add line point
p.X = DataI.Interval*(a - BeginOfData + 1)
p.Y = Tmp3(0)
p.ShowTick = ((a - BeginOfData) Mod 1000 = 0)
DataI.Points.Add(p)
q.X = DataR.Interval*(a - BeginOfData + 1)
q.Y = Tmp3(1)
q.ShowTick = ((a - BeginOfData) Mod 1000 = 0)
DataR.Points.Add(q)
'Store Initial Max/Min data value
If a = BeginOfData Then
MaxMin(0) = Tmp3(0)
MaxMin(1) = Tmp3(0)
MaxMin(2) = Tmp3(1)
MaxMin(3) = Tmp3(1)
Else If a = BeginOfData + 1 Then
'check the first trend, positive if the new point is higher
If prevPoint < Tmp3(1) Then
lastSign = True
Else
lastSign = False
End If
Else
If lastSign = True Then
If prevPoint > Tmp3(1) Then
lastSign = False
DataEnveUpper.Points.Add(q)
End If
Else
'vice versa
If prevPoint < Tmp3(1) Then
lastSign = True
DataEnveLower.Points.Add(q)
End If
End If
If Tmp3(0) > MaxMin(0) Then
MaxMin(0) = Tmp3(0)
Else If MaxMin(1) > Tmp3(0) Then
MaxMin(1) = Tmp3(0)
End If
If Tmp3(1) > MaxMin(2) Then
MaxMin(2) = Tmp3(1)
Else If MaxMin(3) > Tmp3(1) Then
MaxMin(3) = Tmp3(1)
End If
'store the last Y value of R data
prevPoint = Tmp3(1)
End If
Next
End If
DataI.YMax = MaxMin(0)
DataI.YMin = MaxMin(1)
DataR.YMax = MaxMin(2)
DataR.YMin = MaxMin(3)
End Sub
'Sub InitializeGraph(LineGraph As Graph, Title As String, XAxis As String, YAxis As String, YStart As Float, YEnd As Float , YInterval As Double, AxisColor As Int)
Sub InitializeGraph(LineGraph As Graph, Title As String, XAxis As String, YAxis As String, YStart As Double, YEnd As Double , YInterval As Double, AxisColor As Int)
LineGraph.Title = Title
LineGraph.XAxis = XAxis
LineGraph.YAxis = YAxis
LineGraph.YStart = YStart
LineGraph.YEnd = YEnd
LineGraph.YInterval = YInterval
LineGraph.AxisColor = AxisColor
End Sub
Sub DrawLineChart(G As Graph, LD As Data, BackColor As Int, Panels As Panel, pointCount As Int)
LD.Board.Initialize(Panels)
LD.Board.DrawColor(BackColor)
drawGraph(G, LD.Board, Panels, LD.Points, LD, pointCount)
End Sub
Sub drawGraph(G As Graph, Board As Canvas, Target As View, Points As List, LD As Data, pointCount As Int)
Dim GI As GraphInternal
GI.Initialize
GI.gw = Target.Width - 10dip
GI.gh = Target.Height
GI.originX = 30dip
GI.originY = 2dip
GI.maxY = Target.Height - 5dip
GI.intervalX = GI.gw/(pointCount - 1)
'GI.intervalX = GI.gw/(points.Size - 1)
'Dummy data for testing, draw a diagonal line
'Board.DrawLine(GI.originX, GI.originY, GI.gw, GI.gh, G.AxisColor, 5dip)
'Draw Y axis boarder
Board.DrawLine(GI.originX, GI.originY + 2dip, GI.originX, GI.maxY, G.AxisColor, 2dip)
Board.DrawLine(GI.gw,GI.originY, GI.gw, GI.maxY, G.AxisColor, 2dip)
For i = 0 To 5
Dim y As Int
'Dim yValue As Float
Dim yValue As Double
'yValue = G.YStart + G.YInterval * (4 - i)
yValue = LD.YMin + G.YInterval * (5 - i)
If yValue > g.YEnd Then Continue
y = GI.originY + ((GI.maxY- 5dip)/5)*i
Board.DrawLine(GI.originX, y, GI.originX - 5dip, y, G.AxisColor, 2dip)
Board.DrawLine(GI.originX, y, Target.Width, y, G.AxisColor, 1dip)
Board.DrawText(NumberFormat(yValue, 1, 1), GI.originX - 5dip, y + 10dip, Typeface.DEFAULT, 12, G.AxisColor, "RIGHT")
Next
Board.DrawLine(GI.originX, GI.originY, Target.Width, GI.originY, G.AxisColor, 2dip)
Board.DrawLine(GI.originX, GI.maxY, Target.Width, GI.maxY, G.AxisColor, 2dip)
'Draw X Axis label
'For i = 0 To Points.Size - 1
For i = 0 To pointCount - 1
Dim p As Point
p = Points.Get(i)
If p.ShowTick Then
Dim x As Int
x = GI.originX + i*GI.intervalX
Board.DrawLine(x, GI.originY, x, GI.originY + 5dip, G.AxisColor, 2dip)
Board.DrawLine(x, GI.originY, x, GI.maxY, G.AxisColor, 1dip)
If p.X.Length > 0 Then
Board.DrawTextRotated(NumberFormat(p.X, 0, 2), x, GI.originY + Target.Height - 30dip, Typeface.DEFAULT, 10, G.AxisColor, "RIGHT", -45)
End If
End If
Next
Dim dataPoint As Point
dataPoint = LD.Points.Get(0)
'Dim py As Float
Dim py As Double
py = dataPoint.Y
Dim y1,y2 As Int
'For i = 1 To LD.Points.Size - 1
For i = 1 To pointCount - 1
dataPoint = LD.Points.Get(i)
y1 = GI.originY + (py - LD.YMax)*(GI.maxY - 5dip - GI.originY)/(LD.YMin - LD.YMax)
y2 = GI.originY + (dataPoint.Y - LD.YMax)*(GI.maxY - 5dip - GI.originY)/(LD.YMin - LD.YMax)
'Board.DrawLine(GI.originX + GI.intervalX*(i-1), calcPointToPixel(py, G, LD.YMax, LD.YMin), GI.originX + GI.intervalX*i, calcPointToPixel(dataPoint.Y, G, LD.YMax, LD.YMin), Colors.Blue, 2dip)
Board.DrawLine(GI.originX + GI.intervalX*(i-1), y1, GI.originX + GI.intervalX*i, y2, Colors.Blue, 2dip)
py = dataPoint.Y
Next
LD.Target.Invalidate
Msgbox("Done Graphing", "")
End Sub
'Sub calcPointToPixel(py As Float, G As Graph, YMax As Float, YMin As Float) As Int
Sub calcPointToPixel(py As Float, G As Graph, YMax As Double, YMin As Double) As Int
Return G.GI.originY + 1000*(YMax - py)*(G.GI.maxY - G.GI.originY)/(YMax - YMin) + 150dip
End Sub
Sub ButtonFilterRespiration_Click
BandPassFilter(ShoulderRfft, 0.7, 0.1)
InitializeGraph(GRfft, "Shoulder R FFT", "Hz", " ", ShoulderRfft.YMin, ShoulderRfft.YMax, (ShoulderRfft.YMax - ShoulderRfft.YMin)/5, Colors.Black)
DrawLineChart(GRfft, ShoulderRfft, Colors.White, PanelShoulderRfft, ShoulderRfft.Points.Size)
End Sub