Microplate Reader Data Sorting
DannDann
Wed, 04/23/2014 - 05:09 pm
I've used IGOR to analyze voltage-clamp data, but I'm new to programming. I'm working through the Payam's Place "Introduction to IGOR Programming," and I've made it to the Intermediate Algorithms section, but I think I'm having a more basic issue.
So each data file I get is an excel file with 385 columns (the first is time) of 600 points each - each corresponding to a well on a 364-well plate. I read these all in as waves, and thanks to jjweimer's responses to a few other topics in the forum, I've managed to write functions to rename and duplicate all of the files:
function TempRenameEpic(matchstring, newsuffix)
string matchstring, newsuffix
string wavenames=wavelist("*", ";", "")
string theOne
string theName
variable i
for (i = 0; i < itemsinlist(wavenames); i += 1)
theOne = stringfromlist(i,wavenames)
theName = ReplaceString(matchstring,theOne,newsuffix)
rename $theOne $theName
endfor
End
function duplicateEpic(matchstring, newsuffix)
string matchstring, newsuffix
string wavenames=wavelist("*", ";", "")
string theOne
variable i
for (i = 0; i < itemsinlist(wavenames); i += 1)
theOne = stringfromlist(i,wavenames)
string theName = ReplaceString(matchstring,theOne,newsuffix)
duplicate/O $theOne $theName
endfor
End
string matchstring, newsuffix
string wavenames=wavelist("*", ";", "")
string theOne
string theName
variable i
for (i = 0; i < itemsinlist(wavenames); i += 1)
theOne = stringfromlist(i,wavenames)
theName = ReplaceString(matchstring,theOne,newsuffix)
rename $theOne $theName
endfor
End
function duplicateEpic(matchstring, newsuffix)
string matchstring, newsuffix
string wavenames=wavelist("*", ";", "")
string theOne
variable i
for (i = 0; i < itemsinlist(wavenames); i += 1)
theOne = stringfromlist(i,wavenames)
string theName = ReplaceString(matchstring,theOne,newsuffix)
duplicate/O $theOne $theName
endfor
End
Since all of the original titles for each wave are cumbersome, this allows me to rename them the simple A1_ A2_ A3_ etc (I include the underscore because of the system variables K0-K19). Here's the issue: I have baseline wells - in the O and P rows of the plate - that are buffer controls. Each one corresponds to one well in a group of four - such that O1 is the control well for A1, O2 for A2, P1 for B1, and P2 for B2. This continues down the column of the 384-well plate, so O1 is the control for not only A1, but C1, E1, G1, I1, K1, and M1.
I want to quickly subtract the appropriate control wave from each of its well waves. I can easily do it for one wave:
duplicate A1_, A1_mb
A1_mb = A1_ - O1_
So now I just need to set up a series of If, elseif parameters inside a function to do it for each column and then the whole plate. Here is what I have so far:
function SubtractBaselineOnce(input,baseline) //This works if I supply the target wave and its appropriate control wave
wave input
wave baseline
string outputname = nameofwave(input) + "mb"
duplicate/O input, $outputname
wave output = $outputname
output = input - baseline
End
Function SubBase(matchstring)
string matchstring
string wavenames=wavelist("*", ";", "")
string theOne
string theName
variable i
for (i = 0; i < itemsinlist(wavenames); i += 1)
theOne = stringfromlist(i,wavenames)
if //How do I sort this?
endif
endfor
End
wave input
wave baseline
string outputname = nameofwave(input) + "mb"
duplicate/O input, $outputname
wave output = $outputname
output = input - baseline
End
Function SubBase(matchstring)
string matchstring
string wavenames=wavelist("*", ";", "")
string theOne
string theName
variable i
for (i = 0; i < itemsinlist(wavenames); i += 1)
theOne = stringfromlist(i,wavenames)
if //How do I sort this?
endif
endfor
End
Thanks for any tips you might have.
-EM
for the subtraction you could try:
Wave inW,baseW
String name=nameofwave(inW)+"mb"
MatrixOP/O $name=inW-baseW
End
This saves the duplication.
If you are going to repeat this for the whole plate I recommend that you reconsider the way you arrange your data. Specifically you might benefit from storing all the data in a single 2D wave where each one of your current waves is a single column. It would then be easier to perform uniform baseline subtraction and all your waves are nicely organized in a single object.
A.G.
WaveMetrics, Inc.
April 23, 2014 at 05:33 pm - Permalink
...
Wave w2 = $theOne // Create wave reference
w2 -= w1 // Subtract
To learn about this, execute:
But you really should read all of the Programming help file or the equivalent - chapters IV-1, IV-2 and IV-3 of the PDF manual.
On the topic of loading waves, if you are loading waves using XLLoadWave and you know the desired wave names in advance, you can use the XLLoadWave /NAME flag to set the wave names.
April 23, 2014 at 06:17 pm - Permalink
I'm sure it can be cleaned up and simplified, but I'm just happy I got it to work, and hopefully someone can use this info in the future. The functions that were the most helpful for me were sscanf, StringByKey, and SelectString.
string matchstring
string wavenames=wavelist("*", ";", "")
string theOne
variable i
for (i = 0; i < itemsinlist(wavenames); i += 1)
theOne = stringfromlist(i,wavenames)
variable v1
string s1
string whichone //will be 0 or 1 -- 0 for O, 1 for P (to work with SelectString)
sscanf theOne, "%1s%f", s1, v1 //separates plate column number from row letter
//make all waves containing A, C, E ect return 0 and the rest return 1
whichone = StringByKey(s1, "A:0;B:1;C:0;D:1;E:0;F:1;G:0;H:1;I:0;J:1;K:0;L:1;M:0;N:1")
//SelectString will output O or P based on whichone value
string intermediatename = SelectString(str2num(whichone), "O", "P")
string baselinename = intermediatename + num2str(v1) +"_"
string outputname = nameofwave($theOne) + "mb"
//this last part is to prevent generating the buffer-subtracted wave from buffer-well waves or time waves
if (str2num(whichone) == 0)
duplicate/O $theOne, $outputname
wave original = $theOne
wave output = $outputname
wave baseline = $baselinename
output = original - baseline
elseif (str2num(whichone) == 1)
duplicate/O $theOne, $outputname
wave original = $theOne
wave output = $outputname
wave baseline = $baselinename
output = original - baseline
else
duplicate/O $theOne, $outputname
killwaves $outputname
endif
endfor
End
Thanks again for the help!
-EM
April 24, 2014 at 08:52 pm - Permalink
if (str2num(whichone) == 0)
andelseif (str2num(whichone) == 1)
blocks?And also the last
else
block seems redundant, as you first duplicate the wave and two lines later kill it.Recent igor versions also allow to create a wave reference on duplication i.e.
Make data
string temp = "abcd"
Duplicate/O data, $temp/Wave=output
End
which make the code more compact to read.
April 25, 2014 at 10:00 am - Permalink
Function SubtractBuffer()
string wavenames, theOne, s1, iname, blname, outname
variable ic, v1, nw, ns
wavenames = wavelist("*", ";", "")
nw = ItemsInList(wavenames)
for (ic = 0; ic <nw; ic += 1)
theOne = stringfromlist(ic,wavenames)
wave source = $theOne
sscanf theOne, "%1s%f", s1, v1
nw = mod((char2num(s1)-65),2)
iname = nw == 0 ? "O" : "P"
blname = iname + num2str(v1) + "_"
wave baseline = $blname
outname = theOne + "mb"
duplicate/O $theOne $outname
wave output = $outname
output = source - baseline
endfor
return 0
end
You might consider whether your data waves can be collapsed so that MatrixOp can be used (as AG suggested) to streamline and speed up the code
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
April 25, 2014 at 10:03 am - Permalink