Archive for the 'UCF Lab' Category
Graphing Computer Usage
Posted by Scott May 20th, 2009 | 5,253 words | No Comments »
I’m a big fan of writing Python scripts to analyze huge volumes of linear data. It’s a sick addiction. One of my favorite blog entries is Linear Data Smoothing with Python, developed for my homemade electrocardiogram project. Anyway, I installed the free Windows program TimeTrack.exe on my work computer. I can’t remember why I installed it – this looks like pretty crappy software – but I did nonetheless. It basically logs whenever you open or close a program. The data output looks like this:
"Firefox","Prototype of a Digital Biopsy Device - Mozilla Firefox","05/19/2009 9:45a","05/19/2009 9:45a","766ms","0.0"
"Firefox","Dual-Channel Mobile Surface Electromyograph - Mozilla Firefox","05/19/2009 9:46a","05/19/2009 9:46a","797ms","0.0"
"Windows Explorer","","03/24/2008 9:30a","05/19/2009 9:48a","49d 6h 9m","20.7"
"Windows Explorer","09_04_07_RA_SA_AV","05/19/2009 8:48a","05/19/2009 8:48a","1.0s","0.0"
"Windows Explorer","Image003.jpg - Windows Picture and Fax Viewer","05/18/2009 4:03p","05/18/2009 4:03p","1.2s","0.0"
I have a 13mb file containing lines like this which I parse, condense, analyze, re-parse, and graph with a Python script I just wrote. Briefly it finds the first and last entry time and creates a dictionary object whose keys are the hours between the 1st and last log lines, parses the log, determines which time block each entry belongs to, and increments the integer (value of the dictionary) for its respective key. Something similar is repeated, but with respect to days rather than hours. The result is:

I’d like to thank Python, Numpy, and of course my all-time-favorite software in the world, MatPlotLib. The code I used to generate the graph above is here:
# This script analyzes data exported from "TimeTrack" (a free computer usage
# monitoring program for windows) and graphs the data visually.
import time, pylab, datetime, numpy
# This is my computer usage data. Generate yours however you want.
allHours = ['2008_10_29 0', '2009_03_11 5', '2009_04_09 5', '2008_07_04 10',
'2008_12_18 9', '2009_01_30 12', '2008_09_04 7', '2008_05_17 1',
'2008_05_11 5', '2008_11_03 3', '2008_05_21 3', '2009_02_19 11',
'2008_08_15 13', '2008_04_02 4', '2008_07_16 5', '2008_09_16 8',
'2008_04_10 5', '2009_05_10 1', '2008_12_30 4', '2008_06_07 2',
'2008_11_23 0', '2008_08_03 0', '2008_04_30 4', '2008_07_28 9',
'2008_05_19 0', '2009_03_30 7', '2008_06_19 3', '2009_01_24 3',
'2008_08_23 6', '2008_12_01 0', '2009_02_23 6', '2008_11_27 0',
'2008_05_02 5', '2008_10_20 13', '2008_03_27 5', '2009_04_02 9',
'2009_02_21 0', '2008_09_13 1', '2008_12_13 0', '2009_04_14 11',
'2009_01_31 7', '2008_11_04 10', '2008_07_09 6', '2008_10_24 10',
'2009_02_22 0', '2008_09_25 12', '2008_12_25 0', '2008_05_26 4',
'2009_05_01 10', '2009_04_26 11', '2008_08_10 8', '2008_11_08 6',
'2008_07_21 12', '2009_04_21 3', '2009_05_13 8', '2009_02_02 8',
'2008_10_07 2', '2008_06_10 6', '2008_09_21 0', '2009_03_17 9',
'2008_08_30 7', '2008_11_28 4', '2009_02_14 0', '2009_01_22 6',
'2008_10_11 0', '2008_06_22 8', '2008_12_04 0', '2008_03_28 0',
'2009_04_07 2', '2008_09_10 0', '2008_05_15 5', '2008_08_18 12',
'2008_10_31 5', '2009_03_09 7', '2009_02_25 8', '2008_07_02 4',
'2008_12_16 7', '2008_09_06 2', '2009_01_26 5', '2009_04_19 0',
'2008_07_14 13', '2008_11_01 5', '2009_01_18 0', '2009_05_04 0',
'2008_08_13 10', '2009_02_27 3', '2009_01_16 12', '2008_09_18 8',
'2009_02_03 7', '2008_06_01 0', '2008_12_28 0', '2008_07_26 0',
'2008_11_21 1', '2008_08_01 8', '2008_04_28 3', '2009_05_16 0',
'2008_06_13 5', '2008_10_02 11', '2009_03_28 6', '2008_08_21 7',
'2009_01_13 6', '2008_11_25 4', '2008_06_25 1', '2008_10_22 11',
'2008_03_25 6', '2009_02_07 6', '2008_12_11 4', '2009_01_01 4',
'2008_09_15 2', '2009_02_05 12', '2008_07_07 9', '2009_04_12 0',
'2008_04_11 5', '2008_10_26 4', '2008_05_28 3', '2008_09_27 14',
'2009_05_03 0', '2008_12_23 5', '2009_05_12 10', '2008_11_14 3',
'2008_07_19 0', '2009_04_24 8', '2008_04_07 1', '2008_08_08 11',
'2008_06_04 0', '2009_05_15 12', '2009_03_23 13', '2009_02_01 10',
'2008_09_23 11', '2009_02_08 3', '2008_08_28 4', '2008_11_18 9',
'2008_07_31 7', '2008_10_13 0', '2008_06_16 9', '2009_03_27 6',
'2008_12_02 0', '2008_05_01 7', '2009_04_05 1', '2008_08_16 9',
'2009_03_15 0', '2008_04_16 6', '2008_10_17 4', '2008_06_28 5',
'2009_01_28 10', '2008_04_18 0', '2008_12_14 0', '2008_11_07 6',
'2009_04_17 7', '2008_04_14 7', '2008_07_12 0', '2009_01_15 7',
'2009_05_06 8', '2008_12_26 0', '2008_06_03 7', '2008_09_28 0',
'2008_05_25 4', '2008_08_07 8', '2008_04_26 7', '2008_07_24 1',
'2008_04_20 0', '2008_11_11 4', '2009_04_29 0', '2008_10_04 0',
'2009_05_18 9', '2009_03_18 4', '2008_06_15 8', '2009_02_13 6',
'2008_05_04 5', '2009_03_04 2', '2009_03_06 3', '2008_05_06 0',
'2008_08_27 11', '2008_04_22 0', '2009_03_26 6', '2008_03_31 9',
'2008_06_27 5', '2008_10_08 4', '2008_09_09 4', '2008_12_09 3',
'2008_05_10 0', '2008_05_14 5', '2009_04_10 0', '2009_01_11 0',
'2008_07_05 8', '2009_01_05 7', '2008_10_28 0', '2009_02_18 11',
'2009_03_10 7', '2008_05_30 3', '2008_09_05 7', '2008_12_21 6',
'2009_03_02 6', '2008_08_14 5', '2008_11_12 5', '2008_07_17 8',
'2008_04_05 6', '2009_04_22 11', '2009_05_09 0', '2008_06_06 0',
'2009_01_03 0', '2008_09_17 6', '2009_03_21 3', '2009_02_10 7',
'2008_05_08 4', '2008_08_02 0', '2008_11_16 0', '2008_07_29 12',
'2008_10_15 5', '2008_06_18 5', '2009_03_25 2', '2009_01_10 0',
'2009_04_03 5', '2008_08_22 7', '2009_03_13 11', '2008_10_19 0',
'2008_06_30 8', '2008_09_02 9', '2008_05_23 4', '2008_12_12 7',
'2008_07_10 11', '2008_11_05 8', '2008_04_12 4', '2009_04_15 7',
'2008_12_24 1', '2008_09_30 0', '2008_05_27 2', '2008_08_05 10',
'2008_04_24 6', '2009_04_27 6', '2008_07_22 3', '2008_11_09 1',
'2008_06_09 6', '2008_10_06 14', '2009_03_16 7', '2008_05_22 5',
'2009_01_29 12', '2008_11_29 4', '2008_04_09 7', '2008_08_25 12',
'2009_02_15 0', '2008_03_29 7', '2008_06_21 7', '2008_10_10 9',
'2008_05_12 6', '2009_02_16 10', '2008_09_11 11', '2008_12_07 0',
'2008_07_03 6', '2009_04_08 3', '2009_01_23 7', '2009_01_27 5',
'2008_10_30 0', '2009_03_08 0', '2009_01_21 8', '2008_12_19 0',
'2008_05_16 2', '2009_01_25 1', '2009_02_26 5', '2008_09_07 2',
'2008_04_03 1', '2008_08_12 6', '2008_04_13 10', '2008_11_02 0',
'2008_07_15 0', '2009_04_20 3', '2009_02_24 10', '2009_05_11 8',
'2008_12_31 8', '2008_04_15 7', '2008_09_19 10', '2009_01_19 0',
'2008_11_22 3', '2008_07_27 2', '2009_02_04 7', '2009_03_31 1',
'2008_05_24 3', '2008_10_01 8', '2008_06_12 6', '2009_01_12 11',
'2008_11_26 8', '2009_04_01 10', '2009_02_28 0', '2008_08_20 6',
'2008_10_21 10', '2008_06_24 4', '2008_03_26 4', '2008_12_10 0',
'2008_09_12 0', '2008_05_09 7', '2009_02_17 7', '2008_07_08 6',
'2008_10_25 5', '2009_04_13 9', '2009_05_02 0', '2008_12_22 8',
'2008_09_24 9', '2009_01_20 5', '2008_11_15 6', '2009_04_25 10',
'2008_08_11 9', '2008_04_06 8', '2008_07_20 1', '2009_03_22 3',
'2008_06_11 6', '2008_09_20 3', '2009_05_14 10', '2008_11_19 0',
'2008_08_31 2', '2009_02_09 8', '2008_10_12 0', '2008_04_25 5',
'2008_06_23 4', '2009_01_07 8', '2008_08_19 0', '2008_12_05 2',
'2008_07_01 8', '2008_10_16 6', '2009_04_06 3', '2009_03_14 5',
'2008_09_01 2', '2008_12_17 14', '2008_05_18 7', '2008_04_01 2',
'2009_04_18 0', '2008_04_17 0', '2008_07_13 0', '2008_06_02 10',
'2008_09_29 6', '2008_12_29 0', '2009_05_05 8', '2008_04_19 0',
'2009_04_30 8', '2008_08_06 4', '2008_11_20 0', '2008_07_25 6',
'2009_02_06 6', '2009_03_29 3', '2009_05_17 0', '2009_03_19 7',
'2008_10_03 1', '2008_06_14 3', '2008_05_07 5', '2008_08_26 3',
'2008_11_24 9', '2008_04_21 8', '2008_04_23 4', '2008_10_23 11',
'2008_06_26 4', '2008_03_24 8', '2008_12_08 5', '2008_09_14 2',
'2009_01_02 6', '2008_04_08 0', '2008_10_27 6', '2009_04_11 0',
'2008_07_06 0', '2008_12_20 3', '2009_04_23 6', '2008_09_26 9',
'2008_05_31 0', '2008_07_18 4', '2008_11_13 6', '2008_08_09 2',
'2008_04_04 0', '2009_03_20 5', '2008_09_22 7', '2009_05_08 9',
'2008_06_05 7', '2008_07_30 7', '2008_11_17 10', '2008_05_03 0',
'2008_08_29 3', '2009_02_11 12', '2009_01_08 8', '2008_06_17 0',
'2008_10_14 7', '2009_03_24 11', '2008_08_17 6', '2008_12_03 0',
'2009_01_09 4', '2008_05_29 5', '2008_06_29 9', '2008_10_18 5',
'2009_04_04 0', '2008_12_15 10', '2009_03_12 0', '2009_03_05 7',
'2008_05_20 4', '2008_09_03 7', '2009_03_07 8', '2009_01_14 6',
'2008_05_05 5', '2008_11_06 7', '2008_07_11 6', '2009_04_16 9',
'2009_02_20 0', '2008_12_27 0', '2009_01_17 0', '2009_05_07 7',
'2008_11_10 5', '2008_07_23 11', '2009_04_28 0', '2008_04_27 2',
'2008_08_04 0', '2009_03_01 11', '2008_10_05 0', '2008_06_08 8',
'2009_05_19 5', '2008_04_29 4', '2008_11_30 0', '2009_01_06 8',
'2009_02_12 3', '2008_08_24 2', '2009_03_03 10', '2008_10_09 6',
'2008_06_20 2', '2008_05_13 10', '2008_12_06 0', '2008_03_30 7']
def genTimes():
## opens exported timetrack data (CSV) and re-saves a compressed version.
print "ANALYZING..."
f=open('timetrack.txt')
raw=f.readlines()
f.close()
times=["05/15/2009 12:00am"] #start time
for line in raw[1:]:
if not line.count('","') == 5: continue
test = line.strip("n")[1:-1].split('","')[-3].replace(" "," ")+"m"
test = test.replace(" 0:"," 12:")
times.append(test) #end time
test = line.strip("n")[1:-1].split('","')[-4].replace(" "," ")+"m"
test = test.replace(" 0:"," 12:")
times.append(test) #start time
times.sort()
print "WRITING..."
f=open('times.txt','w')
f.write(str(times))
f.close()
def loadTimes():
## loads the times from the compressed file.
f=open("times.txt")
times = eval(f.read())
newtimes=[]
f.close()
for i in range(len(times)):
if "s" in times[i]: print times[i]
newtimes.append(datetime.datetime(*time.strptime(times[i],
"%m/%d/%Y %I:%M%p")[0:5]))
#if i>1000: break #for debugging
newtimes.sort()
return newtimes
def linearize(times):
## does all the big math to calculate hours per day.
for i in range(len(times)):
times[i]=times[i]-datetime.timedelta(minutes=times[i].minute,
seconds=times[i].second)
hr = datetime.timedelta(hours=1)
pos = times[0]-hr
counts = {}
days = {}
lasthr=pos
lastday=None
while pos1:counts[pos]=1 #flatten
if not daypos in days: days[daypos]=0
if not lasthr == pos:
if counts[pos]>0:
days[daypos]=days[daypos]+1
lasthr=pos
pos+=hr
return days #[counts,days]
def genHours(days):
## outputs the hours per day as a file.
out=""
for day in days:
print day
out+="%s %in"%(day.strftime("%Y_%m_%d"),days[day])
f=open('hours.txt','w')
f.write(out)
f.close()
return
def smoothListGaussian(list,degree=7):
## (from an article I wrote) - Google "linear data smoothing with python".
firstlen=len(list)
window=degree*2-1
weight=numpy.array([1.0]*window)
weightGauss=[]
for i in range(window):
i=i-degree+1
frac=i/float(window)
gauss=1/(numpy.exp((4*(frac))**2))
weightGauss.append(gauss)
weight=numpy.array(weightGauss)*weight
smoothed=[0.0]*(len(list)-window)
for i in range(len(smoothed)):
smoothed[i]=sum(numpy.array(list[i:i+window])*weight)/sum(weight)
pad_before = [smoothed[0]]*((firstlen-len(smoothed))/2)
pad_after = [smoothed[-1]]*((firstlen-len(smoothed))/2+1)
return pad_before+smoothed+pad_after
### IF YOU USE MY DATA, YOU ONLY USE THE FOLLOWING CODE ###
def graphIt():
## Graph the data!
#f=open('hours.txt')
#data=f.readlines()
data=allHours
data.sort()
f.close()
days,hours=[],[]
for i in range(len(data)):
day = data[i].split(" ")
if int(day[1])<4: continue
days.append(datetime.datetime.strptime(day[0], "%Y_%m_%d"))
hours.append(int(day[1]))
fig=pylab.figure(figsize=(14,5))
pylab.plot(days,smoothListGaussian(hours,1),'.',color='.5',label="single day")
pylab.plot(days,smoothListGaussian(hours,1),'-',color='.8')
pylab.plot(days,smoothListGaussian(hours,7),color='b',label="7-day gausian average")
pylab.axhline(8,color='k',ls=":")
pylab.title("Computer Usage at Work")
pylab.ylabel("hours (rounded)")
pylab.legend()
pylab.show()
return
#times = genTimes()
#genHours(linearize(loadTimes()))
graphIt()
In other news, I managed to locate the patent for the Nintendo 64 Video Game Console – how funny is that?
Proofing Scientific Literature
Posted by Scott May 7th, 2009 | 5,253 words | 1 Comment »
Man, what a long day! Work is so tedious sometimes. This week I’ve been proofing scientific literature (revising scientific manuscripts in an attempt to improve them as much as possible to increase their probability of acceptance and timely publication). I’ve been using Office 2003 (with “track changes”) to do this. I make changes, my boss makes changes, I make more changes, and it goes back and forth a few times. I wonder why office 2007 is so bad. Does anybody truly like it, and find it to be a significant improvement upon 2003? … or Vista over XP? [sigh] Maybe I’m just getting old, inflexible, and grumpy.
Here, take a look at what I’m working on [snapps screenshot]. I had to blur the content for intellectual property protection and to avoid possible future copyright violations. The light bubbles on the right are deletions. The dark bubbles on the right are comments. The red text is insertions/modifications I made. Pretty intense, huh? Pages and pages of this. And, upon successful completion of a manuscript, my reward is to begin working on another one! Luckily we’re almost caught-up on manuscripts… but that means we get to start writing grants… I’m starting to grasp the daunting amount of time a scientist must spend writing in the laboratory as opposed to performing actual experiments or even doing literature research.
Last night I assembled a Pixie II circuit similar to the one pictured here. I must say that I’m a little disappointed with the information available on the internet regarding simple RF theory in relation to transceiver circuits. I’m probably just not looking in the right places though. (Yes, I know about the ARRL handbook.) The thing is that I’m just now starting to get into RF circuitry and the concept looking at solid-state circuits and imagining a combination of AC and DC flowing through it is warping my brain. I have everything I need to build an ultra-simple Pixie II transceiver (which is supposedly capable of morse code transmissions over 300 miles, and QRSS applications over 3,000 miles) but I refuse to use it. No, it’s not because of moral obligations preventing me from powering it up before I get a general class radio license (shhhh). It’s because building something is useless unless you understand what you’re building.
I’m trying to break this circuit down into its primary components. I understand the role of the lowpass pi filter (before antenna). I understand the role of the 1st transistor and related circuitry in amplifying the output of the oscillator (left side). I totally get the audio amplifier circuitry (bottom). It’s that center transistor (which supposedly handles signal amplification, receiving, and mixing) that I can’t get my mind around. Every time I think figure it out for one mode (sending or receiving), I lose the other one, and visa versa. It has me very frustrated (and a little depressed about the whole thing) because this should be much easier than I’m making it. There’s no thourough documentation on this circuit! I selected it because it was extremely simple and I assumed I’d be smart enough to figure it out. I guess I was wrong. I wish I had an oscilloscope so I could probe the RF passing through various stages of this circuit [sigh]. Back to the ARRL handbook. Maybe if I read chapters 5-11 a couple more times I’ll magically understand it.

Momentary Silence
Posted by Scott March 23rd, 2009 | 5,253 words | No Comments »
My public writing project is still on hiatus. For now, I need to concentrate on completing my degree requirements. I anticipate that graduation will be in order by next week. Until then, hold on a bit longer, and brace yourself for an outpouring of blogs related to obscure and geeky projects. In the mean time, this is what I’m working on, and sure you’re invited. It’s at the University of Central Florida in Orlando, Florida. Show up, say you’re from my blog, and I’ll buy you a round after the examination!

Thesis Countdown Continues…
Posted by Scott March 11th, 2009 | 5,253 words | No Comments »
Today is the much-awaited day of anticipation, mystery, excitement, and dread. Yes, today is the day that I will sit down (with the intent to) actually begin writing the content of my master’s thesis. Molecular biology is one of the most boring subjects invented. Luckily, my thesis has little to do with molecular biology and more to do with cardio-neurological anatomy.
Today is Wednesday. Supposedly one week from Friday (9 days from now) the thesis should be complete and turned in. I have my work cut out for me. Luckily, the outline of the thesis is already finished, and I believe I have all the representative figures I will need. Yesterday my PI (principal investigator, aka: lab manager, aka: my boss!) told me that my paper (which I’ve neatly compiled into the outline of a single document) would be better if it were split into 3 documents, and published as 3 separate papers (one for sympathetic findings, one for parasympathetic findings, and one for findings involving sympathetic/parasympathetic interaction). I guess my plan is to proceed as originally planned, writing a single paper for my thesis, then splitting it up into 3 and sending them off for review/publication after I graduate.
I’m counting the days until I’ve fulfilled my thesis requirements and have graduated. I cannot wait! Why? Am I excited because I’ll finally have a masters degree? no. Am I excited because a lot of the academic pressures in my life will be temporarily relieved? no. Am I excited because I, having graduated in 19 months will have set the new department record (the current fastest thesis-track molecular biology masters graduate took 22 months)? no. Well why then, why are you so excited about finishing. BECAUSE IT GIVES ME TIME TO WORK ON MY PROJECTS! I have a huge list of projects I’ve wanted to work on but couldn’t (or decided not to) because I wanted to devote all of my time to graduating. I can’t wait! First and foremost, I’ve definitely decided I want to dip my toe into the field of amateur radio (AR). I know what you’re picturing – a bunch of old guys sitting around wooden desks with 50’s style microphones and headphones jabbering about little things over the airwaves (like how good Catfish Cory’s is, or how some guy is in a fight with his cable company over his service, or why gator tail tastes so much like chicken). For the most part, your image is probably correct. However, why not get into it? I’ve done the comptuer thing. I’ve done the linux thing. I’ve done the computer programming thing. Heck, I’ve even done the microchip programming thing. But radio? There’s something I know absolutely nothing about, and I can’t stand it! I don’t feel the need to be a crazy obsessed expert, but I definitely want to have an advanced working knowledge of the concepts.
From my [very limited, internet-based] research I have discovered that there’s far more to AR than just talking to random local folks. Yeah, you can use satellites to connect with people far, far away, and you can even talk to members of the space shuttle or international space station but I don’t think it’s conversation that will ever satisfy me. I’m not much of a conversationalist. I much enjoy making/hacking things. I’m really wanting to get into QRSS, or simple-low power slow speed data transmitting circuits with the potential to broadcast signals around the world! I think it will be fun to combine my microcontroller programming knowledge with these simple circuits. Sure, I don’t have any data that I necessarily want to have transmitted, but that’s not important. I just want to be able to smile knowing that I sent it =o)
Last night I built a makeshift antenna for my balcony. (pictured above) The antenna (theory/plans) are good, but I kind of hacked it together at the last minute. The basic design measurements were obtained from “this online calculator:http://www.qsl.net/wrav/2mjpole.htm but the surprising thing is that I purchased the copper/connectors/pvc without knowing the plans. That’s right!
I was initially going to find some 300Ohm TV antenna runner wire to “assemble a ghetto 2m jpole antenna” but when I couldn’t find the correct wire at WalMart, and 100FT of it at RadioSh*t was almost $20! Not cool. So I went to Lowes hoping to find the wire but they didn’t have it either. I walked by the plumbing section, saw the huge copper pipes (for about 1$) and remembered the copper jpoles I saw on the web earlier that day. I didn’t have any plans with me, so I didn’t know what I needed. I closed my eyes in the isle, pictured the Google image searches, and decided to go to town and buy as much as I could remember. I totally lucked out too! After getting a ton of random copper and PVC pipes and connectors (mostly Ts, couldn’t find copper elbows of the right size) I took it all home, looked at the measurements I needed, and I had everything!
Haray! I quickly assembled my makeshift antenna with the parts I [blindly] purchased. I’m sure that it requires tuning for maximal efficiency (and to decrease the possibility of damaging a future transmitter I attach to it),
but I don’t have the equipment I need to tune it. Perhaps after I get my radio in, get my license, and start making some local contacts, I’ll find someone who will help me tune it. Oh! I haven’t written about that yet. A couple days ago I purchased some cheap Chinese electronics that (fingers-crossed) will work decently. I went cheapest of the cheapest and got a 5W 2m (VHF, ~144MHz) handheld – the Puxing-777! I figure it’ll help me establish some local contacts and get used the the whole AR scene. Why do I see myself taking it apart for some who-knows reason? I freaked out the other day and almost went psycho on my frequency scanner when I discovered that it was controlled by two boards (likely a logic board and a radio board), which were only connected by ~12 pins. It was the perfect reverse-engineering / hardware hacking project, and the perfect excuse to build my own logic analyzer to intercept the data being communicated. Bah! Anyway, I backed off the project, even though (if I had more time) I would have loved to do it. (Imagine how cool it would be to turn old cheap scanners into software-defined radios!?)
I completely forgot where I was going so I’ll just end this rant. Goodbye, so long, farewell, and I love you, oh sweet blog of mine. I’m sorry I neglect you so, but I promise that I will return to you shortly and garnish your sweet pages with beautiful words. Until then, I have a thesis to write!
Finally, a Use for Inkscape!
Posted by Scott February 7th, 2009 | 5,253 words | No Comments »
Several days ago I gushed on and on about how amazing InkScape is. The possibly-discrediting thing is that my post was made first day I ever used it! A few weeks later, slowly reading documentation, tutorials, and practicing drawing random objects, I think I’m finally getting the feel of designing images in InkScape, and am growing
to appreciate the depth of its usefulness. This week in lab I reached an epiphany which (if proven true) would be a significant revelation to the field of autonomic neuroscience. To prove it I’ll have to publish a paper with a lot of confocal images demonstrating this unique feature, and cite a lot of previously-written literature to support my theory molecularity. To clarify the process, I’d love to have some great diagrams. For example, I want a diagram to show how the autonomic nervous system innervates the mouse heart, but no such diagram exists! Here’s one for humans but it’s major overkill, shows every organ (I only want the heart), and doesn’t go into detail as to what the nerves do when they reach the heart (something no one knows – but my research is uncovering!). Also, mouse brains are very different in shape from human brains, and there aren’t any good pictures of the ventral side of a mouse brain. So, I found the best one I could and re-created it with InkScape. Looks pretty snazzy so far huh?

Celebrity Dwarf Gouramis
Posted by Scott January 29th, 2009 | 5,253 words | No Comments »
So I was reviewing my website statistics generated by a Python script I wrote when I noticed a peculiarity so bizarre that it made me questin the very purpose of my life. Okay maybe it wasn’t that bizarre, but it was interesting. The python script (which is automatically run every hour) downloads my
latest access.log and saves it to its own folder. It then analyzes the data, creates some charts and graphs, and dumps out a bare-bones results file displaying some of the information I found useful. Of note is the number of times each page is hit.
This is where things get funny. Outperforming my home page by nearly double was indexOld.php (now indexOld22.php) – a simple webpage I tossed of for about a year before I put my big blog back online! Why were people still going to this page? Further investigation (from the referring sites section of my stats page) revealed a lot of hits from Google image-searches. I started looking at the actual requests and realized that many of these hits were people searching for the term Dwarf Gouramis “a type of freshwater aquarium fish) which was mentioned on that old webpage. The ironic part about it is what happens when you google image search for dwarf gouramis there is a picture of an extremely rare zebra pleco which is actually a link to my website! However the link APPEARS to be to wallpaperfishtalk.com because on my page I just linked to their image.
My conclusion: People are Google image-searching for ‘dwarf gouramis’, and an amazing picture of a zebra pleco is coming up which links to my site (due to the fact that months ago I talked about dwarf gouramis but posted a photo of a zebra pleco) and people (in their awe at this amazing fish) are clicking on it. So what did I do? I pulled a bait-and-switch! You bet I did. Now when you go to indexOld2.php it just forwards you to my current website – mua ha ha ha ha
PS: I’m appending to this entry at 2:17pm to note that I made a wonderful breakthrough in the lab today. Due to intellectual property protection blah blah and the fact that I don’t want anyone else to beat me to my research goal I will not describe what this is, I’ll just say that it took months of preparation and today – presto! It worked beautifully =oD

Merry Labmice
Posted by Scott December 23rd, 2008 | 5,253 words | No Comments »
The pain caused my eyes opened 5am this morning. My alarm wasn’t set to go off until 7:30am, but I couldn’t sleep. I was anxious. Hundreds of thoughts continuously raced through my mind, all of them bad. I’ve been rejected from one dental school, will another take me? Will I ever graduate the program I’m in? Why do I feel like my thesis project is going to fail? My wife postponed starting nursing school for me because we were going to move for dental school, and now I’ve been rejected, what have I done to her? If I don’t get into any dental school, how could I get a job? What would I do with a masters in biomolecular science? Teach at a community college? Get a PhD? In what? God, not the same subject, right? Do they have a PhD in bioinformatics at my school? Will I have to move to another state? Have PhD application deadlines for enrollment in August have already come and gone? What do I have to do today, just kill 6 mice in lab and they try to finish my Christmas shopping? What am I going to get my wife for Christmas? Was she serious when she said she didn’t want to exchange valuable gifts with each other in order to save money? Should I make her something? Should I buy her something? Did I pay rent this month? Power, did I pay that? I don’t remember getting a power bill, but that doesn’t mean I don’t have to pay it anyway, right?
You get the idea. Anyway, stress and the lying-down position combined with acid reflux resulted in the fiery sensation of heartburn as I lay there pondering what felt like my imminent doom. I couldn’t take it anymore. I got up and left. Yeah, I got to work a little early this morning (way early, actually) but I figure that a little more time (spent relaxing, spent blogging) and perhaps some Tums would help me out a bit. So, here I am. Walking into work today I realized that I didn’t have a lot of pictures documenting my time here. So, in the cover of early darkness, I pranced around the building from room to room snapping pictures of the laboratories. Then I got a cup of coffee, sat on a step, and watched the reflection of the rising sun from building I work in.
Thankfully this is not the building where I attended any of my classes, or the thought of sitting beside it for so long would likely be revolting instead of relaxing. On a separate note, as much as Adobe Photoshop’s PhotoMerge plugin disappoints me (it crashes right in front of me every time I try to create an image larger than 4,000×4,000 pixels) I have to say that it worked nicely in my case. This is my lab desk.
It’s clickable too. Go on, click it! I changed desks a few months ago. I thought it would be cool to have a photo of this so, years down the road, I can look back, remember all of the memories, and probably ask myself “why the heck did I choose the molecular biology and microbiology program?”
Currently, I’m listening to Beethoven – Pathetique – Piano Sonata #8 c minor Op- 13.aac at relatively high volume at my desk since no one is in the laboratory yet. This is one of my favorite songs. I have a copy saved on my website, but it’s kind of hidden and unlabeled so it can’t be found on Google and I can’t get in trouble for it (that’s the plan anyway). If you’d like a copy, you can download it yourself (.aac files are like .mp3 files – they can be played with Winamp or Mplayer but they have better sound quality after extreme compression – this 18 and 1/2 minute song is a little over 3 megabytes). Anyhow, the link is: song4.aac and all I ask of you is that you download the file instead of streaming it directly from the website (it’ll save a little bandwidth). Thanks =o)
Data Mismanagement / Infestation
Posted by Scott December 20th, 2008 | 5,253 words | 3 Comments »
*As if threat of impending doom doom weren’t already haunting my nightmares* (possibly due to the intimidating threat of overlooked graduation requirements preventing my career from moving forward in a timely manner, but more likely due to terrifying possibility that my entire life will be spent stuck graduate school), yesterday I had two separate wrenches thrown into my academic gears. First, although I succeeded in confirming my legal rights with respect to being bound only to program policies that were already enacted prior to my admission, I came across a disturbing amendment to the thesis policies which claims that no student can propose, submit, or defend their thesis in the same semester. If this ruling applies to me, it will be devastating. I’ve spent a year and a half figuring out a way to do something no body has ever done before (looking at something no one has ever seen before, developing a method to quantitatively measure it that was never used before, and drawing conclusions about a pathological condition that was only previously theorized), and now that I’ve perfected my technique I want to use the subject matter for my thesis, propose the thesis, formally write and submit the thesis, and formally defend it (in rapid succession), thus satisfying my thesis requirements for graduation.
*So, I’m gathering preliminary data together and forming an experimental plan when, oh my, do I need to write more Python code?* Yeah, I know I feel that I look for excuses to find reasons to program, but the truth is that Python is so versatile and my working knowledge of it is thorough enough that I can’t imagine what I’d do without it! My department has an animal facility where they house literally thousands of mice of many different strains. These mice are housed in cages (maximum 5 mice per cage), and each cage contains only one (occationally two) types of mice with respect to sex, age, strain, and heredity. The project I’m working on will compare OVE26 (transgenic diabetic) mice with FVB (normal) controls. I also have a small collection of GFP (fluorescent) mice which I plan to use on a separate project.
*So, what’s the problem?* These mice are randomly distributed in giant racks with 6 stacked rows and 7 columns. Each rack has 46 cages, and racks are double-sided. Thankfully, all of the FVB, OVE26, and GFP mice are located on two large racks for a total of 184 cages. Unfortunately, interspersed are C57BL and other strains of mice I don’t plan to use. Another issue is that I only plan to use male mice in my experiment. A real pain is the fact that one rack is underground in the transgenic animal facility “headquarters” (for lack of a better word), and the other rack containing my mice is three stories up. Not only are these mice seemingly randomly distributed in location, but there appears to be a total lack of species/strain/heridity/sex specific inventory. The only inventory methods appear to be a total animal count. So when I went to my boss to ask how many diabetic mice we have and of what ages, he talked to another person who works in the laboratory and they concluded that they don’t really know. Do they have enough diabetic mice for my experiment? Are they old or young?
Can we produce age-matched diabetic and control mice? Are there enough mice for my experiment that I don’t have to ruin the project of another laboratory worker planning on using the same mice? These are all questions that could not be answered, only speculated.
*With all of the uncertainties already afflicting my thesis process, I didn’t want animal confusion to be a problem.* From what I heard, about a dozen diabetic animals (in the age range I wanted most for my experiment) were recently killed. I felt that this process needed to be organized before I could properly come up with a plan, and of course, Python would be involved. I spent the morning downstairs manually inventorying mice. I decided that a location-based system would be the most useful. Each cage got its own line on a sheet of notebook paper (actually more like 8 sheets), and on each line I noted the cage location (in story/row/column coordinates), and information about the 1 or 2 groups of animals housed in the cage (count, sex, and date of birth for each group). After a couple hours sweating beneath my disposable hairnet and lab coat, I completed the downstairs inventory. To the side is a picture I took of myself half way through the monotonous process. (I think blood was about to shoot out of my eyes) Later I ate lunch, then did the upstairs. After I finished, I went home and manually entered this data into the computer (open office spreadsheet -> XLS), so it looked like this:

*Then I saved this data as a CSV* (comma separated values) file (using either open office or microsoft excel). Note that this is done in such a way that it’s very easy to make modifications to the XLS file to reflect new cages, changing cage locations, or animal death. Anyway, once it was in a CSV format, I wrote a Python script to convert the CSV format to a custom easy-to-analyze format which basically boils down to one line per mouse (not one line per cage). This is the Python script:
f=open("data.csv")
raw=f.readlines()
f.close()
animals=[] # [cage,sex,type,dob,age]
cages=[]
def addAnimals(animal,cage):
if len(animal[0])==0: return False
if cage not in cages: cages.append(cage)
count=int(animal[0])
if animal[1] == 'm': sex="male"
else: sex="female"
strain=animal[2]
dob=animal[3]
age=int(round(float(animal[4])))
animal = [cage,sex,strain,dob,age]
for i in range(count):
animals.append(animal)
for i in range(len(raw)):
line = raw[i].replace('"','').replace('n',"")
if "-" in line:
line = line.split(",")
addAnimals(line[3:8],line[14])
addAnimals(line[8:13],line[14])
f=open("data.txt",'w')
f.write('['+str(animals)+"],["+str(cages)+']')
f.close()
*Running this script produced a file with content like this:*
[[['d-a1', 'male', 'fvb', '09/26/08', 3], ['d-a2', 'male', 'fvb', '08/12/08', 4], ['d-a2', 'male', 'fvb', '08/12/08', 4], ['d-a3', 'male', 'fvb', '12/24/07', 12], ['d-a3', 'male', 'fvb', '12/24/07', 12], ['d-a4', 'male', 'fvb', '11/16/08', 1], ['d-a4', 'male', 'ove26', '11/16/08', 1], ['d-a4', 'male', 'ove26', '11/16/08', 1], ['d-a4', 'male', 'ove26', '11/16/08', 1], ['d-a5', 'male', 'fvb', '10/26/08', 2], ['d-a5', 'male', 'fvb', '10/26/08', 2],...
*From there, I wrote an analysis python script.* Should I post it? [thinks about it] Sure why not. A warning though, the code is pretty rough. It works though =o)
import pylab
f=open('data.txt')
animals,cages=eval(f.read())
animals,cages=animals[0],cages[0]
f.close()
print "Processing data for %d animals in %d cages..." % (len(animals),len(cages))
##LIMITS######
sex="male" #'male' or 'female'
strain="ove26"
minage=3
maxage=9
##############
selected=[]
def passIt(animal): #['u-l7', 'male', 'ove26', '10/28/08', 2]
global selected
if not animal: #dscription
title="Displaing "
if sex: title = title+sex+" "
if strain: title = title+strain+" "
else: title = title+"all "
title = title + "mice from "
if minage: title = title+str(minage)+" months to "
else: title = title+"birth to "
if maxage: title = title+str(maxage)+" months."
else: title = title+"death."
return title
if sex:
if not animal[1]==sex: return False
if strain:
if not animal[2]==strain: return False
if minage:
if animal[4]maxage: return False
selected.append(animal)
return True
def histIt(strain="all",col='k',label=True,limitTest=False,lw=None):
ages,xs,a=[],[],{}
for animal in animals:
if limitTest:
col='b'
if passIt(animal):
ages.append(animal[-1])
if not animal[-1] in a: a[animal[-1]]=0
a[animal[-1]]=a[animal[-1]]+1
elif strain in animal or strain == "all":
ages.append(animal[-1])
if not animal[-1] in a: a[animal[-1]]=0
a[animal[-1]]=a[animal[-1]]+1
for x in range(max(ages)+1):
xs.append(x-.45)
if not x in a: a[x]=0
if not limitTest:
pylab.title("Ages of %d (%s) Mice"%(len(ages),strain))
pylab.xticks(range(1,max(ages)+1))
if not label: col,lw='0.9',0
else: pylab.title(passIt(None))
pylab.bar(xs,a.values(),color=col,lw=lw)
for x in range(max(ages)+1):
if label:
if a[x]>0: pylab.text(x,a[x]+1,a[x],ha='center')
def showSelected():
cages={}
ids=[]
m,f=0,0
for animal in selected:
if animal[1]=="female":f=f+1
if animal[1]=="male":m=m+1
if animal[0] not in cages:
cages[animal[0]]=0
ids.append(animal[0])
cages[animal[0]]=cages[animal[0]]+1
ids.sort()
x=0
disp="Total of %d mice (%dm/%df)nn"%(m+f,m,f)
disp=disp+"Animal Cage Locations:n"
for cage in ids:
disp = disp+"%s(%d), "%(cage,cages[cage])
x=x+1
if x>7:
x=0
disp = disp + "n"
return disp
def getLimits():
global sex, strain, minage, maxage
answer=raw_input("Sex [m,f]:")
if answer=="": sex = None
if answer=="m": sex = "male"
if answer=="f": sex = "female"
answer=raw_input("Strain [ove26,fvb,gfp]:")
if answer=="": strain = None
else: strain=answer
answer=raw_input("Minimum Age [3]:")
if answer=="": minage = None
else: minage=int(answer)
answer=raw_input("Maximum Age [9]:")
if answer=="": maxage = None
else: maxage=int(answer)
print "nn"
print passIt(None)
raw_input("npress ENTER to start")
return
getLimits()
fig = pylab.figure(figsize=(12,8))
histIt(label=False)
histIt(limitTest=True)
masterAxis = [0,pylab.axis()[1]+1,0,int(pylab.axis()[3]*1.15)]
pylab.axis(masterAxis)
pylab.figtext(.4,.85,showSelected(),va='top')
pylab.show()
#fname=raw_input("Enter a name for this image to save it or press ENTER to quit:")
#if len(fname)>1:
# pylab.savefig(fname+".png")
# print "nsaved as [%s]"%(fname+".png")
# raw_input("npress ENTER to exit...")
*Running this code* asks some questions about what type of information I should display. if I have it display all male OVE26 animals (for example) the output looks like this (thanks to matplotlib):

*Here the gray bars are the total number of all animals, and the blue bars are the animals I searched for* (in this case, all male ove26 animals). Comparing FVB and OVE26 charts, I estimated that we had enough male 4-5 month old OVE26 and FVB animals to make the experiment work (about 12 of each group). Searching for male ove26 mice at least 4 months and no older than 5 months old produces this chart:

See how it lists the location of each of the cages and the number of animals I want from each *cage?* For example, “d-I2(1)” means that there is a cage downstairs, along row I, in column 2, which contains 1 male OVE26 mouse 4 or 5 months old. Awesome list generation! Thanks Python =oD
*But wait, couldn’t I have just gone down and looked for 4-5 month old mice?* Yes and no. Yes, it would be easy to find (and mark) these mice, but no because I would not have known to look for them. The goal of yesterday’s little python project was to be able to see at one time everything we have, so I could best determine the criteria of the animals I wanted. Before I made this program, I was planning on comparing mice between 5 and 7 months – something that appears would have been impossible based on the animals we currently have. I can also tell what other experiments I will be able to do in a few months, when some of the mid-age FVB mice will grow older. Additionally, this program is versatile and can be used again and again, for many different projects, with no modification to the code required. Yay Python!
Molecular Purgatory
Posted by Scott December 17th, 2008 | 5,253 words | No Comments »
In my program (the University of Central Florida’s Master of Science in Molecular Biology and Microbiology) there is a handbook distributed to each class during orientation. The handbook lists the requirements of the program. Presumably, when these requirements are met, one can graduate. It clearly states that you need 30 credit hours to graduate, of which 6 are thesis and 24 are non-thesis courses.
Of the 24 hours of non-thesis coursework, there is a small list of required classes [core I (5hr), core II (5hr), Lab (4hr), Prac (2hr), Seminar I (1hr), and Seminar 2 (1hr)] totaling 18 hours. Therefore, since 24 hours are required, but required courses only total 18 hours, it’s assumed that one needs to take 6 hours of elective courses to make-up for this deficiency. I’m pulling my hair out today because my program advisor told me that I needed 10 hours of elective coursework to graduate – something that is not mentioned anywhere in the handbook. (To be accurate, there is a single passing mention of a single 3 hour elective course, but it’s to be taken to help reach the requirement of 24 non-thesis credit hours.) This change (requiring 10 hours of elective credit) was made after I began the program. I do not believe that the program has the right (ethically, or legally) to hold this change against me and prevent my graduation (preventing graduation means that even if I do get accepted into dental school, I could not attend, because acceptance is dependent upon completion of the program I’m in). I spent the last hour describing my plight to the members of the graduate office, in hopes that I can obtain legal documentation to support my case. This stuff is so frustrating. [sigh]
It’s True, My Application Essay Says So!
Posted by Scott October 1st, 2008 | 5,253 words | 1 Comment »
A couple days ago I finished writing my personal statement (4500 characters, ~1.5 pages single spaced) for the dental school application. After the blood shooting out of my eyes subsided, I was able to sit back and admire my work. There, in front of me, was a surprisingly eloquent description of my academic life from the perspective of why I think everything I have ever done makes me an incredible candidate for dental school. As far as the assignment goes, I’m content. I wrote it so well that I almost convinced myself that I wanted to go to dental school. Regardless, it’ll be submitted in a day or two once a few final things get processed. Once I’m accepted or rejected, I’ll have to remember to put a copy of it on here because it’s a real hoot. For now, here’s a snippet.
Although I intended to begin dental school in the fall of 2007, the admissions departments had other plans for my future. Taking my initial rejection in good stride, but still strongly desiring to become a dentist, I decided to expand my knowledge of biology and develop whatever other skills I could by pursuing a graduate degree with the intention of re-applying to dental school.
…
It has been my dream for many years to become a dentist, and following acceptance into dental school I will work hard to become a prominent figure in the community and a great example for all those who have similar dreams. My undergraduate and graduate school experiences have both equipped and energized me to pursue a career in dentistry, and the skills I’ve acquired along the way have prepared me well to pursue my dream of becoming a dentist. |
I know, right? Jeez. Moving on, I wanted to note something about my research. Things are progressing nicely, and I’m about to have my boss buy ~600 bucks worth of antibodies (a total volume of ~1100 microliters, or about 22 drops of a clear liquid). It’s crazy how expensive these things are. Yeah, I understand the concept behind the development of polyclonal antibody solutions – but I’ve never seen a detailed analysis of the costs involved along the way. When I spend $23 per drop of some chemical, where exactly does the money go? Anyway, I had a revelation. One of the most complicated aspects of my project is that the signal I’m trying to observe through the microscope is from a fluorophore that emits light around a λ of 498nm to 529nm, and that thick myocardial tissue is autofluorescent in this region. Yes, I might see a tad of labeled fibers, but it’s amidst a sea of background fluorescence! Today (since I needed to order some new secondary antibodies anyway) I decided to investigate exactly which regions of the spectrum were most affected by myocardial autofluorescence. I blasted some thick atrial tissue with the 405 UV diode and took a series of images with a 5nm-wide recording wavelength window shifted by 3nm each, then took the average intensity of each frame of the stack. The result (when graphed) was a pretty spectral representation of myocardial autofluorescence, which was incredibly string in the blue and green bands that I had been using all along. I’m going to order some far-red secondary antibodies, hoping that it’ll help.
After many more hours of writing code in python, I finally have some presentable data. Due to intellectual property reasons, I’m not going to include details about the method, units, or even samples I used. It’ll suffice to simply say that my method seems to be working well, and that the bottom line appears well outside of the upper band (and its respective standard deviation). ALL processing was completed ENTIRELY within Python. I used the python imaging library (PIL) to load data form the TIFF file into a HUGE array, and NumPY to assist with manging the array. Data was then graphed with MatPlotLib and placed directly into a PNG. Here’s an example!
Okay, it’s getting late and I have a project I have to prepare for tomorrow. I know my blog entries have become boring, dry, and overly scientific since I started writing again, but I have to admit that this is just the kind of person I’ve become. I don’t really write about relationships anymore because I’m kinda “set” in that department (with the whole marriage thing and all), and I don’t think it would be a very good idea to go about blabbing all of our personal life together anyway. Beside, these writings are an expression of my thoughts and (supposedly) not intended to be anything more. If my thoughts are boring, so are these writings. [sigh]