#pragma rtGlobals=3 // Use modern global access method and strict wave access. Menu "Macros" "Load tif movie", LoadMoviePanel() End Function LoadMoviePanel() initialization() newPanel/w = (1170,50,1350,135)/n=Panel Button LoadMovie title="Load",pos={5,10},size={70,30},fColor=(0,52224,0),proc=LoadMovie Button Kill title="Kill",pos={5,45},size={70,30},fColor=(20000,0,20000),proc=KillData EnableDisableAnalysisButton() end Function initialization() newdatafolder/O root:WindowsExplorer newdatafolder/O root:RawData newdatafolder/O root:Analysis setdatafolder root:WindowsExplorer end Function LoadMovie(CtrlName):ButtonControl string CtrlName initialization() setdatafolder root:WindowsExplorer string/G fileName string/G filePath string/G format = ".tif" string/G file_Name WindowsExplorer() Setdatafolder root:RawData variable/G sizeOfRows,sizeOfColumns,sizeOfFrames variable/G MinColorValue,MaxColorValue variable/G frameNum variable/g FirstFrame=0 variable/g LastFrame variable/G framesPerSec=4 wave singleFrame wave movie ImageLoad/C=-1/G/O/Q/T=tiff filePath file_Name = s_filename duplicate/O/R=[][][frameNum,frameNum] $s_filename, singleFrame sizeOfRows = dimsize($s_filename,0) sizeOfColumns = dimsize($s_filename,1) sizeOfFrames = dimsize($s_filename,2) LastFrame = sizeOfFrames-1 rename $s_filename,movie EnableDisableAnalysisButton() doWindow/R/f ShowMovie display/w=(10,10,360,200*1.618+10) as s_filename newImage/F/HOST=# singleFrame SetAxis/A left wavestats/Q/M=1 root:rawData:movie MinColorValue=V_min MaxColorValue=V_max ModifyImage singleFrame ctab= {MinColorValue,MaxColorValue,grays,0} movesubwindow fnum=(50,0,200,200*1.618) newPanel/HOST=##/FG=(FL,FT,,FB)/W=(0,0,50,200*1.618) ModifyPanel frameInset=0,frameStyle=0 doupdate button play appearance={default},fstyle=0,size={50,30},pos={5,5},title="Play",fColor=(0,30000,0),proc=Play_Movie setVariable FramesPerSec,appearance={default},pos={5,35},title=" ",value=framesPerSec,limits={1,100,0},size={20,18} setDrawEnv fname= "Times New Roman",fsize=10 drawText 30,48,"Frame/s" ValDisplay FrameNum_shown,pos={22,380},size={40,13} ValDisplay FrameNum_shown,valueBackColor=(47872,47872,47872) ValDisplay FrameNum_shown,limits={0,0,0},barmisc={0,1000} ValDisplay FrameNum_shown,value= #"root:RawData:frameNum" slider frameNum appearance={os9},limits={0,sizeOfFrames-1,1},ticks=1,live=1,fsize=9,pos={22,55},Size={30,1.618*200},side=1,vert=1,variable= frameNum,proc=MovingSlider setVariable FirstFrame,appearance={default},pos={5,400},title=" ",value=FirstFrame,limits={0,sizeOfFrames-1,0},size={22,13} setVariable LastFrame,appearance={default},pos={5,415},title=" ",value=LastFrame,limits={FirstFrame,sizeOfFrames-1,0},size={22,13} button cutMovie appearance={default},fstyle=0,size={30,30},pos={30,400},title="Cut",fColor=(15000,15000,0),proc=cutMovie Dokymograph() end Function EnableDisableAnalysisButton() wave movie = root:RawData:movie if (waveexists(movie) == 0) Button Analysis title="Analyze", pos={80,10},size={50,64},fColor=(32768,54528,65280),proc=MovieAnalysis,disable=2 Button Clear title="Clear",pos={132,10},size={38,64},fColor=(65280,16384,35840),proc=ClearData,disable=2 else Button Analysis title="Analyze", pos={80,10},size={50,64},fColor=(32768,54528,65280),proc=MovieAnalysis,disable=0 Button Clear title="Clear",pos={132,10},size={38,64},fColor=(65280,16384,35840),proc=ClearData,disable=0 endif end Function MovingSlider(CtrlName, value, event) string CtrlName variable value,event NVAR frameNum=root:rawData:frameNum wave Movie=root:rawData:Movie wave singleFrame=root:rawData:singleFrame duplicate/O/R=[][][frameNum,frameNum] movie, singleFrame end Function Play_Movie(CtrlName):ButtonControl string CtrlName variable value,event,i,ElapseTime NVAR framesPerSec = root:rawData:framesPerSec NVAR sizeOfFrames = root:rawData:sizeOfFrames NVAR frameNum = root:rawData:frameNum ElapseTime = 1/framesPerSec if(frameNum==sizeOfFrames-1) for(i=0;i rightBoundary) duplicate/O/R=[0,sizeOfFrames-1][0,leftBoundary] Kymograph, Kymograph_lower duplicate/O/R=[0,sizeOfFrames-1][rightBoundary,sizeOfColumns-1] Kymograph, Kymograph_upper for(i=0;iBoundary[i]) Kymograph_lower[i][j]=bleachedIntensity[i] endif endfor for (j=0;jBoundary[i]) Kymograph_lower[i][j]=bleachedIntensity[i] endif endfor for (j=0;j=Upper_sizeOfColumns) // continue // else // sxy = sxy + (Kymograph_upper[0][j] - xm)*(Kymograph_upper[i][j-Upper_centralShift[0]+Upper_centralShift[i]+d] - ym) // sy = sy + (Kymograph_upper[i][j-Upper_centralShift[0]+Upper_centralShift[i]+d] - ym)^2 // endif // endfor // Upper_CrossCor[d+maxDelay_upper][i] = sxy/(sx*sy)^0.5 // endfor // // CurveFit/Q gauss, Upper_CrossCor[*][i]/X=upper_delayNum // rename W_coef tempwave // wave tempwave // Upper_centralShift_temp[i] = tempwave[2] // killwaves root:Analysis:W_sigma // killwaves root:Analysis:tempwave // Upper_centralShift[i] = Upper_centralShift[i] + Upper_centralShift_temp[i] // endfor // // for (i=sizeOfFrames-1;i>=0;i=i-1) // Upper_centralShift[i] = (Upper_centralShift[i] - Upper_centralShift[0])*pixelSize // endfor display/w=(370,55+95*1.618,520,55+190*1.618) as "Lower part" newimage/f/HOST=# Kymograph_lower movesubwindow fnum=(0,0,150,95*1.618) CrossCorrelation("Kymograph_lower","_lower",0) wave centralShift_lower = root:Analysis:centralShift_lower CrossCorrelation("Kymograph_lower","_lowerEdge",1) wave centralShift_lowerEdge = root:Analysis:centralShift_lowerEdge // //for Kymograph_lower // make/N=(sizeOfFrames) lower_centralShift // for (i=0;i=lower_sizeOfColumns) // continue // else // sxy = sxy + (Kymograph_lower[0][j] - xm)*(Kymograph_lower[i][j-lower_centralShift[0]+lower_centralShift[i]+d] - ym) // sy = sy + (Kymograph_lower[i][j-lower_centralShift[0]+lower_centralShift[i]+d] - ym)^2 // endif // endfor // lower_CrossCor[d+maxDelay_lower][i] = sxy/(sx*sy)^0.5 // endfor // // CurveFit/Q gauss, lower_CrossCor[*][i]/X=lower_delayNum // rename W_coef tempwave // wave tempwave // lower_centralShift_temp[i] = tempwave[2] // killwaves root:Analysis:W_sigma // killwaves root:Analysis:tempwave // lower_centralShift[i] = lower_centralShift[i] + lower_centralShift_temp[i] // endfor // // for (i=sizeOfFrames-1;i>=0;i=i-1) // lower_centralShift[i] = (lower_centralShift[i] - lower_centralShift[0])*pixelSize // endfor display/w=(530,10,800,10+90*1.618) centralShift_upper vs timeSeries appendtograph centralShift_lower vs timeSeries appendtograph centralShift_upperEdge vs timeSeries appendtograph centralShift_lowerEdge vs timeSeries ModifyGraph rgb(centralShift_lower)=(0,9472,39168) ModifyGraph rgb(centralShift_upper)=(0,9472,39168) ModifyGraph lstyle(centralShift_lower)=3 ModifyGraph lstyle(centralShift_lowerEdge)=3 Label bottom "Time (s)" Label left "Distance shifted (nm)" end Function CrossCorrelation(KymographName,NameAddOn,mode) // mode defines whether targets bright band or dark boundary for cross-correlation, 0 is bright band, 1 is dark boundary //The length of segment used for cross-correlation is 2*halfseriesSize+1 //maxDelay defines the max number of pixel one segment can move away from the other during correlation string KymographName,NameAddOn variable mode variable/G halfseriesSize variable/G maxDelay if(strlen(WaveList(KymographName,";",""))==0) Doalert 0,"Wrong wave name input, man" return -1 endif string pathOfKymo = "root:Analysis:" + KymographName string centralShift = "centralShift" + NameAddOn string crossCor = "crossCor"+ NameAddOn string delayNum = "delayNum" + NameAddOn string centralShift_temp = "centralShift_temp" + NameAddOn string halfseriesSizeName = "halfseriesSize" + NameAddOn string maxDelayName = "maxDelay" + NameAddOn string centralshift_band = "centralshift_band" + NameAddOn wave Kymowave = $pathOfKymo variable xm,ym,sx,sy,sxy,d,i,j variable sizeOfColumns_part = dimsize(Kymowave,1) NVAR sizeOfFrames = root:RawData:sizeOfFrames NVAR sizeOfColumns = root:RawData:sizeOfColumns NVAR pixelSize = root:Analysis:pixelSize variable temp_0,temp_1 variable/G offset if (dimOffset(Kymowave,1)>0) offset = sizeOfColumns - sizeOfColumns_part elseif (dimOffset(Kymowave,1)==0) offset = 0 endif make/O/N=(sizeOfFrames) tempwave1 //centralShift if (mode==0) //detect bright band make/O/N=(sizeOfFrames) tempwave0 for (i=0;i 30) halfseriesSize = 30 endif maxdelay = halfseriesSize killwaves/z tempwave0 duplicate tempwave1 $centralshift_band appendToGraph/C=(0,0,65000) $centralshift_band temp_0 = tempwave1[0]-offset - halfseriesSize temp_1 = tempwave1[0]-offset + halfseriesSize elseif (mode==1) //Detect edge FindThreeStates(KymographName) string pathOfEdge1 = "root:Analysis:" + KymographName + "Edge1" string pathOfEdge2 = "root:Analysis:" + KymographName + "Edge2" wave Edge1 = $pathOfEdge1 wave Edge2 = $pathOfEdge2 wave tempwave1 = root:Analysis:tempwave1 AppendToGraph Edge1 AppendToGraph Edge2 halfseriesSize = 5 maxDelay = 5 temp_0 = tempwave1[0] - halfseriesSize temp_1 = tempwave1[0] + halfseriesSize else Doalert 0, "we only have mode 0 and 1..." endif make/N=(2*maxDelay+1,sizeOfFrames) tempwave2 //$crossCor make/N=(2*maxDelay+1) tempwave3 //$delayNum for(i=0;i<2*maxDelay+1;i=i+1) tempwave3[i] = i - maxDelay endfor make/N=(sizeOfFrames) tempwave4 //$centralShift_temp duplicate/O/R=[0,0][temp_0,temp_1] Kymowave,Kymo_zero wavestats/Q/M=1 Kymo_zero xm=V_avg for (j=temp_0;j<=temp_1;j=j+1) sx = sx + (Kymowave[0][j] - xm)^2 endfor variable temp_2, temp_3 for (i=0;isizeOfColumns_part-1) continue else sxy = sxy + (Kymowave[0][j] - xm)*(Kymowave[i][j-tempwave1[0]+tempwave1[i]+d] - ym) sy = sy + (Kymowave[i][j-tempwave1[0]+tempwave1[i]+d] - ym)^2 endif endfor tempwave2[d+maxDelay][i] = sxy/(sx*sy)^0.5 endfor CurveFit/Q gauss, tempwave2[*][i]/X=tempwave3 rename W_coef wavetemp wave wavetemp tempwave4[i] = wavetemp[2] killwaves root:Analysis:W_sigma killwaves root:Analysis:wavetemp tempwave1[i] = tempwave1[i] + tempwave4[i] endfor for (i=sizeOfFrames-1;i>=0;i=i-1) tempwave1[i] = (tempwave1[i] - tempwave1[0])*pixelSize endfor rename tempwave1 $centralShift rename halfseriesSize $halfseriesSizeName rename maxDelay $maxDelayName killwaves/z tempwave2 killwaves/z tempwave3 killwaves/z tempwave4 killwaves/z Kymo_zero Killwaves/z Kymowave_temp // rename tempwave2 $crossCor // rename tempwave3 $delayNum // rename tempwave4 $centralShift_temp End Function FindThreeStates(KymographName) //this function serves to find two boundary points to segregate each slice of Kymograph into three parts string kymographName string pathOfKymo = "root:Analysis:" + KymographName string Edge1name = KymographName + "Edge1" string Edge2name = KymographName + "Edge2" wave Kymowave = $pathOfKymo variable sizeOfColumns_part = dimsize(Kymowave,1) NVAR sizeOfFrames = root:RawData:sizeOfFrames NVAR offset = root:Analysis:offset variable i,j,k,tempvar1,tempvar2 make/O/N=(sizeOfColumns_part,sizeOfColumns_part,4,sizeOfFrames) bestFitOfSteps//this matrix stores the best fitting parameter for each row of wave "column_addup_part" //first layer is sum of chi-square, second layer is average of the first segment //third layer is average of the second segment, forth layer is average of the third segment //rows num equals the point of the first step, columns num is the point of the second step bestFitOfSteps = Nan make/O/N=(sizeOfFrames) Edge1 make/O/N=(sizeOfFrames) Edge2 make/O/N=(sizeOfFrames) tempwave1 for (i=0;i0)) tempwave1[i] = V_minRowLoc endif endfor rename Edge1 $Edge1name rename Edge2 $Edge2name end //Function BleachedArea():GraphMarquee // setdatafolder root:Analysis // variable/G startrow,endrow,startcolumn,endcolumn // variable/G BleachedIntensity = 0 // variable marqueeWidth,marqueeHeight // variable i,j // wave Kymograph = root:rawData:Kymograph // getMarquee left,bottom // startrow = floor(v_bottom) // endrow = ceil(v_top) // startcolumn = floor(v_left) // endcolumn = ceil(v_right) // if (startcolumn < 0) // startcolumn = 0 // endif // marqueeWidth = endColumn-startColumn+1 // marqueeHeight = endRow-startRow+1 // // for (i=startcolumn;i<=endcolumn;i=i+1) // for (j=startrow;j<=endrow;j=j+1) // BleachedIntensity = BleachedIntensity + Kymograph[i][j] // endfor // endfor // // BleachedIntensity = BleachedIntensity/MarqueeWidth/MarqueeHeight //end Function WindowsExplorer() setdatafolder root:WindowsExplorer string path = "C:Users:lc:Desktop:For LuChen Data2" string subpath SVAR fileName = root:WindowsExplorer:fileName SVAR filePath = root:WindowsExplorer:filePath SVAR format = root:WindowsExplorer:format string fileList Prompt path, "Where to load your data?" DoPrompt "Enter your path", path if (V_Flag) //user canceled return -1 endif Do newpath/O/Q DataPath, path fileList = indexedDir(Datapath,-1,0) fileList = fileList + indexedfile (Datapath,-1,format) Prompt subpath "Which would you choose?" popup fileList DoPrompt "Choose your path" subpath if (V_Flag) return -1 endif if (stringmatch (subpath,"!*.*")) path = path+":"+subpath else break endif while(1) path = path+":"+subpath filePath = path fileName = ParseFilePath (3, filePath,":",0,0) fileName = CleanupName (fileName,0) end Function KillData(CtrlName):ButtonControl String CtrlName String graphName killwindows(0) setdatafolder root: Killdatafolder/z root:WindowsExplorer Killdatafolder/z root:RawData Killdatafolder/z root:Analysis EnableDisableAnalysisButton() end Function ClearData(CtrlName):ButtonControl string CtrlName dowindow/F graph0 killwindows(1) Killdatafolder/z root:Analysis newdatafolder/O root:Analysis end Function killwindows(value) variable value String graphName Do graphName=winName(value,1) if (strlen(graphName)==0) break endif killwindow $graphName While(1) end Function PressEscapeToAbort() Variable doAbort = 0 if (GetKeyState(0) & 32) // Is Escape key pressed now? doAbort = 1 endif return doAbort End