Using DoPrompt in a button function
tooprock
I have been away for a while. With great support of Igor team and you guys I managed to write my own data analysis tool and it works perfectly. However I need to improve some parts and increase the functionality of the code that I wrote. Here is what I need in the very beginning:
I would like to analyse (selectively) a multi-dimensional wave. To do this I wrote a main function which defines the target wave and performs a simple mathematical calculation on it. Another simple function moves the data to another data folder and does a quick statistical calculation on the data. A third function is then responsible for displaying the final result on a panel so the user can select desired result by pressing on previously defined buttons.
What I would like to do is including a small Promt window that appears when the button is called. By doing so user can enter a time interval (i.e., 01.01.2015 12:00:00 - 01.01.2015 13:00:00) which I am planning to save as variables (time can be converted to numbers according to a reference point, right?). After having the start & end point for the analysis, I can look up in the entire wave and extract the interval that I want to analyse.
The problem is where should I put the DoPrompt function? Here are the functions I mentioned above.
//This is the button function. When user clicks the button following functions are called and finally a panel windows appears where the user can display results.
Function ButtonProc_21(ctrlName) : ButtonControl
String ctrlName
buildSizeResolvedRatio()
plotRatioData()
End
// Calculate size resolved ratio waves
// This is so called Nf/Nt data (size resolved)
// So we know the contribution of fluorescent particle number to the total for each size bin
Function buildSizeResolvedRatio()
SetDataFolder root:INCD
// Wave SizeResolvedBioWave // this wave contains only the raw counts, not concentration
Wave finalBioWave3D
Variable numofRows, numofColumns, numofLayers
numofRows = dimSize(finalBioWave3D,0)
numofColumns = dimSize(finalBioWave3D,1)
numofLayers = dimSize(finalBioWave3D,2)
Make/O/N=(numofRows, numofColumns, numofLayers) sizeResolvedRatioWave
Variable i
for(i=0; i<=NumBioType; i +=1)
//sizeResolvedRatioWave[][][i] = SizeResolvedBioWave[p][q][i] / SizeResolvedBioWave[p][q][3] // changed 24/07/2013
sizeResolvedRatioWave[][][i] = finalBioWave3D[p][q][i] / finalBioWave3D[p][q][3]
endfor
// There are lots of missing data points and when we remove all missing points (NaN) it's likeyl that both median and mean
// never reach zero...
sizeResolvedRatioWave = sizeResolvedRatioWave[p][q][r] == NaN ? 0 : sizeResolvedRatioWave[p][q][r]
// Call findSResolvedAverages to calculate mean&median
findSResolvedAverages(sizeResolvedRatioWave)
End
// Calculate mean and median values for each bio_Type and also averaged for entire time
Function findSResolvedAverages(inputWave)
Wave inputWave
//dNdlogDo = dNdlogDo[p][q][r] == 0 ? NAN : dNdlogDo[p][q][r] // Set all NANs to zeros.
String prefix = "temp"
SetDataFolder root:INCD
Duplicate /O inputWave, temp3DWave
NewDataFolder root:tempData
SetDataFolder root:tempData
MoveWave root:INCD:temp3DWave, root:tempData:
Variable numRows = dimSize(temp3DWave,0)
Variable numColumns = dimSize(temp3DWave,1)
Variable numLayers = dimSize(temp3DWave, 2)
Variable i, ii
Variable numStatParam = 6
// Make the output wave
Make/O/N=(numColumns,numLayers,numStatParam) workedAvgWave // distribution wave for mean(layer0) and median(layer1)
SetDimLabel 2, 0, TheMedian, workedAvgWave
SetDimLabel 2, 1, TheMean, workedAvgWave
SetDimLabel 2, 2, Q10, workedAvgWave
SetDimLabel 2, 3, Q90, workedAvgWave
SetDimLabel 2, 4, Q25, workedAvgWave
SetDimLabel 2, 5, Q75, workedAvgWave
Variable numberpoints
for(ii=0; ii<numLayers; ii +=1)
for(i=0; i<numColumns; i += 1)
String colName = "temp_" + num2str(i)
MAKE/O/N=(numRows) $(colName)/Wave=ww
ww = temp3DWave[p][i][ii]
Sort ww, ww
// We need to remove NANs becuase mean doesn't support NaNs.
//WaveTransform zapNaNs, ww
ww = ww[p] == NaN ? 0 : ww[p]
// Calculate inter quartile ranges and mean/median values
WaveStats/Q/Z ww
numberpoints = V_npnts
workedAvgWave[i][ii][%TheMedian] = ww[((numberpoints+1)/2)-1]
workedAvgWave[i][ii][%TheMean] = V_avg
workedAvgWave[i][ii][%Q10] = ww[(2*(numberpoints/20))-1]
workedAvgWave[i][ii][%Q90] = ww[(18*(numberpoints/20))-1]
workedAvgWave[i][ii][%Q25] = ww[(numberpoints/4)-1]
workedAvgWave[i][ii][%Q75] = ww[3*(numberpoints/4)-1]
endfor
endfor
if(DataFolderExists("root:SizeResolved:")==0)
NewDataFolder root:SizeResolved
MoveWave root:tempData:workedAvgWave, root:SizeResolved:
KillDataFolder/Z root:tempData
SetDataFolder root:SizeResolved:
else
KillDataFolder/Z root:SizeResolved
NewDataFolder root:SizeResolved
SetDataFolder root:SizeResolved
MoveWave root:tempData:workedAvgWave, root:SizeResolved:
KillDataFolder/Z root:tempData
endif
End
Function ButtonProc_21(ctrlName) : ButtonControl
String ctrlName
buildSizeResolvedRatio()
plotRatioData()
End
// Calculate size resolved ratio waves
// This is so called Nf/Nt data (size resolved)
// So we know the contribution of fluorescent particle number to the total for each size bin
Function buildSizeResolvedRatio()
SetDataFolder root:INCD
// Wave SizeResolvedBioWave // this wave contains only the raw counts, not concentration
Wave finalBioWave3D
Variable numofRows, numofColumns, numofLayers
numofRows = dimSize(finalBioWave3D,0)
numofColumns = dimSize(finalBioWave3D,1)
numofLayers = dimSize(finalBioWave3D,2)
Make/O/N=(numofRows, numofColumns, numofLayers) sizeResolvedRatioWave
Variable i
for(i=0; i<=NumBioType; i +=1)
//sizeResolvedRatioWave[][][i] = SizeResolvedBioWave[p][q][i] / SizeResolvedBioWave[p][q][3] // changed 24/07/2013
sizeResolvedRatioWave[][][i] = finalBioWave3D[p][q][i] / finalBioWave3D[p][q][3]
endfor
// There are lots of missing data points and when we remove all missing points (NaN) it's likeyl that both median and mean
// never reach zero...
sizeResolvedRatioWave = sizeResolvedRatioWave[p][q][r] == NaN ? 0 : sizeResolvedRatioWave[p][q][r]
// Call findSResolvedAverages to calculate mean&median
findSResolvedAverages(sizeResolvedRatioWave)
End
// Calculate mean and median values for each bio_Type and also averaged for entire time
Function findSResolvedAverages(inputWave)
Wave inputWave
//dNdlogDo = dNdlogDo[p][q][r] == 0 ? NAN : dNdlogDo[p][q][r] // Set all NANs to zeros.
String prefix = "temp"
SetDataFolder root:INCD
Duplicate /O inputWave, temp3DWave
NewDataFolder root:tempData
SetDataFolder root:tempData
MoveWave root:INCD:temp3DWave, root:tempData:
Variable numRows = dimSize(temp3DWave,0)
Variable numColumns = dimSize(temp3DWave,1)
Variable numLayers = dimSize(temp3DWave, 2)
Variable i, ii
Variable numStatParam = 6
// Make the output wave
Make/O/N=(numColumns,numLayers,numStatParam) workedAvgWave // distribution wave for mean(layer0) and median(layer1)
SetDimLabel 2, 0, TheMedian, workedAvgWave
SetDimLabel 2, 1, TheMean, workedAvgWave
SetDimLabel 2, 2, Q10, workedAvgWave
SetDimLabel 2, 3, Q90, workedAvgWave
SetDimLabel 2, 4, Q25, workedAvgWave
SetDimLabel 2, 5, Q75, workedAvgWave
Variable numberpoints
for(ii=0; ii<numLayers; ii +=1)
for(i=0; i<numColumns; i += 1)
String colName = "temp_" + num2str(i)
MAKE/O/N=(numRows) $(colName)/Wave=ww
ww = temp3DWave[p][i][ii]
Sort ww, ww
// We need to remove NANs becuase mean doesn't support NaNs.
//WaveTransform zapNaNs, ww
ww = ww[p] == NaN ? 0 : ww[p]
// Calculate inter quartile ranges and mean/median values
WaveStats/Q/Z ww
numberpoints = V_npnts
workedAvgWave[i][ii][%TheMedian] = ww[((numberpoints+1)/2)-1]
workedAvgWave[i][ii][%TheMean] = V_avg
workedAvgWave[i][ii][%Q10] = ww[(2*(numberpoints/20))-1]
workedAvgWave[i][ii][%Q90] = ww[(18*(numberpoints/20))-1]
workedAvgWave[i][ii][%Q25] = ww[(numberpoints/4)-1]
workedAvgWave[i][ii][%Q75] = ww[3*(numberpoints/4)-1]
endfor
endfor
if(DataFolderExists("root:SizeResolved:")==0)
NewDataFolder root:SizeResolved
MoveWave root:tempData:workedAvgWave, root:SizeResolved:
KillDataFolder/Z root:tempData
SetDataFolder root:SizeResolved:
else
KillDataFolder/Z root:SizeResolved
NewDataFolder root:SizeResolved
SetDataFolder root:SizeResolved
MoveWave root:tempData:workedAvgWave, root:SizeResolved:
KillDataFolder/Z root:tempData
endif
End
Thanks everyone for any contribution, idea, etc.
Cheers,
Emre
March 3, 2015 at 05:21 am - Permalink
Cheers,
Emre
P.S. If someone is interested in what I did. Here is the function I use now.
String ctrlName
String format
String left, right
Variable leftDP, rightDP // after reading input from user, left and right edge of the wave are saved in these variables
// these variables are later used to extract a part of the data (the interval we want to analyse)
SetDataFolder root:
KillDataFolder/Z root:SizeResolved
SetDataFolder root:INCD
Prompt left, "Enter left component" //Please enter a valid start point for the analysis, example: 01.01.2015 00:00:00 (dd.mm.yyyy hh:mm:ss)
Prompt right, "Enter right component" //Please enter a valid start point for the analysis, example: 01.01.2015 00:00:00 (dd.mm.yyyy hh:mm:ss)
DoPrompt "Enter start and end times", left, right
if (V_Flag)
return -1
endif
Variable day, month, year, hour, minute, second
format = "%d.%d.%d %d:%d:%d"
sscanf left, format, day, month, year, hour, minute, second // read first entry (start time of the analysis)
if(day<=0 || day>31 || month<=0 || month>12 || year<1999 || year>2100) // is the entry correct? test
Print "Error in Date format. Please enter a valid date"
return -1
else
leftDP = Date2Secs(year,month,day)
leftDP += second + 60*minute + 60*60*hour
endif
sscanf right, format, day, month, year, hour, minute, second // read second entry (end time of the analysis)
if(day<=0 || day>31 || month<=0 || month>12 || year<1999 || year>2100) // same for the second entry
Print "Error in Date format. Please enter a valid date"
return -1
else
rightDP = Date2Secs(year,month,day)
rightDP += second + 60*minute + 60*60*hour
endif
if(leftDP >= rightDP) // this checks if you entered correct time interval. otherwise cancels the procedure.
print "error - check your data"
return -1
endif
if(!leftDP && !rightDP)
buildSizeResolvedRatio()
plotRatioData()
else
buildSelectedSizeResolvedRatio(leftDP,rightDP)
plotRatioData()
endif
End
March 3, 2015 at 07:22 am - Permalink