Monday, January 28, 2013

Hypoplasia: Improved Algorithm Explained


Let's take a closer look at my outlier ignoring algorithm.  First, let's look at what is going on in the photo.  The tiny dots every are the data points gathered during a simulated left hand test.  The slightly transparent purple regions are the regions the algorithm "deletes" from the list of valid data points.  The cyan dot is the average point from the available data and the cyan lines are the lines made by the Cartesian coordinate system centered at the average point (I am aware that the cyan dot in this picture is not in the exact average location, but it is close enough to illustrate how the algorithm works).  The red numbers number each quadrant.


First off, the algorithm finds the average point of the collected data.  That point should be inside the circle made by the arc.  Next, the algorithm determines which hand is being tested.  In the screenshot, it uses the average point, but I have since changed it to use the first data point because patients start with their thumb along the side of the device and sweep their thumb towards themselves.  The change was made to accomodate smaller devices in which the test may take up the entire screen.  Once the average point and the hand being tested are found, the algorithm deletes all data in the 3rd quadrant for left handed tests and the 4th quadrant for right handed tests.  This region is represented by the semi-transparent magenta rectangle in the screenshot of the app.  A collection of data points along the edge of the screen is common during tests on smaller devices, but not on tablets, because the palm comes in contact with the screen.  

Second, the algorithm uses some statistics to calculate the maximum allowed distances between valid data points.  I have yet to take a stats class, so I used a formula that I found on Yahoo Answers.  I really wish my school offered AP Stats...

Third, the algorithm checks all remaining data points to see if they have a neighbor within the allowed maximum distance.  If they do, then the data point is assumed to be valid.  This caused problems earlier with the palm's invalid data points because they had neighbors within the allowed maximum distance, but they were all invalid data points.  But if the data point does not have a neighbor within the specified distance, then it is discarded.  In the screenshot of the app, you can see data points discarded by this part of the algorithm highlighted in a semi-transparent magenta circle.

That pretty much sums up the algorithm.  It can be processor intensive, especially the third part because of the number of calculations involved, but since the user starts the process by clicking on the "analyze data" button I'm not too worried if it takes a second or two to finish.

Thanks for stopping by!

Chris Konstad

Update: Robotics, Thumb Hypoplasia, Algorithms, etc.


I've been busy recently with school work, Robotics and working on the thumb hypoplasia app.  My homework load is manageable, but it keeps me busy (thank you, AP classes).

As far as Robotics goes, we've been having double workdays so that we can get in the water a little early, and we're making the most complex ROV we've ever had.  We are designing and making many parts that we used to buy commercially, and we are packing more electronics onboard the ROV than we *ever* have before.  This ROV is going to have more processing power than my first computer (a Win98 SE hand-me-down).  To top it all off, we have the absolute COOLEST electronics canister.  It honestly belongs in a Sci-Fi movie!  I wish I could post some pictures, but you'll have to wait for our team's official tech report.  Sorry!

The lab that I'm working with for the thumb hypoplasia app recently got a Samsung Galaxy Player, so I've been busy optimizing the app for their screen size and making changes as they report issues discovered during their field testing.  For example, on my A500 (10.1" tablet), there were no accidental touches by the palm on the edge of the screen, but on the Galaxy Player it is quite easy to accidentally touch the edge.  I worked out a function last night to remove one outlying point.  I need to modify the algorithm because it only works for a single outlying point and it needs to be able to remove many.  Here's an explanation of the function:

It takes a little time to execute when there are many data points to check, but that doesn't really affect the user experience as it is only run when the user tells the app to analyze the data.

This summer, I plan to work on many projects.  I want to finish the Git client during summer vacation, and I'd really like to finish porting Monterey to Android.  I also want to tweak ROV-Suite to add in some Raspberry Pi fun (probably on the bottomside).

Thanks for stopping by!

Chris Konstad


Tuesday, January 1, 2013

Android Git Client (GUI)


Great news!  I've started working on a GUI Git client for Android devices.  Right now, all it does is install Git and then display the version, but I'll expand on the feature set in the coming months.  It is written in Qt using Necessitas.  Right now, I use wget (from BusyBox, I believe) to download a Git binary, but I plan on writing a downloader class to handle that because stock Android does not have wget (or that's what my testing has shown).  The UI then passes commands to the git binary using QProcess.  Yes, this is not the most elegant way to handle Git, but it works.  Also, this will let me expose the entire feature set of Git to the GUI.  You can find the source for it here.  Please keep in mind that the current app is currently in a proof-of-concept state, so the code may be a little sloppy.  Sorry about that!  I'll be cleaning up the current code as I flesh out this app.

You can find the proof-of-concept build here.  When you run it, please be patient with the initial black screen!  I need to show a progress indicator for the git binary download, but right now there is no indication that the app is running.  It should show a black screen for a few seconds while it downloads the 5.5MB binary.

Thanks for stopping by!

Chris Konstad

Monday, December 31, 2012

Update

Although I've been on break for school for the past week, I haven't been able to do any programming because I've been helping my dad and friend replace the roof of our RV.  It's been an intense project!  Today was the first day that I had free from working on it, and I've spent most of it programming.

For my robotics team, I spent today playing around with the WiringPi library on my Raspberry Pi.  We want to have access to it's GPIO so we can use it as an embedded microcontroller onboard our ROV.  The GPIO utility it has (for turning on inputs and outputs from Bash) is pretty awesome!  I'm looking forward to writing some interesting embedded Qt apps for this.

I also found out today that my Raspberry Pi has a habit of breaking off the corner of my SD cards (above the contacts on the corner with the write-lock).  Debugging that issue took up a fair amount of time, sadly.  If you have the same issue, just take a piece of paper and put it between the SD card and the SD card holder (but not between the SD card and the contacts).  That will apply just enough pressure to maintain contact.

I'm looking into writing a Git client for Android devices at some point (probably this summer).  I tried to do a proof of concept today using QProcess to launch the Git executable that came with TerminalIDE (there is a Qt Git library, libqgit2, but it won't even compile on my Kubuntu VM), but I kept running into issues.  Hopefully I'll be able to resolve them and start working on the app soon!

Thanks for stopping by and expect more Android apps soon,

Chris K

Edit:  I just made a Qt app (for Android) that can execute Git commands.... (right now just the installed version).  User must have TerminalIDE installed for this build to work, but I plan on changing that soon.  Happy New Year!

Sunday, December 16, 2012

Thumb Hypoplasia Update




I've been doing a lot of work recently on updating my hypoplasia app, and the results are looking pretty good!  It can now calculate the center point of the circle that fits the arc, calculate an average radius and use that information to calculate the range of motion of the patient's thumb.  It uses averages of many calculated center points (each one calculated from 3 randomly selected data points) to find the center point of the circle.  Then, it averages the radii from each datapoint to the center point to find the average radius.  Once it draws the circle on the screen, it uses some trig to calculated the range of motion of the thumb (from straight up to the blue line).  I've written the app to ignore extraneous data points (i.e. points caused by QPushButton clicks being registered on the QGraphicsScene).  I also greatly improved performance of the QGraphicsView by removing all anti-aliasing and by changing when data points are recorded.  All in all, it is working out pretty well right now!  I just need to get it tested in the clinical environment.  I plan on putting it on Google Play sometime this Christmas break.

If you'd like to download the current version of it (0.3.1), you can get it here.

The GUI theme looks very different from previous versions because I used Necessitas Alpha 4.1 instead of Alpha 3.

Thanks for stopping by!

Chris Konstad

Tuesday, November 27, 2012

Thumb Hypoplasia App: V0.2.0


I updated my Thumb Hypoplasia app to version 0.2.0 today.  This update brings more optimizations (non-antialiased text, for example) other other tweaks to improve performance.  My goal is to take exactly 10 samples per second on a variety of hardware so that each data point specifies a known point in time.  Also, I added a display of the current trial's ID number next to the test information text.

You can find the source code here.

Thanks for stopping by!

Chris Konstad

Tuesday, November 20, 2012

Thumb Hypoplasia: First Test


I found out today that one of my friends has thumb hypoplasia (diagnosed with Type 1).  Since I had my tablet with a beta build of my thumb hypoplasia app, we decided to try it out and see how well it worked.

I am not a doctor or a medically trained professional.  I am a high school student who loves science and programming.  The following analysis of the data is my interpretation of the data. I have received permission from my friend ("the patient") to post this information here.

The patient told me that he has type 1 thumb hypoplasia in his right hand only.  To run this test, the patient held my Acer A500 (10.1" screen) in both hands in the landscape position.  The full application looks like this:


He swept each thumb, one at a time, across the screen in an arc that started with his thumb parallel to the edge of the screen.



My software recorded his thumb position roughly ten times a second.  The slow sample rate is due to the painting of the "data field" (the area with the grid).  Once I learn how to cache the background pixmap of a QGraphicsScene, then I can increase the performance of this app.  Once he was done with swiping his thumbs across the screen, I saved the data as a *.png and the test was over.

Once home, I started to analyze the data that I had just taken.  I printed it out to the proper size (with each grid box being one square centimeter) and began taking measurements.  


I printed out the data field image (life sized, I checked it with a pair of calipers) and used a pair of calipers and a compass to obtain my measurements.  You can see the calculations overlayed on the data above (Keep in mind that the bezel of the tablet moved the centers of the circles off of the data field.  By printing out the data field image on an 8.5" by 11" piece of paper, I had enough room to the sides to find the center of the circles using a compass.  The area calculations include the area off-screen).  The afflicted thumb (right hand) has 86% of the range of motion (ROM) of the non-afflicted thumb on the plane that we measured on.  

The patient told me during the test that he has a smaller abductor pollicis brevis, which would result in a weaker abduction of the thumb manifested in a smaller angle of abduction from the starting position (aligned with the side of the palm, parallel to the index finger).  The data gathered from this test shows that symptom.  In other words, my app works (so far)!  


My application gathers data at a relatively constant rate that varies by device (because of the screen painting time).  In the future, I hope to make each data point represent the same change in time no matter which device it is used on, but that's lower on my list of priorities at the moment.  What you can see here, though, is how hard the patient had to work to force his thumb to sweep across the screen.  The data points on both thumbs end (at the bottom of the arc) with a much closer grouping than they do at the middle of the arc.  Therefore, one can deduce that the patient was struggling harder at the end of the arc to try to push his thumb as far as it could go.  On the non-afflicted side, the close grouping at the end is only 8mm long.  On the afflicted side, however, it is 13mm long.  The tighter the grouping near the end, the harder the patient was trying to move his thumb.  The data shows us that the patient struggled harder to abduct his afflicted thumb than his non-afflicted thumb, which supports the conclusion of a smaller abductor pollicis brevis. 

The tighter grouping of the data points at the beginning of the arc (at the top) can be explained by a slow velocity as the thumb accelerates during its sweeping motion.  The generally tighter grouping of the afflicted side versus the non-afflicted side can probably be attributed to the fact that the patient did the first test with his afflicted side.  He wasn't familiar with the testing process, so he did not know how fast he could move his thumb.  More tests are needed to confirm these hypotheses.

All of my interpretations are based on a single test with only one trial, which means that the data could be inaccurate.  More testing is needed to see how effective this application will be, but these are definitely promising first results!   One of my goals for this application is to automate the data analysis process.  I also want to optimize how the data field is rendered so that each data point is taken at a known time interval.

Thanks for stopping by!

Chris Konstad