#pragma rtGlobals=1 // Use modern global access method. #pragma IgorVersion = 6.2 #pragma version = 4.8 #include #include #include #include #include #include #include // written by Matt Sfeir, Brookhaven National Laboratory // msfeir@bnl.gov // v.4.8 February 6. 2015 // Build menu items Menu "Load Waves" "Load Transient Absorption Data", OpenTA() End Menu "TA Analysis" "Load Transient Absorption Data", OpenTA() "Import SX Pro Solvent Fit Coeffs", ImportCC() "Export Data as CSV", ExportCSV() "-" "Inspect Image Data", ImageHookGen() // "Kill Data Inspector", KillHookGen() // "-" "Extract Kinetics", ExtractKin() "Extract Spectra", ExtractSpec() "-" "Time Zero Correction", T0ImCorr() "Scattered Light Correction", DisplayIntBkgdControlPanel() "Extract Region of Interest", ImageROI() "Combine Data Sets", JoinMatrices() "-" "Generate Fit Coeffs from Solvent Response",FitSolvFC() "Generate t0 wave from Fit Coeffs", t0WaveGen() "Chirp Correction from t0 Wave", ChirpCorrect() "-" "Singular Value Decomposition", AutoSVG() "Rank SVD Matrices", RankSVD() "Global Fit", WM_NewGlobalFit1#InitNewGlobalFitPanel() "Store Coeffients from GF", ProcessGFResult() "Species Absorption from GF", ReconWrapper() "-" "Generate Progressive Time Axis", ExpTimeAxis() "New Generate PTA - Helios v14", ExpTimeAxisHv14() End /////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// // For debugging. Remove Later. Function KillHookGen() //DoWindow/K kinetics0 //DoWindow/K spectra0 DoWindow/K kinetics DoWindow/K spectra KillDataFolder root:Packages:InspectData return 0 End /////////////////////////////////////////////////////////////////////////////////////////////// // Modify Open File Dialog to break if cancelled Function OpenTA() Variable refNum String message = "Select a file" String outputPath, fileHandle, wName, wName2 String fileFilters = "Transient Absorption Data Files (*.csv):.csv;" fileFilters += "All Files:.*;" Open /D /R /F=fileFilters /M=message refNum outputPath = S_fileName if(cmpstr(outputPath,"",0) == 0) Print "Open file cancelled." return 0 else printf "%s\r" outputPath endif fileHandle = ParseFilePath(5, outputPath, ":", 0,0) fileHandle = ParseFilePath(3, outputPath, ":", 0,0) printf "%s\r" fileHandle Variable lengthTest = strlen(fileHandle) // shorten string to 22 characters to satisfy Igor constraints on wave name length // max is 31. start with 22 so that we can append suffix. fileHandle = CleanUpName(fileHandle, 0) if(lengthTest >= 22) Variable i = lengthTest - 22 Variable j=0 do fileHandle = RemoveEnding(fileHandle) j+=1 while(j <= i) else fileHandle = fileHandle endif //Print "fileHandle = " + fileHandle Prompt fileHandle, "Base name for waves" DoPrompt "Edit generated wave name . . .", fileHandle if (V_flag == 1) Print "Open file cancelled." return 0 else LoadWave/J/M/U={0,2,0,2}/D/A=$fileHandle/K=0 outputPath endif // what is the wave named when it is loaded // since we delete the original matrix // the name we want is not always the name we get wName = StringFromList(2, S_waveNames) String sval String expr = fileHandle + "([[:digit:]]+)" SplitString/E=(expr) wName, sval Variable val val = str2num(sval) // need to separate wave names for this to work Print wName // Print val ProcessTAIP7(wName, outputPath, val) End // Loads waves and processes them for plotting // Called by OpenTA() Function ProcessTAIP7(wName, outputPath, val) // CMD - . aborts the procedure String wName, outputPath Variable val Duplicate $wName w String RPName = "RP_" + wName String CPName = "CP_" + wName Wave/Z RPtemp =$RPName Wave/Z CPtemp =$CPName Duplicate RPtemp RP Duplicate CPtemp CP // kill orignal waves generated by LoadFile before processing KillWaves $wName, $RPName, $CPName String wNamebase = RemoveEnding(wName, num2str(val)) Print wNamebase Variable b=val String wName2 = wName + "_zmat" if (WaveExists ($wName2) == 1) do b += 1 wName = wNamebase + num2str(b) Print wName wName2 = wName + "_zmat" Print wName2 while(WaveExists ($wName2) == 1) // write b-1 since loop runs one more time than we want //wName = fileHandle + num2str(b-1) endif // Wave w,RP,CP Variable m, n, pp, qq, r // remove NaNs and Infs. Replace with zeros. m = Dimsize(w,0) // numer of rows // printf "%f\r" m n = Dimsize(w,1) // number of columns Make/N=(m,n) /D/O Zmat // numtype==1 --> INF // numtupe==2 --> NaN // ? : conditional operator If-Else-Endif // (expression) ? : Zmat= (numtype(w) == 1) ? 0 : w Zmat= (numtype(Zmat) == 2) ? 0 : Zmat Make/N=(m) /D/O ContX ContX= (numtype(RP) == 1) ? 0 : RP ContX= (numtype(ContX) == 2) ? 0 : ContX Make/N=(n) /D/O ContY ContY= (numtype(RP) == 1) ? 0 : CP ContY= (numtype(ContY) == 2) ? 0 : ContY // remove extra rows - often contain bad data // re-write to handle arbitrary sized wavelength dimension while scaling is monotonic, increasing // re-write again: we are checking from the end of the wave. Sometimes footer information contains // monotonic numbers as a note // Make it so that it starts from the front of the wave and quits after first non-monotonic point qq = Dimsize(ContX,0) // Variable aa = qq // Do // Redimension /N=(aa) ContX // Redimension /N=(aa,-1) Zmat // aa-=1 // While(ContX[aa] <= ContX [aa-1]) // qq = Dimsize(ContX,0) // Print qq Variable aa = 0 Do If(aa+1 >= qq) break Endif aa+=1 While(ContX[aa] >= ContX [aa-1]) // don't redimension yet - will remove all footer info // Redimension /N=(aa+1) ContX // Redimension /N=(aa+1,-1) Zmat // redefine qq qq = aa // EDIT:: 2015/04/06 // remove extra columns - this seems to be an issue with new (2015) EOS software Variable nrowsi = Dimsize(ContY,0) Variable bb = 0 // Make it so that it starts from the front of the wave and quits after first non-monotonic point Do If(bb+1 >= nrowsi) break Endif bb+=1 While(ContY[bb] >= ContY [bb-1]) // redefine nrowsi nrowsi = bb //ENDEDIT // use new length information to import footer text // needs to be handled after extra rows are removed so we know where to start importing // without resorting to regular expressions Variable refNum2 String buffer Variable linenumber, len linenumber = 0 Open/R refNum2 outputPath do //Print linenumber FReadLine refNum2, buffer len = strlen(buffer) if(len == 0) break endif if(linenumber > qq) Print buffer Note/NOCR Zmat, buffer endif linenumber +=1 while(1) Close refNum2 // Now redimension Redimension /N=(aa) ContX Redimension /N=(nrowsi) ContY Redimension /N=(aa,nrowsi) Zmat // continue with formatting m = Dimsize(Zmat,0) // numer of rows n = Dimsize(Zmat,1) // number of columns pp = m*n Make/N=(n) /D/O ContY ContY= (numtype(CP) == 1) ? 0 : CP ContY= (numtype(ContY) == 2) ? 0 : ContY Make/N=(pp) /D/O tempXwave Make/N=(pp) /D/O tempYwave Make/N=(pp) /D/O tempZwave Make/N=(m+1) /D/O ImageX Make/N=(n+1) /D/O ImageY Make/N=(M,N,3) /O ParametricWave // create new processed row, column positions and z matrix // can be used to generate contour plot Variable i,j i=0 do j=0 do tempXwave[j+m*i]=ContX[j] tempYwave[j+m*i]=ContY[floor((j+m*i)/m)] tempZwave[j+m*i]=Zmat[j][i] j +=1 while (j <=m) i +=1 while (i <= n) Concatenate/O {tempXwave, tempYwave, tempZwave}, wScatterMatrix KillWaves tempXwave, tempYwave, tempZwave // Format for Image Plot // Create x and y wave for image. Points define start and end of pixel positions, not center // so need to generate N+1 points from N. // Add point at [-1] at same distance from [0] as [1] // and shift by [0] - [1] distance OR pick midpoint between consecutive points // assuming smallest increment at start of wave // this needs to be modifed to ensure that data is monotonic // bug in Variable g, h ImageX[0]= ContX[0]-((ContX[1]-ContX[0])/2) // g = 0 // do // ImageX[g+1]=ContX[g]+((ContX[1]-ContX[0])/2) // g += 1 // while (g <= m) g=1 do ImageX[g] = (ContX[g] + ContX[g-1])/2 g += 1 while (g < m) ImageX[m] = ContX[m-1] + ((ContX[m-1] - ContX[m-2])/2) ImageY[0]= ContY[0]-((ContY[1]-ContY[0])/2) // h=0 // do // ImageY[h+1]=ContY[h]+((ContY[1]-ContY[0])/2) // h += 1 // while (h <= n) h=1 do ImageY[h] = (ContY[h] + ContY[h-1])/2 h+= 1 while (h < n) ImageY[n] = ContY[n-1] + ((ContY[n-1] - ContY[n-2])/2) // start looking for non-monotonic behavior at point 1 not point 0 // assume first 2 points are good Variable h2 = 1 Variable deltaNM Variable ipts, jpts //Variable h2orig do ipts = 2 // first find 2 consecutive equal points if (ImageY[h2] == ImageY[h2+1]) // now check for more using ipts as a counting variable //Print "non-monotonic" do if(ImageY[h2] == ImageY[h2+ipts]) ipts+=1 else //Print "breaking . . ." break endif while(ipts<100) // use ipts and previous non-equal point to define spacing deltaNM = Abs((ImageY[h2+ipts]-ImageY[h2] ))/ipts //print deltaNM jpts = 0 do ImageY[h2+jpts] = ImageY[h2+jpts] + (jpts)*deltaNM jpts +=1 while(jpts < ipts) endif //Print h2 h2 +=1 // stop one point before the end while(h2 < n -1) // generate Parametic data. // used for uneven spacings in surface plots Variable k,l k=0 do l=0 do ParametricWave[k][l][0]=ContX[k] ParametricWave[k][l][1]=ContY[l] ParametricWave[k][l][2]=Zmat[k][l] l +=1 while (l <= n) k +=1 while (k <= m) // clean up wave names // String ZmatName = NameOfWave(w) + "_zmat" String ZmatName = wName + "_zmat" Duplicate/O Zmat, $ZmatName // String ContXName = NameOfWave(w) + "_xc" String ContXName = wName + "_xc" Duplicate/O ContX, $ContXName // String ContYName = NameOfWave(w) + "_yc" String ContYName = wName + "_yc" Duplicate/O ContY, $ContYName // String ImageXName = NameOfWave(w) + "_xim" String ImageXName = wName + "_xim" Duplicate/O ImageX, $ImageXName // String ImageYName = NameOfWave(w) + "_yim" String ImageYName = wName + "_yim" Duplicate/O ImageY, $ImageYName // String ScatMatName = NameOfWave(w) + "_sca" String ScatMatName = wName + "_sca" Duplicate/O wScatterMatrix, $ScatMatName // String ParaName = NameOfWave(w) + "_par" String ParaName = wName + "_par" Duplicate/O ParametricWave, $ParaName // Generate default image qq = Dimsize(ContX,0) if(qq == 1) Plot1DFromMat2(ZmatName, 0, 0, ContXName, ContYName, 0) else Display;AppendImage $ZmatName vs {$ImageXName,$ImageYName};DelayUpdate ModifyImage $ZmatName ctab= {*,*,Rainbow,0} ModifyImage $ZmatName ctabAutoscale=3,lookup= $"" ShowInfo Cursor/I/H=1 A $ZmatName 1,1 Cursor/M/H=1 B // GetWindow kwTopWin wtitle // String imTitle = S_Value // imTitle = RemoveEnding(imTitle, ":") // Cursor/I/H=1 /W=$imTitle A $ZmatName 1,1 // Cursor/M/H=1 B // if inspector is already enabled on other images // enable by default on subsequent images //DoWindow kinetics0 // DoWindow kinetics // if (V_Flag == 1) // SetWindow $imTitle, hook(MyHook)=MyWindowHook // else // return 0 // endif // DoUpdate ImageHookGen() endif KillWaves Zmat KillWaves ContX KillWaves ContY KillWaves ImageX KillWaves ImageY KillWaves wScatterMatrix KillWaves ParametricWave, w, RP, CP return 0 End ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// // Inspect Image Data section // Apply Window Hook Calls to existing image Function ImageHookGen() // No need to build new image // Just apply window hook function to top window // first make sure this is an image String ImTest = ImageInfo("","",0) // make this only applicable to images if(cmpstr(Imtest,"",0) == 0) Print "Not an image." return 0 else String info= ImageInfo("","",0) String zmatName = StringByKey("ZWAVE",info) String xwName = StringByKey("XWAVE",info) String ywName = StringByKey("YWAVE",info) // figure out which one is z String Zregex = "(.*?)(zmat|zibg|zroi|zccm|A.sv)" Print "Z = " + zmatName GetWindow kwTopWin, wtitle String imTitle = S_Value // Cursor/I A $ZMatName 1,1 // add call for Window Hook - testing phase SetWindow kwTopWin, hook(MyHook)=MyWindowHook // build window for displaying kinetics String base, xybase String suffix, xysuffix String regex = "(.*?)(zmat|zibg|zroi|zccm|A.sv)" SplitString /E=(regex) ZMatName, base, suffix String XYregex = "(.*?)(ximr|xim|xcim)" SplitString /E=(XYregex) xwName, xybase, xysuffix Print xysuffix if(CmpStr(xysuffix,"")==0) xwName = "NewXwave" ywName = "NewYWave" elseif(CmpStr(xysuffix,"ximr")==0) ywName = xybase + "yroi" xwName = xybase + "xroi" elseif(CmpStr(xysuffix,"xcim")==0) ywName = xybase + "ycc" xwName = xybase + "xcc" elseif(CmpStr(xysuffix,"xim")==0) ywName = xybase + "yc" xwName = xybase + "xc" endif endif // first data to display for kinetics Variable xpos, lambda xpos = pcsr(A) lambda = hcsr(A) // first data to display for spectra Variable ypos, stime ypos = qcsr(A) stime = vcsr(A) // build kinetics graph Wave kM = $ZMatName // Wave lM = $xwName // generate target wave for kinetic information // named appropriately with the wavelength Variable m,n m = Dimsize(kM,0) // numer of rows n = Dimsize(kM,1) // number of columns // name with generic name so it can be continuously overwritten // can be copied later with appropriate command // String kWaveName = "kinetics" // String sWaveName = "spectra" String kWaveName = "kineticsA" String sWaveName = "spectraA" // why do we change names here? String tWave = ywName // . . . and lambda wave String sWave = xwName Make/D/O/N=(n) $kWaveName Wave w = $kWaveName Make/D/O/N=(m) $sWaveName Wave v = $sWaveName // replace with MatrixOp //w = kM[xpos] [p] MatrixOp/O w = row(kM,xpos)^t //v = kM[p][ypos] MatrixOp/O v = col(kM, ypos) // break out graphing function so that the panel can be modified // first create global variables if they don't exist if(DataFolderExists("root:Packages:InspectData") == 0) NewDataFolder/O root:Packages NewDataFolder/O root:Packages:InspectData endif String/G root:Packages:InspectData:gMessagek= "" String/G root:Packages:InspectData:gMessagekB= "" String/G root:Packages:InspectData:gMessageki= "" String/G root:Packages:InspectData:gMessageXSck= "" String/G root:Packages:InspectData:gMessageYSck= "" Variable/G root:Packages:InspectData:gCursB= 0 String/G root:Packages:InspectData:gMessages= "" String/G root:Packages:InspectData:gMessagesB= "" String/G root:Packages:InspectData:gMessagesi= "" String/G root:Packages:InspectData:gMessageXScs= "" String/G root:Packages:InspectData:gMessageYScs= "" // next fill in string values SVAR gMessagek = root:Packages:InspectData:gMessagek SVAR gMessagekB = root:Packages:InspectData:gMessagekB SVAR gMessageki = root:Packages:InspectData:gMessageki gMessagek = num2str(lambda) gMessageki = ZMatName NVAR gCursB = root:Packages:InspectData:gCursB SVAR gMessages = root:Packages:InspectData:gMessages SVAR gMessagesB = root:Packages:InspectData:gMessagesB SVAR gMessagesi = root:Packages:InspectData:gMessagesi gMessages = num2str(stime) gMessagesi = ZMatName // make waves for cursor B anyway // same size as A String kWaveNameB = "kineticsB" String sWaveNameB = "spectraB" Make/D/O/N=(n) $kWaveNameB Make/D/O/N=(m) $sWaveNameB Wave wB = $kWaveNameB Wave vB = $sWaveNameB Variable xposB, lambdaB Variable yposB, stimeB // initialize properly if B is on graph Variable bExists= strlen(CsrInfo(B)) > 0 if (bExists == 1) gCursB = 1 // first data to display for kinetics xposB = pcsr(B) lambdaB = hcsr(B) gMessagekB= num2str(lambdaB) // first data to display for spectra yposB = qcsr(B) stimeB = vcsr(B) gMessagesB = num2str(stimeB) //wB = kM[xposB] [p] MatrixOp/O wB = row(kM, xposB)^t //vB = kM[p][yposB] MatrixOp/O vB = col(kM, yposB) else gCursB = 0 gMessagekB = "" gMessagesB = "" endif // now build graphs InspectGraphK(kWaveName, tWave, "kinetics") InspectGraphS(sWaveName, sWave, "spectra") // do these only if cursor B is already on the graph if (bExists == 1) InspectGraphK(kWaveNameB, tWave, "kinetics") InspectGraphS(sWaveNameB, sWave, "spectra") endif return 0 End Function InspectGraphK(ywave, xwave, wvname) String ywave, xwave, wvname //String wwname = wvname + "0" String wwname = wvname if(DataFolderExists("root:Packages") == 0) NewDataFolder/O root:Packages endif // Print wwname // make sure proper folder exists for global variables // do not switch to this folder SVAR gMessagek = root:Packages:InspectData:gMessagek SVAR gMessageki = root:Packages:InspectData:gMessageki SVAR gMessagekB = root:Packages:InspectData:gMessagekB NVAR gCursB = root:Packages:InspectData:gCursB SVAR gMessageXSck = root:Packages:InspectData:gMessageXSck SVAR gMessageYSck = root:Packages:InspectData:gMessageYSck String grState // create new graph if it doesn't exist // this will only add the first trace that is called (A cursor) // we need to incorporate logic that will add the second trace under the right conditions DoWindow/F $wwname if (V_Flag == 0) Display/W=(505,42,1068,414)/K=2/N=$wvname $ywave vs $xwave as wvname ControlBar 50 SetVariable msg,pos={12,10},size={120,17},title="A Wavelength " SetVariable msg,limits={-Inf,Inf,1},value= root:Packages:InspectData:gMessagek SetVariable msg5,pos={142,10},size={120,17},fcolor=(65535,0,0),title="B Wavelength " SetVariable msg5,limits={-Inf,Inf,1},value= gMessagekB SetVariable msg2,pos={280,10},size={230,17},title="Image " SetVariable msg2,limits={-Inf,Inf,1},value= root:Packages:InspectData:gMessageki SetVariable msg3,pos={12,30},size={250,17},title="X Scaling " SetVariable msg3,limits={-Inf,Inf,1},value= root:Packages:InspectData:gMessageXSck SetVariable msg4,pos={280,30},size={230,17},title="Y Scaling " SetVariable msg4,limits={-Inf,Inf,1},value= root:Packages:InspectData:gMessageYSck ModifyGraph/Z rgb[0] = (0,0,0) ModifyGraph/Z rgb[1] = (65535,0,0) ModifyGraph/Z zero(left)=1 else grState = TraceNameList("",":",1) // first ask if both traces are already on the graph // then we do nothing if(CmpStr(grState, "kineticsA:kineticsB:")== 0) return 0 // next ask if the wave on which we are running this function already exists on the graph elseif(CmpStr(grState, ywave + ":") == 0) return 0 // if not, append to graph else Print xwave AppendToGraph $ywave vs $xwave endif endif // SetWindow kwTopWin,hook(MyHook)=MyWindowHook //hook=SimpleInfoHook,hookevents=3 SetWindow $wwname,hook(MyHook)=MyWindowHook //hook=SimpleInfoHook,hookevents=3 // SetWindow kwTopWin,hook=MyWindowHook DoUpdate End Function InspectGraphS(ywave, xwave, wvname) String ywave, xwave, wvname //String wwname = wvname + "0" // IP7 missing "Packages" by default String wwname = wvname if(DataFolderExists("root:Packages") == 0) NewDataFolder/O root:Packages endif // make sure proper folder exists for global variables // do not switch to this folder if(DataFolderExists("root:Packages:InspectData") == 0) NewDataFolder/O root:Packages:InspectData endif SVAR gMessages = root:Packages:InspectData:gMessages SVAR gMessagesi = root:Packages:InspectData:gMessagesi SVAR gMessageXScs = root:Packages:InspectData:gMessageXScs SVAR gMessageYScs = root:Packages:InspectData:gMessageYScs String grState // create new graph if it doesn't exist DoWindow/F $wwname if (V_Flag == 0) Display/W=(505,442,1068,814)/K=2/N=$wvname $ywave vs $xwave as wvname ControlBar 50 SetVariable msg,pos={12,10},size={120,17},title="A Time " SetVariable msg,limits={-Inf,Inf,1},value= root:Packages:InspectData:gMessages SetVariable msg5,pos={142,10},size={120,17},fcolor=(65535,0,0),title="B Time " SetVariable msg5,limits={-Inf,Inf,1},value= root:Packages:InspectData:gMessagesB SetVariable msg2,pos={280,10},size={230,17},title="Image " SetVariable msg2,limits={-Inf,Inf,1},value= root:Packages:InspectData:gMessagesi SetVariable msg3,pos={12,30},size={250,17},title="X Scaling " SetVariable msg3,limits={-Inf,Inf,1},value= root:Packages:InspectData:gMessageXScs SetVariable msg4,pos={280,30},size={230,17},title="Y Scaling " SetVariable msg4,limits={-Inf,Inf,1},value= root:Packages:InspectData:gMessageYScs ModifyGraph/Z rgb[0] = (0,0,0) ModifyGraph/Z rgb[1] = (65535,0,0) ModifyGraph/Z zero(left)=1 else grState = TraceNameList("",":",1) if(CmpStr(grState, "spectraA:spectraB:")== 0) return 0 elseif(CmpStr(grState, ywave + ":") == 0) return 0 else AppendToGraph $ywave vs $xwave endif endif SetWindow $wwname,hook(MyHook)=MyWindowHook DoUpdate End // begin Window Hook implementation // testing phase Function MyWindowHook(s) STRUCT WMWinHookStruct &s Variable hookResult = 0 // Wave wk = kinetics // Wave ws = spectra Wave wk = kineticsA Wave ws = spectraA Wave wkB = kineticsB Wave wsB = spectraB // do this when procedure is called String ImTest = ImageInfo("","",0) // make this only applicable to images if(cmpstr(Imtest,"",0) == 0) //Print "Not an image." return 0 else String info= ImageInfo("","",0) String zmatName = StringByKey("ZWAVE",info) String xwName = StringByKey("XWAVE",info) String ywName = StringByKey("YWAVE",info) //String Zregex = "(.*?)(zmat|zibg|zroi|zccm|A.sv)" Wave kM = $zmatName endif // initalize variables for case 0, image window get activated String grtitle String base, xybase String suffix, xysuffix String regex = "(.*?)(zmat|zibg|zroi|zccm|A.sv)" SplitString /E=(regex) ZMatName, base, suffix String XYregex = "(.*?)(ximr|xim|xcim)" SplitString /E=(XYregex) xwName, xybase, xysuffix String tWave, sWave if(CmpStr(xysuffix,"")==0) tWave = "EmptyTimeWave" sWave = "EmptyLamWave" elseif(CmpStr(xysuffix,"ximr")==0) tWave = xybase + "yroi" sWave = xybase + "xroi" elseif(CmpStr(xysuffix,"xcim")==0) tWave = xybase + "ycc" sWave = xybase + "xcc" elseif(CmpStr(xysuffix,"xim")==0) tWave = xybase + "yc" sWave = xybase + "xc" endif Variable colsize, rowsize, xpos, ypos, lambda, stime Variable xposB, lambdaB Variable yposB, stimeB Variable bExists // add global variable references for the PreserveGraphScaling function PreserveGraphScaling("kinetics","k") PreserveGraphScaling("spectra","s") // what is happening here? // are we resetting the values somehow??? NVAR gvaslk = root:Packages:InspectData:gvaslk NVAR gvasbk = root:Packages:InspectData:gvasbk NVAR gvlmink = root:Packages:InspectData:gvlmink NVAR gvlmaxk = root:Packages:InspectData:gvlmaxk NVAR gvbmink = root:Packages:InspectData:gvbmink NVAR gvbmaxk = root:Packages:InspectData:gvbmaxk //PreserveGraphScaling("spectra0","s") // add global variable references for the PreserveGraphScaling function NVAR gvasls = root:Packages:InspectData:gvasls NVAR gvasbs = root:Packages:InspectData:gvasbs NVAR gvlmins = root:Packages:InspectData:gvlmins NVAR gvlmaxs = root:Packages:InspectData:gvlmaxs NVAR gvbmins = root:Packages:InspectData:gvbmins NVAR gvbmaxs = root:Packages:InspectData:gvbmaxs // global variables for graph messages SVAR gMessagek = root:Packages:InspectData:gMessagek SVAR gMessageki = root:Packages:InspectData:gMessageki SVAR gMessageXSck = root:Packages:InspectData:gMessageXSck SVAR gMessageYSck = root:Packages:InspectData:gMessageYSck SVAR gMessagekB = root:Packages:InspectData:gMessagekB SVAR gMessagesB = root:Packages:InspectData:gMessagesB NVAR gCursB = root:Packages:InspectData:gCursB SVAR gMessages = root:Packages:InspectData:gMessages SVAR gMessagesi = root:Packages:InspectData:gMessagesi SVAR gMessageXScs = root:Packages:InspectData:gMessageXScs SVAR gMessageYScs = root:Packages:InspectData:gMessageYScs // Print gvaslk switch(s.eventcode) // activate window case 0: //Print "case 0" //Print gvaslk //PreserveGraphScaling("kinetics0","k") PreserveGraphScaling("kinetics","k") // update for window hook calls on kinetics or spectra window // just updates control bar fields GetWindow kwTopWin, wtitle grTitle = S_Value // Print grTitle if(CmpStr(grTitle,"kinetics",0) == 0) PreserveGraphScaling("kinetics","k") if(gvaslk == 1) gMessageYSck = num2str(gvlmink) +", "+ num2str(gvlmaxk) else gMessageYSck = "Auto" endif if(gvasbk == 1) gMessageXSck = num2str(gvbmink) +", "+ num2str(gvbmaxk) else gMessageXSck = "Auto" endif hookresult = 1 break endif // do the same for the spectra graph GetWindow kwTopWin, wtitle grTitle = S_Value // Print grTitle if(CmpStr(grTitle,"spectra",0) == 0) PreserveGraphScaling("spectra","s") if(gvasls == 1) gMessageYScs = num2str(gvlmins) +", "+ num2str(gvlmaxs) else gMessageYScs = "Auto" endif if(gvasbs == 1) gMessageXScs = num2str(gvbmins) +", "+ num2str(gvbmaxs) else gMessageXScs = "Auto" endif hookresult = 1 break endif // may need to plot against new time wave if we have switched windows // update dimensions of the kinetics wave colsize = Dimsize(kM,1) // numer of columns rowsize = DimSize(kM,0) // number of rows Redimension/N=(colsize) kineticsA Redimension/N=(rowsize) spectraA // re-initialize graph //DoWindow kinetics0 DoWindow kinetics if (V_Flag == 0) return 0 else // RemoveFromGraph/W=kinetics0 kinetics // AppendToGraph/W=kinetics0 kinetics vs $tWave RemoveFromGraph/W=kinetics kineticsA AppendToGraph/W=kinetics kineticsA vs $tWave endif //DoWindow spectra0 DoWindow spectra if (V_Flag == 0) return 0 else // RemoveFromGraph/W=spectra0 spectra // AppendToGraph/W=spectra0 spectra vs $sWave RemoveFromGraph/W=spectra spectraA AppendToGraph/W=spectra spectraA vs $sWave endif xpos = pcsr(A) ypos = qcsr(A) lambda = hcsr(A) stime = vcsr(A) gMessagek = num2str(lambda) gMessageki = ZMatName gMessages = num2str(stime) gMessagesi = ZMatName //wk = kM[xpos] [p] MatrixOp/O wk = row(kM, xpos)^t //ws = kM[p] [ypos] MatrixOp/O ws = col(kM, ypos) // the cursor calls reset the graph scaling need to fix it here // include temp variable to reset axes back to default Variable gvaslktemp = gvaslk Variable gvasbktemp = gvasbk Variable gvaslstemp = gvasls Variable gvasbstemp = gvasbs Cursor/H=2/W=kinetics A kineticsA ypos Cursor/H=2/W=spectra A spectraA xpos gvaslk = gvaslktemp gvasbk = gvasbktemp gvasls = gvaslstemp gvasbs = gvasbstemp // this is repeated during image operations // also calls setaxis so state of graph is preseved if not autoscaled if(gvaslk == 1) //SetAxis/W=kinetics0 left, gvlmink, gvlmaxk SetAxis/W=kinetics left, gvlmink, gvlmaxk gMessageYSck = num2str(gvlmink) +", "+ num2str(gvlmaxk) else gMessageYSck = "Auto" endif if(gvasbk == 1) //SetAxis/W=kinetics0 bottom, gvbmink, gvbmaxk SetAxis/W=kinetics bottom, gvbmink, gvbmaxk gMessageXSck = num2str(gvbmink) +", "+ num2str(gvbmaxk) else gMessageXSck = "Auto" endif if(gvasls == 1) //SetAxis/W=spectra0 left, gvlmins, gvlmaxs SetAxis/W=spectra left, gvlmins, gvlmaxs gMessageYScs = num2str(gvlmins) +", "+ num2str(gvlmaxs) else gMessageYScs = "Auto" endif if(gvasbs == 1) //SetAxis/W=spectra0 bottom, gvbmins, gvbmaxs SetAxis/W=spectra bottom, gvbmins, gvbmaxs gMessageXScs = num2str(gvbmins) +", "+ num2str(gvbmaxs) else gMessageXScs = "Auto" endif // updates for cursor B bExists= strlen(CsrInfo(B)) > 0 if (bExists == 1) gCursB = 1 Redimension/N=(colsize) kineticsB Redimension/N=(rowsize) spectraB DoWindow kinetics if (V_Flag == 0) return 0 else RemoveFromGraph/Z/W=kinetics kineticsB AppendToGraph/W=kinetics kineticsB vs $tWave endif DoWindow spectra if (V_Flag == 0) return 0 else RemoveFromGraph/Z/W=spectra spectraB AppendToGraph/W=spectra spectraB vs $sWave endif // first data to display for kinetics xposB = pcsr(B) lambdaB = hcsr(B) gMessagekB= num2str(lambdaB) // first data to display for spectra yposB = qcsr(B) stimeB = vcsr(B) gMessagesB = num2str(stimeB) //wkB = kM[xposB] [p] MatrixOp/O wkB = row(kM, xposB)^t //wsB = kM[p][yposB] MatrixOp/O wsB = col(kM, yposB) Cursor/H=2/C=(65535,0,0)/W=kinetics B kineticsB yposB Cursor/H=2/C=(65535,0,0)/W=spectra B spectraB xposB else gCursB = 0 gMessagekB = "" gMessagesB = "" RemoveFromGraph/Z/W=kinetics kineticsB RemoveFromGraph/Z/W=spectra spectraB Cursor/K/W=kinetics B Cursor/K/W=spectra B endif ModifyGraph/Z/W=kinetics rgb[0] = (0,0,0) ModifyGraph/Z/W=kinetics rgb[1] = (65535,0,0) ModifyGraph/Z/W=spectra rgb[0] = (0,0,0) ModifyGraph/Z/W=spectra rgb[1] = (65535,0,0) hookresult = 1 break // implement cursor move part // current problem with cursor move - activate seems ok //null string variable on startup case 7: //Print "case 7" //Print "1: " + num2str(gvaslk) // mouse move // Print s.pointnumber // Print s.yPointNumber //PreserveGraphScaling("kinetics0","k") PreserveGraphScaling("kinetics","k") //PreserveGraphScaling("spectra0","s") PreserveGraphScaling("spectra","s") //Print "2: " + num2str(gvaslk) xpos = pcsr(A) ypos = qcsr(A) //wk = kM[xpos] [p] MatrixOP/O wk = row(kM,xpos)^t //ws = kM[p][ypos] MatrixOp/O ws = col(kM, ypos) lambda = hcsr(A) gMessagek = num2str(lambda) gMessageki = ZMatName stime = vcsr(A) gMessages = num2str(stime) gMessagesi = ZMatName Cursor/H=2/W=kinetics A kineticsA ypos Cursor/H=2/W=spectra A spectraA xpos if(gvaslk == 1) //SetAxis/W=kinetics0 left, gvlmink, gvlmaxk SetAxis/W=kinetics left, gvlmink, gvlmaxk endif if(gvasbk == 1) //SetAxis/W=kinetics0 bottom, gvbmink, gvbmaxk SetAxis/W=kinetics bottom, gvbmink, gvbmaxk endif if(gvasls == 1) //SetAxis/W=spectra0 left, gvlmins, gvlmaxs SetAxis/W=spectra left, gvlmins, gvlmaxs endif if(gvasbs == 1) //SetAxis/W=spectra0 bottom, gvbmins, gvbmaxs SetAxis/W=spectra bottom, gvbmins, gvbmaxs endif // updates for cursor B // Variable xposB, lambdaB // Variable yposB, stimeB bExists= strlen(CsrInfo(B)) > 0 if (bExists == 1) gCursB = 1 // first data to display for kinetics xposB = pcsr(B) lambdaB = hcsr(B) gMessagekB= num2str(lambdaB) // first data to display for spectra yposB = qcsr(B) stimeB = vcsr(B) gMessagesB = num2str(stimeB) //wkB = kM[xposB] [p] MatrixOp/O wkB = row(kM, xposB)^t //wsB = kM[p][yposB] MatrixOp/O wsB = col(kM, yposB) CheckDisplayed/W=kinetics kineticsB if(V_flag == 1) Cursor/H=2/C=(65535,0,0)/W=kinetics B kineticsB yposB // return 0 else AppendToGraph/W=kinetics kineticsB vs $tWave endif CheckDisplayed/W=spectra spectraB if(V_flag == 1) Cursor/H=2/C=(65535,0,0)/W=spectra B spectraB xposB // return 0 else AppendToGraph/W=spectra spectraB vs $sWave endif else gCursB = 0 gMessagekB = "" gMessagesB = "" RemoveFromGraph/Z/W=kinetics kineticsB RemoveFromGraph/Z/W=spectra spectraB Cursor/K/W=kinetics B Cursor/K/W=spectra B endif //Print "4: " + num2str(gvaslk) hookresult = 1 break case 8: //Print "case 8" //Print gvaslk // update if we rescale the kinetics graph GetWindow kwTopWin, wtitle grTitle = S_Value if(CmpStr(grTitle,"kinetics",0) == 0) //Print "modified kinetics running" // PreserveGraphScaling("kinetics0","k") PreserveGraphScaling("kinetics","k") if(gvaslk == 1) gMessageYSck = num2str(gvlmink) +", "+ num2str(gvlmaxk) else gMessageYSck = "Auto" endif if(gvasbk == 1) gMessageXSck = num2str(gvbmink) +", "+ num2str(gvbmaxk) else gMessageXSck = "Auto" endif hookresult = 1 break endif if(CmpStr(grTitle,"spectra",0) == 0) //PreserveGraphScaling("spectra0","s") PreserveGraphScaling("spectra","s") if(gvasls == 1) gMessageYScs = num2str(gvlmins) +", "+ num2str(gvlmaxs) else gMessageYScs = "Auto" endif if(gvasbs == 1) gMessageXScs = num2str(gvbmins) +", "+ num2str(gvbmaxs) else gMessageXScs = "Auto" endif hookresult = 1 break endif endswitch return hookResult End // After a Window Hook call, graph axis limits automatically reset // We want to preserve the axis range as the window is activated // But, we want to preserve autoscaling so that things are easy when // we switch images. Use this function in combination with SetScale Function PreserveGraphScaling(graphname, suffix) // be careful that suffix is less than 25 or so characters String graphname String suffix DoWindow $graphname if (V_Flag == 0) //Print "Window doesn't exist" return 0 else // create folder to store global variables which will be accessed // by our window hook functions DFREF saveDFR = GetDataFolderDFR() if(DataFolderExists("root:Packages:InspectData") == 1) SetDataFolder("root:Packages:InspectData") else NewDataFolder/O/S root:Packages:InspectData endif // create global variables for manual or auto // default is autoscale // left axis String vaslname = ":gvasl" + suffix Variable vasl = NumVarOrDefault(vaslname, 0) Variable/G $vaslname = vasl NVAR gvasl = $vaslname // bottom axis String vasbname = ":gvasb" + suffix Variable vasb = NumVarOrDefault(vasbname, 0) Variable/G $vasbname = vasb NVAR gvasb = $vasbname // create global variables for axis limits // left axis String vlminname = ":gvlmin" + suffix Variable vlmin = NumVarOrDefault(vlminname, -1) Variable/G $vlminname = vlmin NVAR gvlmin = $vlminname String vlmaxname = ":gvlmax" + suffix Variable vlmax = NumVarOrDefault(vlmaxname, 1) Variable/G $vlmaxname = vlmax NVAR gvlmax = $vlmaxname // bottom axis String vbminname = ":gvbmin" + suffix Variable vbmin = NumVarOrDefault(vbminname, -1) Variable/G $vbminname = vbmin NVAR gvbmin = $vbminname String vbmaxname = ":gvbmax" + suffix Variable vbmax = NumVarOrDefault(vbmaxname, 1) Variable/G $vbmaxname = vbmax NVAR gvbmax = $vbmaxname //NVAR gvaslk //Print gvaslk // test for autoscaling // variables created 1 for manual, 0 for auto String asl = StringByKey("SETAXISFLAGS", AxisInfo(graphname,"left")) // Print asl if(CmpStr(asl,"",0) == 0) // Print "left manual" gvasl = 1 else // Print "left auto" gvasl = 0 endif String asb = StringByKey("SETAXISFLAGS", AxisInfo(graphname,"bottom")) // Print asb if(CmpStr(asb,"",0) == 0) // Print "bottom manual" gvasb = 1 else // Print "bottom auto" gvasb = 0 endif // store min and max values if set to manual if(gvasl == 1) GetAxis/Q/W=$graphname left gvlmin = V_min // Print V_min // Print gvlmin gvlmax = V_max // Print V_max // Print gvlmax endif if(gvasb == 1) GetAxis/Q/W=$graphname bottom gvbmin = V_min // Print V_min // Print gvbmin gvbmax = V_max // Print V_max // Print gvbmax endif // return to default folder SetDataFolder saveDFR //Print gvaslk endif End ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// Function ExtractKin() // WAVE/Z w = CsrWaveRef(A) // if (!WaveExists(w)) // return NaN // endif // String zmatName = NameOfWave(w) String ImTest = ImageInfo("","",0) // make this only applicable to images if(cmpstr(Imtest,"",0) == 0) Print "Not an image." return 0 else NVAR gCursB = root:Packages:InspectData:gCursB String info= ImageInfo("","",0) String zmatName = StringByKey("ZWAVE",info) String xwName = StringByKey("XWAVE",info) String ywName = StringByKey("YWAVE",info) String base, xybase String suffix, xysuffix String regex = "(.*?)(zmat|zibg|zroi|zccm|A.sv)" SplitString /E=(regex) zmatName, base, suffix String XYregex = "(.*?)(ximr|xim|xcim)" SplitString /E=(XYregex) xwName, xybase, xysuffix //String tWave, sWave if(CmpStr(xysuffix,"")==0) xwName = "NewXwave" ywName = "NewYWave" elseif(CmpStr(xysuffix,"ximr")==0) ywName = xybase + "yroi" xwName = xybase + "xroi" elseif(CmpStr(xysuffix,"xcim")==0) ywName = xybase + "ycc" xwName = xybase + "xcc" elseif(CmpStr(xysuffix,"xim")==0) ywName = xybase + "yc" xwName = xybase + "xc" endif Variable xpos, lambda, CursName Variable xposB, lambdaB xpos = pcsr(A) lambda = hcsr(A) if(gCursB == 1) xposB = pcsr(B) lambdaB = hcsr(B) endif Prompt CursName, "Cursor used to generate plot:", popup, "Cursor A;Cursor B;ROI Cursor A/B" Prompt zmatName, "Enter matrix wave name: " // Prompt zmatName, "Enter matrix wave name: ", popup, StringByKey("ZWAVE",ImageInfo("","",0)) Prompt xpos, "Enter cursor A postion for desired wavelength: " Prompt xposB, "Enter cursor B postion for desired wavelength: " Prompt xwName, "Enter wavelength wave name: " if(gCursB == 1) DoPrompt "Generate Kinetics", CursName, zmatName, xpos, xposB, xwName else DoPrompt "Generate Kinetics", zmatName, xpos, xwName CursName = 1 endif if (V_Flag) return -1 endif if(CursName == 1) Print "A" Plot1DFromMat2(zmatName, xpos, xpos, xwName, ywName, 0) elseif(CursName == 2) Print "B" Plot1DFromMat2(zmatName, xposB, xposB, xwName, ywName, 0) elseif(CursName == 3) Print "A/B" Plot1DFromMat2(zmatName, xpos, xposB, xwName, ywName, 0) endif // Print zmatName; Print xwName // Variable tName = NumberByKey("RECREATION",CsrInfo(A)) // KineticsPlot2(zmatName,xpos,xwName) return 0 endif End Function ExtractSpec() // WAVE/Z w = CsrWaveRef(A) // if (!WaveExists(w)) // return NaN // endif // String zmatName = NameOfWave(w) String ImTest = ImageInfo("","",0) // make this only applicable to images if(cmpstr(Imtest,"",0) == 0) Print "Not an image." return 0 else NVAR gCursB = root:Packages:InspectData:gCursB String info= ImageInfo("","",0) String zmatName = StringByKey("ZWAVE",info) String xwName = StringByKey("XWAVE",info) String ywName = StringByKey("YWAVE",info) String base, xybase String suffix, xysuffix String regex = "(.*?)(zmat|zibg|zroi|zccm|A.sv)" SplitString /E=(regex) zmatName, base, suffix String XYregex = "(.*?)(ximr|xim|xcim)" SplitString /E=(XYregex) xwName, xybase, xysuffix //String tWave, sWave if(CmpStr(xysuffix,"")==0) xwName = "NewXwave" ywName = "NewYWave" elseif(CmpStr(xysuffix,"ximr")==0) ywName = xybase + "yroi" xwName = xybase + "xroi" elseif(CmpStr(xysuffix,"xcim")==0) ywName = xybase + "ycc" xwName = xybase + "xcc" elseif(CmpStr(xysuffix,"xim")==0) ywName = xybase + "yc" xwName = xybase + "xc" endif Variable ypos, stime, CursName Variable yposB, stimeB ypos = qcsr(A) stime = vcsr(A) if(gCursB == 1) yposB = qcsr(B) stimeB = vcsr(B) endif Prompt CursName, "Cursor used to generate plot:", popup, "Cursor A;Cursor B;ROI Cursor A/B" Prompt zmatName, "Enter matrix wave name: " Prompt ypos, "Enter cursor A postion for desired time: " Prompt yposB, "Enter cursor B postion for desired time: " Prompt ywName, "Enter time wave name: " if(gCursB == 1) DoPrompt "Generate Spectra", CursName, zmatName, ypos, yposB, ywName else DoPrompt "Generate Spectra", zmatName, ypos, ywName CursName = 1 endif if (V_Flag) return -1 endif if(CursName == 1) Print "A" Plot1DFromMat2(zmatName, ypos, ypos, xwName, ywName, 1) elseif(CursName == 2) Print "B" Plot1DFromMat2(zmatName, yposB, yposB, xwName, ywName, 1) elseif(CursName == 3) Print "A/B" Plot1DFromMat2(zmatName, ypos, yposB, xwName, ywName, 1) endif // Print zmatName; Print ywName // SpectraPlot2(zmatName,ypos,ywName) return 0 endif End Function/S Plot1DFromMat2(Mat, ACurs, BCurs, sWave, twave, mode) // this function will average 1D slices over a range given by the 2 cursor positions // for extraction at a single pixel, make sure that ACurs = B Curs // mode should be set to 0 for vertical image slice (kinetics) // mode should be set to 1 for horizontal slice (spectra) // written to behave like KineticsPlot2 (found in v. 4alpha3) String Mat, sWave, twave Variable ACurs, BCurs, mode Wave ksM = $Mat Variable m,n m = Dimsize(ksM,0) // numer of rows n = Dimsize(ksM,1) // number of columns // get base name to append to // also define name of time wave to plot against String base String suffix // First write for kinetics plot String kWaveName, sWaveName // Name for common plot String kWinName, sWinName String dfSave String regex = "(.*?)(zmat|zibg|zroi|zccm|A.sv)" SplitString /E=(regex) Mat, base, suffix if(CmpStr(base,"")==0) kWaveName = "NewMatrix" // plot all extracted kinetics on the same graph // define window name to be base + kp kWinName = "Empty K Name" sWinName = "Empty S Plot" else // plot all extracted kinetics on the same graph // define window name to be base + kp kWinName = base + "kp" sWinName = base + "sp" endif // make sure it is not more than 31 chars if(mode == 0) // kinetics Wave ltM = $sWave elseif(mode == 1) // spectra Wave ltM = $tWave endif Variable DAB = abs(ACurs - BCurs) String IName Variable IA = ltM[ACurs] Variable lB = ltM[BCurs] Variable lAB = abs(IA - lB) Variable minpix, maxpix if(ACurs <= BCurs) // Print "Less than or equal" minpix = ACurs maxpix = BCurs // IName = num2Str(IA + ((IA - lB)/2)) if(mode == 0) sprintf IName, "%3.0f", (IA + (lAB/2)) else sprintf IName, "%1.3f", (IA + (lAB/2)) endif else // Print "GT!" minpix = BCurs maxpix = ACurs // IName = num2Str(lB + ((lB - IA)/2)) if(mode == 0) sprintf IName, "%3.0f", (lB + (lAB/2)) else sprintf IName, "%1.3f", (lB + (lAB/2)) endif endif kWaveName = base + "k" + IName + "_" + num2iStr(DAB) sWaveName = base + "s" + IName + "_" + num2iStr(DAB) kWaveName = CleanupName(kWaveName, 1) sWaveName = CleanupName(sWaveName, 1) ColorTab2Wave blueredgreen Wave CT = M_colors Variable colorind, nwav Variable i = 0 Variable j = 0 if(mode == 0) Make/D/O/N=(n) $kWaveName Wave w = $kWaveName w = 0 // use built-in indexing capabilities to // extract a row // I find this implementation to be partuclarly confusing do w += ksM[minpix+i] [p] i+=1 while(minpix+i <= maxpix) w /= i // show all extracted traces on the same graph // create new graph if it doesn't exist DoWindow/F $kWinName if (V_Flag == 0) Display/K=0/N=$kWinName w vs $tWave ModifyGraph rgb=(CT[0][0],CT[0][1],CT[0][2]) else GetWindow/Z $kWinName, wavelist nwav = Dimsize(W_wavelist,0) colorind = colorindreturn(nwav) //Print colorind AppendToGraph/C=(CT[colorind][0],CT[colorind][1],CT[colorind][2])/W=$kWinName w vs $tWave endif // DoUpdate elseif(mode == 1) Make/D/O/N=(m) $sWaveName Wave v = $sWaveName v = 0 do v += ksM[p][minpix+j] j+=1 while(minpix+j <= maxpix) v /= j // show all extracted traces on the same graph // create new graph if it doesn't exist DoWindow/F $sWinName if (V_Flag == 0) Display/K=0/N=$sWinName v vs $sWave ModifyGraph rgb=(CT[0][0],CT[0][1],CT[0][2]) else GetWindow/Z $sWinName, wavelist nwav = Dimsize(W_wavelist,0) colorind = colorindreturn(nwav) AppendToGraph/C=(CT[colorind][0],CT[colorind][1],CT[colorind][2])/W=$sWinName v vs $sWave endif else // just fail if mode set to anything else return "" endif KillWaves/Z M_colors KillWaves/Z W_WaveList if(mode == 0) return kWaveName elseif(mode == 1) return sWaveName endif End ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// // Subtract scattered light procedures (laser + fluorescence) // This is not used for other background subtraction // This is the display recreation macro, created by Igor // and then manually tweaked. The parts that were tweaked // are shown in bold. NOTE: Some lines are wrapped to fit on the page. Window IntBackControlPanel() : Panel PauseUpdate; Silent 1 // building window... NewPanel/W=(150,100,600,320)/K=1 as "Get Cursor Positions" SetDrawEnv fsize= 16 DrawText 109,28,"Scattered Light Correction" SetVariable XSetVar,pos={40,45},size={150,15},title="Cursor A:" SetVariable XSetVar,limits={0,Inf,1},value=root:Packages:IntensityBackground:cAComponent SetVariable YSetVar,pos={210,45},size={150,15},title="Cursor B:" SetVariable YSetVar,limits={0,Inf,1},value=root:Packages:IntensityBackground:cBComponent Button ComputeButton,pos={110,76},size={90,20}, proc=GetCursorPositions,title="Preview" Button ComputeButton2,pos={227,76},size={90,20}, proc=GetCursorPositions2,title="Save" SetVariable setvar0 title="matrix:",size={284,15},bodyWidth=250, pos={77,115}, value=root:Packages:IntensityBackground:zWave SetVariable setvar0_1 title="sca_bkgd:",size={298,15},bodyWidth=250, pos={63,142}, value=root:Packages:IntensityBackground:scaWave SetVariable setvar0_2 title="corrected:",size={299,15},bodyWidth=250, pos={62,171}, value=root:Packages:IntensityBackground:corrWave // embed graph // String IntBackPlot // Display/host=# /W=(50,200,400,350) as IntBackPlot End // This is the action procedure for the Compute button. // We created it using the Button dialog. Function GetCursorPositions(ctrlName) : ButtonControl String ctrlName // Make sure both cursors are on the same wave. WAVE wA = CsrWaveRef(A) WAVE wB = CsrWaveRef(B) String dfA = GetWavesDataFolder(wA, 2) String dfB = GetWavesDataFolder(wB, 2) if (CmpStr(dfA, dfB) != 0) Abort "Both cursors must be on the same wave." return -1 endif String info= ImageInfo("","",0) String zmatName = StringByKey("ZWAVE",info) Print zmatName // Wave wZ = $zmatName Variable n = Dimsize($zmatName,0) // number of columns String dfSave = GetDataFolder(1) // SetDataFolder root:Packages:IntensityBackground SVAR zWave = root:Packages:IntensityBackground:zWave zWave = zmatName NVAR cAComponent = root:Packages:IntensityBackground:cAComponent NVAR cBComponent = root:Packages:IntensityBackground:cBComponent cAComponent = qcsr(A) Printf "Cursor A=%g\r", cAComponent Variable imin = cAComponent cBComponent = qcsr(B) Printf "Cursor B=%g\r", cBComponent Variable imax = cBComponent // SetDataFolder dfSave //restore original location // Print imin // Print imax // Print n PreviewSLC(zmatName, imin, imax) End Function GetCursorPositions2(ctrlName) : ButtonControl String ctrlName DoWindow/K tempGraph // Make sure both cursors are on the same wave. WAVE wA = CsrWaveRef(A) WAVE wB = CsrWaveRef(B) String dfA = GetWavesDataFolder(wA, 2) String dfB = GetWavesDataFolder(wB, 2) if (CmpStr(dfA, dfB) != 0) Abort "Both cursors must be on the same wave." return -1 endif String info= ImageInfo("","",0) String zmatName = StringByKey("ZWAVE",info) Print zmatName Wave wZ = $zmatName Variable n = Dimsize(wZ,0) // number of columns String dfSave = GetDataFolder(1) // SetDataFolder root:Packages:IntensityBackground SVAR zWave = root:Packages:IntensityBackground:zWave zWave = zmatName NVAR cAComponent = root:Packages:IntensityBackground:cAComponent NVAR cBComponent = root:Packages:IntensityBackground:cBComponent// Access current data folder. cAComponent = qcsr(A) Printf "Cursor A=%g\r", cAComponent Variable imin = cAComponent cBComponent = qcsr(B) Printf "Cursor B=%g\r", cBComponent Variable imax = cBComponent // SetDataFolder dfSave //restore original location // Print imin // Print imax // Print n ApplySLC(zmatName, imin, imax) End Function PreviewSLC(zMat, tmin, tmax) String zMat Variable tmin, tmax Wave fM = $zMat String scaBName = RemoveEnding(zMat, "zmat") + "scab" Variable minSig, maxSig if(tmin <= tmax) minSig = tmin maxSig = tmax elseif(tmin > tmax) minSig = tmax maxSig = tmin endif Variable m,n m = Dimsize(fM,0) // numer of rows n = Dimsize(fM,1) // number of columns String dfSave = GetDataFolder(1) SetDataFolder root:Packages:IntensityBackground // Make/O/N=(m) dummyS1 Make/O/N=(m) dummyS_avg Display/N=tempGraph Variable i,j i=0 do String dumstr = "dummyS_" + num2str(i) Make/O/N=(m) $dumstr Wave dS = $dumstr j=0 do dS[j] = fM[j][i+minSig] j+=1 while (j<=m) i+=1 dummyS_avg += dS AppendToGraph $dumstr while (i+minSig <= maxSig) dummyS_avg /= i SVAR scaWave = root:Packages:IntensityBackground:scaWave scaWave = scaBName Duplicate/O dummyS_avg, $scaBName KillWaves dummyS_avg SetDataFolder dfSave //restore original location return 0 end Function ApplySLC(zMat, tmin, tmax) String zMat Variable tmin, tmax String scaBName = RemoveEnding(zMat, "zmat") + "scab" String zcorName = RemoveEnding(zMat, "zmat") + "zibg" String ImageXName = RemoveEnding(zMat, "zmat") + "xim" String ImageYName = RemoveEnding(zMat, "zmat") + "yim" Wave fM = $zMat Duplicate/O $zMat, root:Packages:IntensityBackground:zMatTemp Variable minSig, maxSig if(tmin <= tmax) minSig = tmin maxSig = tmax elseif(tmin > tmax) minSig = tmax maxSig = tmin endif Variable m,n m = Dimsize(fM,0) // numer of rows n = Dimsize(fM,1) // number of columns Make/O/N=(m) dummyS1 Make/O/N=(m) dummyS_avg String dfSave = GetDataFolder(1) SetDataFolder root:Packages:IntensityBackground Variable i,j i=0 do j=0 do dummyS1[j] = fM[j][i+minSig] j+=1 while (j<=m) i+=1 dummyS_avg += dummyS1 while (i+minSig <= maxSig) dummyS_avg /= i SVAR scaWave = root:Packages:IntensityBackground:scaWave scaWave = scaBName KillWaves dummyS1 Duplicate/O dummyS_avg, $scaBName Duplicate/O dummyS_avg, root:$scaBName Wave wcorr = zMatTemp Variable k,l k=0 do l=0 do wcorr[l][k] = -log(10^(-(fM[l][k])) - 10^(-(dummyS_avg[l])) +1) // wcorr[k][l] = -log(10^(-(fM[k][l]))) // wcorr[k][l] = fM[k][l] l+=1 while (l<=m) k+=1 while(k xlength - 2) xroimin = xlength -2 endif if (xroimax > xlength - 1) xroimax = xlength -1 endif if (yroimin > ylength - 2) yroimin = ylength -2 endif if (yroimax > ylength - 1) yroimax = ylength -1 endif Variable irange, jrange, imax, imin irange = abs(xroimax-xroimin) jrange = abs(yroimax-yroimin) String ZMatROI = base + "zroi" // for 1D plotting String XROI = base + "xroi" // for image visualization String XIMR = base + "ximr" // for 1D plotting String YROI = base + "yroi" // for image visualization String YIMR = base + "yimr" Make/O/N=(irange,jrange) $ZMatROI Make/O/N=(irange) $XROI Make/O/N=(jrange) $YROI // image needs N+1 points Make/O/N=(irange+1) $XIMR Make/O/N=(jrange+1) $YIMR Wave ZROI = $ZMatROI Wave XR = $XROI Wave XRIm = $XIMR Wave YR = $YROI Wave YRIm = $YIMR // do 2 extractions, 1 for 1D plots (N), 1 for image plots (N+1) Variable i,j i=0 do j = 0 do ZROI[j][i] = wZ[j+xroimin][i+yroimin] XR[j] = Xw[j+xroimin] XRIm[j] = XwIm[j+xroimin] j += 1 while (j+xroimin <= xroimax) YR[i] = Yw[i+yroimin] YRIm[i] = YwIm[i+yroimin] i+=1 while (i+yroimin <= yroimax) // fill in N+1 points for image labels XRIm[irange] = XwIm[1+xroimax] YRIm[jrange] = YwIm[1+yroimax] Display;AppendImage $ZMatROI vs {$XIMR,$YIMR}//;DelayUpdate ModifyImage $ZMatROI ctab= {*,*,Rainbow,0} ModifyImage $ZMatROI ctabAutoscale=3,lookup= $"" ShowInfo GetWindow kwTopWin wtitle String imTitle = S_Value String imTitle2 = WinName(0,1) imTitle = RemoveEnding(imTitle, ":") Cursor/I/H=1 /W=$imTitle A $ZMatROI 1,1 Cursor/M/H=1 B // ImageHookGen() SetWindow $imTitle2, hook(MyHook)=MyWindowHook DoWindow/F $imTitle2 endif return 0 End //////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////// Function AutoSVG() String ImTest = ImageInfo("","",0) // make this only applicable to images if(cmpstr(Imtest,"",0) == 0) Print "Not an image." return 0 else String info= ImageInfo("","",0) String zmatName = StringByKey("ZWAVE",info) String xwName, ywName, ximName, yimName String UmatName, VmatName, SwName String base String suffix String regex = "(.*?)(zmat|zibg|zroi|zccm|A.sv)" SplitString /E=(regex) zmatName, base, suffix if(CmpStr(zmatName,"")==0) Print "Failed to get matrix name." return 0 else xwName = base + "xc" ywName = base + "yc" ximName = base + "xim" yimName = base + "yim" UmatName = base + "psU" VmatName = base + "pkV" SwName = base + "svW" endif MatrixSVD $zmatName MatrixTranspose M_VT Duplicate/O M_U $UmatName Duplicate/O W_W $SwName Duplicate/O M_VT $VmatName KillWaves/Z M_U KillWaves/Z W_W KillWaves/Z M_VT Display $SwName ModifyGraph log(left)=1 ModifyGraph mode=3,marker=16 SetAxis bottom 0,10 endif End //////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////// Function RankSVD() Variable rank = 1 Variable scale = 2 String UmatName, VmatName, SwName, zmatName String ImTest = ImageInfo("","",0) if(cmpstr(Imtest,"",0) == 0) Prompt UmatName, "Enter U matrix wave name: ", popup, Wavelist("*_psU",";","") Prompt VmatName, "Enter V matrix wave name:", popup, Wavelist("*_pkV",";","") Prompt SwName, "Enter singular value wave name:", popup, Wavelist("*_svW",";","") Prompt zmatName, "Enter original matrix wave name:", popup, Wavelist("*_z*",";","") else String info= ImageInfo("","",0) zmatName = StringByKey("ZWAVE",info) String xwName, ywName, ximName, yimName String ImName String base String suffix String regex = "(.*?)(zmat|zibg|zroi|zccm|A.sv)" SplitString /E=(regex) zmatName, base, suffix if(CmpStr(zmatName,"")==0) Print "Failed to get matrix name." return 0 elseif(CmpStr(suffix,"zmat")==0 || CmpStr(suffix,"zibg")==0) ImName = WinName(0,1) xwName = base + "xc" ywName = base + "yc" ximName = base + "xim" yimName = base + "yim" UmatName = base + "psU" VmatName = base + "pkV" SwName = base + "svW" elseif(CmpStr(suffix,"zroi")==0) ImName = WinName(0,1) xwName = base + "xroi" ywName = base + "yroi" ximName = base + "ximr" yimName = base + "yimr" UmatName = base + "psU" VmatName = base + "pkV" SwName = base + "svW" endif if (exists(UmatName) == 1 && exists(VmatName) == 1 && exists(SwName) == 1) Prompt UmatName, "Enter U matrix wave name: " Prompt VmatName, "Enter V matrix wave name:" Prompt SwName, "Enter singular value wave name:" Prompt zmatName, "Enter original matrix wave name:", popup, Wavelist("*",";","") else Prompt UmatName, "Enter U matrix wave name: ", popup, Wavelist("*",";","") Prompt VmatName, "Enter V matrix wave name: ", popup, Wavelist("*",";","") Prompt SwName, "Enter singular value wave name:", popup, Wavelist("*",";","") Prompt zmatName, "Enter original matrix wave name:", popup, Wavelist("*",";","") endif endif Prompt rank, "Number of species in data:" Prompt scale, "Scale by singular value?",popup, "yes;no" DoPrompt "Rank SVD Matrices", UmatName, VmatName, rank, scale, SwName if (V_flag == 1) // User hit cancel button, so do nothing. return 0 endif Wave ZM = $zmatName Wave MU = $UmatName Make/D/O/N=(DimSize(MU,0),rank) MURtemp Wave MV = $VmatName Make/D/O/N=(DimSize(MV,0),rank) MVRtemp Wave SV = $SwName Make/D/O/N=(rank) SVtemp Make/D/O/N=(DimSize(MU,0),DimSize(MV,0)) ARtemp String TempPSName, TempPKName // kill any previously extracted vectors // this does not delete waves that are in use // add code to kill windows first Variable bb = 0 do TempPSName = base + "ps" + num2str(bb+1) TempPKName = base + "pk" + num2str(bb+1) KillWaves/Z $TempPSName KillWaves/Z $TempPKName bb+= 1 while (bb < dimsize(MU,0)) // need to test to see if these exist // otherwise, windows are created at point 0,0,0,0 // not fixed by boolean below NVAR/Z V_left = root:V_left, V_right = root:V_right NVAR/Z V_top = root:V_top, V_bottom = root:V_bottom if (!NVAR_Exists(V_left)) Variable/G V_left = 0 endif if (!NVAR_Exists(V_right)) Variable/G V_right = 0 endif if (!NVAR_Exists(V_top)) Variable/G V_top = 0 endif if (!NVAR_Exists(V_bottom)) Variable/G V_bottom = 0 endif String cmdU0, cmdU1, cmdU2 String Uwindowname = base + "PS" sprintf cmdU0, "GetWindow/Z %s, wsize", Uwindowname Execute/Q cmdU0 // Print V_left, V_top, V_right, V_bottom sprintf cmdU1, "DoWindow/K %s", Uwindowname Execute/Q cmdU1 if ((V_left + V_top + V_right + V_bottom) == 0) sprintf cmdU2, "Display/N=%s", Uwindowname else sprintf cmdU2, "Display/N=%s/W=(%d,%d,%d,%d)", Uwindowname, V_left, V_top, V_right, V_bottom endif Execute/Q cmdU2 Legend String Vwindowname = base + "PK" String cmdV0, cmdV1, cmdV2 sprintf cmdV0, "GetWindow/Z %s, wsize", Vwindowname Execute/Q cmdV0 // Print V_left, V_top, V_right, V_bottom sprintf cmdV1, "DoWindow/K %s", Vwindowname Execute/Q cmdV1 if ((V_left + V_top + V_right + V_bottom) == 0) sprintf cmdV2, "Display/N=%s", Vwindowname else sprintf cmdV2, "Display/N=%s/W=(%d,%d,%d,%d)", Vwindowname, V_left, V_top, V_right, V_bottom endif Execute/Q cmdV2 Legend ColorTab2Wave blueredgreen Wave CT = M_colors Variable aa = 0 Variable colorind = 0 // Print scale // Generate graphs with or without scaling do TempPSName = base + "ps" + num2str(aa+1) if (scale == 1) Make/D/O/N=(dimsize(MU,0)) $TempPSName = MU[p][aa]*sqrt(SV[aa]) else Make/D/O/N=(dimsize(MU,0)) $TempPSName = MU[p][aa] endif AppendToGraph/C=(CT[colorind][0],CT[colorind][1],CT[colorind][2])/W=$Uwindowname $TempPSName vs $xwName TempPKName = base + "pk" + num2str(aa+1) if (scale == 1) Make/D/O/N=(dimsize(MV,0)) $TempPKName = MV[p][aa]*sqrt(SV[aa]) else Make/D/O/N=(dimsize(MV,0)) $TempPKName = MV[p][aa] endif AppendToGraph/C=(CT[colorind][0],CT[colorind][1],CT[colorind][2])/W=$Vwindowname $TempPKName vs $ywName colorind += (floor((Dimsize(CT,0))/(rank-1))) MURtemp[][aa] = MU[p][aa] MVRtemp[][aa] = MV[p][aa] SVtemp[aa] = SV[aa] aa +=1 while(aa < rank) // Reconstruct matrix from significant SVD components MatrixOp/O ARtemp = MURtemp x DiagRC(SVtemp,rank,rank) x ((MVRtemp)^t) String ReconDA = base + "A" + num2str(rank) + "sv" Duplicate/O ARtemp $ReconDA Duplicate/O ARtemp DAtemp_zmat MatrixOp/O DAtemp_zmat = ZM - ARtemp DAtemp_zmat = DAtemp_zmat^2 String DDAname = base + "DDA" + num2str(rank) Duplicate/O DAtemp_zmat $DDAname String cmdZ0, cmdZ1, cmdZ2 String DAwindowname = base + num2str(rank) + "DDA" sprintf cmdZ0, "GetWindow/Z %s, wsize", DAwindowname Execute/Q cmdZ0 // Print V_left, V_top, V_right, V_bottom sprintf cmdZ1, "DoWindow/K %s", DAwindowname Execute/Q cmdZ1 if ((V_left + V_top + V_right + V_bottom) == 0) sprintf cmdZ2, "Display/N=%s;AppendImage %s vs {%s, %s}", DAwindowname, DDAname, ximName, yimName else sprintf cmdZ2, "Display/N=%s/W=(%d,%d,%d,%d);AppendImage %s vs {%s, %s}", DAwindowname, V_left, V_top, V_right, V_bottom, DDAname, ximName, yimName endif Execute/Q cmdZ2 String cmdZ3 sprintf cmdZ3, "ModifyImage %s ctab={*,*,Rainbow,0}", DDAname Execute/Q cmdZ3 String cmdZ4 sprintf cmdZ4, "ModifyImage %s ctabAutoscale=3", DDAname Execute/Q cmdZ4 ShowInfo String cmdZ5 sprintf cmdZ5, "ColorScale/C/N=text0/F=0/A=RC/E image=%s", DDAname Execute/Q cmdZ5 KillWaves/Z M_colors KillWaves/Z MURtemp KillWaves/Z MVRtemp KillWaves/Z SVtemp KillWaves/Z ARtemp KillWaves/Z DAtemp_zmat DoWindow/F $ImName return 0 End //////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////// Function ReconWrapper() String Pmat, Umat, Smat Prompt Pmat, "Choose amplitude matrix with GF coefficients: ", popup, WaveList("*_pmat",";","") Prompt Umat, "Choose U matrix from SVD: ", popup, WaveList("*_psU",";","") Prompt Smat, "Choose singular value matrix from SVD: ", popup, WaveList("*_svW",";","") DoPrompt "Reconstruct species absorption from SVD fit.", Pmat, Umat, Smat if(V_flag == 1) return 0 else ReconSpeciesAbs(Pmat, Umat, Smat) endif End Function ReconSpeciesAbs(Pmat, Umat, Smat) String Pmat, Umat, Smat String GValName = RemoveEnding(Pmat, "pmat")+"gmat" String Fname = RemoveEnding(Umat, "psU")+"fmat" Wave PM = $Pmat Wave UM = $Umat Wave SM = $Smat Variable rank = Dimsize(PM, 0) Variable basis = Dimsize(PM,1) Variable length = Dimsize(UM, 0) Make/O/D/N=(length, rank) $Fname Wave FM = $Fname FM=0 If(WaveExists($GValName)==1) Wave GM = $GValName Else Make/O/D/N=(rank) $GValName Wave GM = $GValName GM = p EndIf Variable i,j, q i = 0 do q=0 do j=0 do // mulitply by appropraite SV // SV0 for basis 0, 1 for basis 1, etc. // so, use j index FM[i][q] = FM[i][q] + PM[q][j]*UM[i][j]*SM[j] j +=1 while(j= 22) Variable i = lengthTest - 22 Variable j=0 do fileHandle = RemoveEnding(fileHandle) j+=1 while(j <= i) else fileHandle = fileHandle endif fileHandle += "_sxfc" LoadWave/J/M/D/A=$fileHandle/K=0 outputPath // WaveExists 1 valid 0 invalid wName = fileHandle +"0" Variable b=0 if (WaveExists ($wName) == 1) do b += 1 wName2 = fileHandle + num2str(b) while(WaveExists ($wName2) == 1) // write b-1 since loop runs one more time than we want wName = fileHandle + num2str(b-1) endif Print wName Variable cancelTest = cmpstr(outputPath, "") if (cancelTest == 0) Print "Open file cancelled." else Redimension/N=(-1,2) $wName endif End Function FitSolvFC() String ImTest = ImageInfo("","",0) // make this only applicable to images if(cmpstr(Imtest,"",0) == 0) Print "Not an image." return 0 else NVAR gCursB = root:Packages:InspectData:gCursB String info= ImageInfo("","",0) String zmatName = StringByKey("ZWAVE",info) // String xwName = StringByKey("XWAVE",info) String base String suffix String regex = "(.*?)(zmat|zibg|zroi|zccm|A.sv)" SplitString /E=(regex) zmatName, base, suffix String xwName, ywName if(CmpStr(zmatName,"")==0) xwName = "new_xc" ywName = "new_yc" else xwName = base + "xc" ywName = base + "yc" endif // String xwName = RemoveEnding(zmatName, "zmat") // xwName = RemoveEnding(zmatName, "zibg") Variable xpos, lambda, CursName Variable xposB, lambdaB xpos = pcsr(A) lambda = hcsr(A) if(gCursB == 1) xposB = pcsr(B) lambdaB = hcsr(B) endif // Prompt CursName, "Cursor used to generate plot:", popup, "Cursor A;Cursor B;ROI Cursor A/B" Prompt CursName, "Cursor used to generate plot:", popup, "Cursor A;Cursor B" Prompt zmatName, "Enter matrix wave name: " // Prompt zmatName, "Enter matrix wave name: ", popup, StringByKey("ZWAVE",ImageInfo("","",0)) Prompt xpos, "Enter cursor A postion for desired wavelength: " Prompt xposB, "Enter cursor B postion for desired wavelength: " Prompt xwName, "Enter wavelength wave name: " if(gCursB == 1) DoPrompt "Generate Kinetics", CursName, zmatName, xpos, xposB, xwName else DoPrompt "Generate Kinetics", zmatName, xpos, xwName CursName = 1 endif if (V_Flag) return -1 endif String skwName if(CursName == 1) Print "A" skwName = Plot1DFromMat2(zmatName, xpos, xpos, xwName, ywName, 0) elseif(CursName == 2) Print "B" skwName = Plot1DFromMat2(zmatName, xposB, xposB, xwName, ywName, 0) elseif(CursName == 3) Print "A/B" skwName = Plot1DFromMat2(zmatName, xpos, xposB, xwName, ywName, 0) endif DoUpdate Variable t0guess, t0final, gaussyesno Prompt t0guess, "Enter guess for t0: " Prompt gaussyesno, "Use gaussian component: ", popup, "yes;no" DoPrompt "Initial Guesses", t0guess, gaussyesno Make/D/N=5/O W_coef Variable Nfitpts = Dimsize($skwName,0) W_coef[0] = {0,.001,-.001,t0guess,.06} Variable linum = WhichListItem(skwName, TraceNameList("",";",1), ";") String wfitrgb = StringByKey("rgb(x)", TraceInfo("","", linum), "=") if(gaussyesno == 1) FuncFit/L=(Nfitpts) /NTHR=0/TBOX=768 TA_SolventResponse W_coef $skwName /X=$ywName /D else FuncFit/L=(Nfitpts) /H="10000"/NTHR=0/TBOX=768 TA_SolventResponse W_coef $skwName /X=$ywName /D endif // procedure fails if wave with fit_ prefix is longer than 31 characters String fitname = "fit_" + skwName Variable strlength = strlen(fitname) - 31 Variable ii = 0 Do fitname = RemoveEnding(fitname) ii +=1 While(ii < strlength) String cmd0, cmd1 sprintf cmd0, "ModifyGraph rgb('%s')= %s", fitname, wfitrgb Execute/Q cmd0 sprintf cmd1, "ModifyGraph lsize('%s')=2", fitname Execute/Q cmd1 DoUpdate t0final = W_coef[3] if(CursName == 1) //Print num2str(lambda) + ", " num2str(t0final) Appendt0Wave(lambda, t0final) elseif(CursName == 2) //Print num2str(lambdaB) + ", " num2str(t0final) Appendt0Wave(lambdaB, t0final) elseif(CursName == 3) //Print num2str(lambda) + ", " num2str(t0final) Appendt0Wave(lambda, t0final) endif endif return 0 End Function Appendt0Wave(lambda, t0final) Variable lambda, t0final String towavename String newtowave = "FC_t0" Variable lcheck, tcheck Prompt towavename, "Enter target 2D t0 Fit Coefficient Wave to Append: ", popup, "New Wave;"+Wavelist("*",";","") Prompt newtowave, "Enter name of new FC target wave: " Prompt lambda, "Lambda position: " Prompt t0final, "Time zero position: " DoPrompt "Store Fit Coefficients", towavename,newtowave, lambda, t0final if (V_flag == 1) // User hit cancel button, so do nothing. return 0 endif Variable dummy If(CmpStr(towavename,"New Wave") == 0) If(WaveExists($newtowave) == 0) Make/D/O/N=(1,2) $newtowave Wave NT0 = $newtowave NT0[0][0] = lambda NT0[0][1] = t0final Else Print "Wave already exists. Try Again." Appendt0Wave(lambda, t0final) Endif Else Wave TWN = $towavename If(Dimsize(TWN,1) == 2) dummy = Dimsize(TWN,0) Redimension/N=(dummy+1,2) TWN TWN[dummy][0] = lambda TWN[dummy][1] = t0final Else Print "Target wave does not have the proper dimensions. Try a new wave." Appendt0Wave(lambda, t0final) Endif EndIf End Function colorindreturn(n) // n = number of waves in W_WaveList Variable n Wave wcl = M_colors Variable nmax = Dimsize(wcl,0) Variable denom, num Variable colorind if(n == 1) colorind = 0 elseif(n == 2) colorind = nmax-1 else denom = 2^(floor(log(n-2)/log(2))+1) //Print denom Variable i = 0 do num = 1 + 2*(i) i+=1 while(floor(log(n-2)/log(2)) == floor(log(n-2-i)/log(2))) //Print num colorind = floor((nmax-1)*(num/denom)) endif //Print colorind return colorind End //////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////// // Add function to join two data sets with identical time or wavelength axes // Sort into monotonic order // And then average duplicate points to make image generation work // Feature added 11/29/12 // TODO - make work for data sets with different time and wavelength axes Function JoinMatrices() String xwave1, xwave2, ywave1, ywave2, zwave1, zwave2 String Znew = "JoinedDataSet_" Variable N1 = 1 Variable N2 = 1 Prompt xwave1, "Enter X wave for data set 1: ", popup, Wavelist("*_x*",";","") Prompt ywave1, "Enter Y wave for data set 1: ", popup, Wavelist("*_y*",";","") Prompt zwave1, "Enter Z matrix for data set 1:", popup, Wavelist("*_z*",";","") Prompt N1, "Enter normalization factor for data set 1:" Prompt xwave2, "Enter X wave for data set 2:", popup, Wavelist("*_x*",";","") Prompt ywave2, "Enter Y wave for data set 2:", popup, Wavelist("*_y*",";","") Prompt zwave2, "Enter Z matrix for data set 2:", popup, Wavelist("*_z*",";","") Prompt N2, "Enter normalization factor for data set 2:" Prompt Znew, "New name for joined data set:" DoPrompt "Select data sets to join and sort", xwave1, ywave1, zwave1, N1, xwave2, ywave2, zwave2, N2 // Make sure wave is short enough Variable lengthTest = strlen(Znew) Znew = CleanUpName(Znew, 0) if(lengthTest >= 22) Variable i = lengthTest - 22 Variable j=0 do Znew = RemoveEnding(Znew) j+=1 while(j <= i) else Znew = Znew endif // standard wave assignments Wave X1 = $xwave1 Wave Y1 = $ywave1 Wave Z1 = $zwave1 Wave X2 = $xwave2 Wave Y2 = $ywave2 Wave Z2 = $zwave2 // check to see if wavelength and time waves are different // so that we can properly join or average Variable xmode = EqualWaves(X1,X2,1,0) Variable ymode = EqualWaves(Y1,Y2,1,0) Variable casemode // same wavelength scaling If(xmode == 1 && ymode == 0) casemode = 0 // same time scaling elseif(xmode == 0 && ymode == 1) casemode = 1 // all different elseif(xmode == 0 && ymode == 0) casemode = 2 // all identical elseif(xmode == 1 && ymode == 1) casemode = 3 endif String XNew, YNew, ZZNew // define string with base name but make sure we do not overwrite existing wave Variable b=0 String zbase = Znew + num2str(b) XNew = zbase + "_xc" if (WaveExists ($XNew) == 1) do b += 1 zbase = Znew + num2str(b) XNew = zbase + "_xc" while(WaveExists ($XNew) == 1) endif YNew = zbase + "_yc" ZZnew = zbase + "_zmat" // case 0: wavelengths are the same, time axis is different If(casemode == 0) // use either wave to set wavelength scaling Duplicate/O X1, $Xnew // join y waves (time column) then generate index wave to be used to // sort other waves later Concatenate/NP/O {Y1,Y2}, tempy Duplicate/O tempy, tempindex Duplicate/O tempy, $YNew MakeIndex tempy, tempindex Wave YN = $YNew YN = tempy[tempindex[p]] // apply index wave to matrices // apply normalization factors Duplicate/O Z1, Z1temp Z1temp*=N1 Duplicate/O Z2, Z2temp Z2temp*=N2 // join Concatenate/O/NP {Z1temp,Z2temp}, tempz Duplicate/O tempz, $ZZnew Wave ZN = $ZZnew ZN = tempz[p][tempindex[q]] KillWaves/Z tempy, tempindex, tempz, Z1temp, Z2temp // case 1: wavelengths are different, time axis is same elseif(casemode == 1) // generate index wave from wavelength column and sort Concatenate/NP/O {X1,X2}, tempx Duplicate/O tempx, tempindex Duplicate/O tempx, $XNew MakeIndex tempx, tempindex Wave XN = $XNew XN = tempx[tempindex[p]] // use either wave to set time scaling Duplicate/O Y1, $Ynew // apply index wave to matrices Duplicate/O Z1, Z1temp Z1temp*=N1 // transpose to join properly MatrixOp/O Z1temp = Z1temp^t Duplicate/O Z2, Z2temp Z2temp*=N2 MatrixOp/O Z2temp = Z2temp^t // join Concatenate/O/NP {Z1temp,Z2temp}, tempz MatrixOp/O tempz = tempz^t Duplicate/O tempz, $ZZnew Wave ZN = $ZZnew ZN = tempz[tempindex[p]][q] KillWaves/Z tempx, tempindex, tempz, Z1temp, Z2temp // case2: different time and wavelength elseif(casemode == 2) Print "Files have different scaling in time and wavelength." // implementation - create parametric wave // use interpolation functions // case 3: identical scaling, inform user to average instead or call directly once implemented elseif(casemode == 3) Print "Scaling for the data sets is identical. Use the Average function instead." endif IndexAndRemoveDups(XNew, YNew, ZZNew, casemode) return 0 End Function IndexAndRemoveDups(xwave, ywave, zmat, casemode) String xwave, ywave, zmat Variable casemode Wave xw = $xwave Wave yw = $ywave Wave zw = $zmat Variable i,j, index Variable imax, jmax imax = Dimsize(xw,0) jmax = Dimsize(yw,0) if(casemode == 0) // search and index time axis - y Duplicate/O yw, ywtemp Duplicate/O zw, zwtemp i = 1 index = 1 // make wave when first duplicate is found do if(yw[index] == yw[index - 1]) Make/D/O/N=1 indexwavetemp indexwavetemp[0] = index index+=1 else index +=1 endif while((WaveExists(indexwavetemp)) == 0 && (index < jmax)) // continue with index writing duplicate positions to created wave // make sure some duplicates are found otherwise error messages if(WaveExists(indexwavetemp) == 1) do if(yw[index] == yw[index - 1]) i+=1 Insertpoints i, 1, indexwavetemp indexwavetemp[i] = index index+=1 else index +=1 endif while(index < jmax) // delete points from time wave // work from end of file otherwise assignements dynamically change j=i Do Deletepoints indexwavetemp[j], 1, yw j-=1 While(j>=0) // sum relevant columns from ywtemp back into zmat j=i Do zw[][indexwavetemp[j]-1] = (zwtemp[p][indexwavetemp[j]] + zwtemp[p][indexwavetemp[j]-1])/2 Deletepoints/M=1 (indexwavetemp[j]), 1, zw j-=1 While(j>=0) endif KillWaves/Z ywtemp, zwtemp, indexwavetemp ImageGen(xwave, ywave, zmat) elseif(casemode == 1) // search and index wavelength axis - x Duplicate/O xw, xwtemp Duplicate/O zw, zwtemp i = 1 index = 1 // make wave when first duplicate is found do if(xw[index] == xw[index - 1]) Make/D/O/N=1 indexwavetemp indexwavetemp[0] = index index+=1 else index +=1 endif while((WaveExists(indexwavetemp) == 0) && (index < imax)) // continue with index writing duplicate positions to created wave // make sure some duplicates are found otherwise error messages if(WaveExists(indexwavetemp) == 1) do if(xw[index] == xw[index - 1]) i+=1 Insertpoints i, 1, indexwavetemp indexwavetemp[i] = index index+=1 else index +=1 endif while(index < imax) // delete points from time wave // work from end of file otherwise assignements dynamically change j=i Do Deletepoints indexwavetemp[j], 1, xw j-=1 While(j>=0) // sum relevant rows from xwtemp back into zmat j=i Do zw[indexwavetemp[j]-1][] = (zwtemp[indexwavetemp[j]][q] + zwtemp[indexwavetemp[j]-1][q])/2 Deletepoints/M=0 (indexwavetemp[j]), 1, zw j-=1 While(j>=0) endif KillWaves/Z ywtemp, zwtemp, indexwavetemp ImageGen(xwave, ywave, zmat) endif return 0 End // Generate separate function for image generation // Repeated code in two other functions // Eventually will achieve full modularization Function ImageGen(xwave, ywave, zmat) // generate pixel locations for image // assume monotonic data since already processed in other functions String xwave, ywave, zmat //Print "Runnning Image Gen." Wave xw = $xwave Wave yw = $ywave Wave zw = $zmat Variable imax, jmax imax = Dimsize(xw,0) jmax = Dimsize(yw,0) String base String suffix String IMx, IMy String regex = "(.*?)(zmat|zibg|zroi|A.sv)" SplitString /E=(regex) zmat, base, suffix if(CmpStr(zmat,"")==0) Print "Failed to get matrix name." return 0 else IMx = base + "xim" IMy = base + "yim" endif // for image plots Make/D/O/N=(imax+1) $IMx Wave xIm = $IMx Make/D/O/N=(jmax+1) $IMy Wave yIm = $IMy Variable g, h // if first two points are the same then the resulting file will not be monotonic If(xw[1]== xw[0]) xIm[0]= xw[0]-(xw[0]/1) else xIm[0]= xw[0]-((xw[1]-xw[0])/2) endif g=1 do xIm[g] = (xw[g] + xw[g-1])/2 g += 1 while (g < imax) xIm[imax] = xw[imax-1] + ((xw[imax-1] - xw[imax-2])/2) // if first two points are the same then the resulting file will not be monotonic If(yw[1]== yw[0]) yIm[0]= yw[0]-(yw[0]/1) else yIm[0]= yw[0]-((yw[1]-yw[0])/2) endif h=1 do yIm[h] = (yw[h] + yw[h-1])/2 h+= 1 while (h < jmax) yIm[jmax] = yw[jmax-1] + ((yw[jmax-1] - yw[jmax-2])/2) Display;AppendImage $zmat vs {$IMx,$IMy}//;DelayUpdate ModifyImage $zmat ctab= {*,*,Rainbow,0} ModifyImage $zmat ctabAutoscale=3,lookup= $"" ShowInfo GetWindow kwTopWin wtitle String imTitle = S_Value String imTitle2 = WinName(0,1) imTitle = RemoveEnding(imTitle, ":") Cursor/I/H=1 /W=$imTitle A $zmat 1,1 Cursor/M/H=1 B // ImageHookGen() SetWindow $imTitle2, hook(MyHook)=MyWindowHook DoWindow/F $imTitle2 return 0 End ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// // Function to Export csv file added to version 4.5 // Adds back column and row information to match format of imported data // Deletes temporary matrix with time and lambda information - comment out KillWaves at end to keep // Utilizes code from hrodstein (wavemetrics) to generate csv file from waves Function ExportCSV() String xwave, ywave, zwave Prompt xwave, "Enter X wave name (lambda): ", popup, Wavelist("*_x*",";","") Prompt ywave, "Enter Y wave name (time): ", popup, Wavelist("*_y*",";","") Prompt zwave, "Enter Z matrix name:", popup, Wavelist("*_z*",";","") DoPrompt "Select data to export to csv file", xwave, ywave, zwave Variable cancelTest = cmpstr(zwave, "") if (cancelTest == 0) Print "Export file cancelled." else Wave xw = $xwave Wave yw = $ywave Wave zw = $zwave Variable nrows = Dimsize(zw,0) Variable ncols = Dimsize(zw,1) Duplicate/O zw tempmat InsertPoints 0,1, tempmat InsertPoints/M=1 0,1, tempmat Variable i = 1 Do tempmat[0][i] = yw[i-1] i+=1 While(i<=ncols) Variable j = 1 Do tempmat[j][0] = xw[j-1] j+=1 While(j<=nrows) SaveWavesDelimited("", "", "tempmat", ",", 0, 2) KillWaves/Z tempmat endif return 0 End // Thanks to hrodstein for the following code snippet. Modified for csv specificity. // SaveWavesDelimited(pathName, filePath, list, delimiter, includeWaveNames, overwriteMode) // As of Igor Pro 6.22, the Igor Save operation can not save comma-delimited files. // It can save tab-delimited (/J) or space-delimited (/G). // To work around this, this routine writes the wave data and then replaces the // tab delimiter in the saved file with the specified delimiter. // The target file is specified using an Igor symbolic path and a file name, partial path // to the file or full path to the file. Pass "" for filePath to get a Save file dialog. // If you are not familiar with Igor symbolic paths, execute this and read the help: // DisplayHelpTopic "Symbolic Paths" // The function returns 0 if successful or non-zero if an error occurred or the user cancelled. // Read the comments for the parameters for further information. Function SaveWavesDelimited(pathName, filePath, list, delimiter, includeWaveNames, overwriteMode) String pathName // Igor symbolic path name or "" if filePath is a full path. String filePath // File name, partial path or full path. "" to get save file dialog. String list // Semicolon-separated list of wave names. String delimiter // e.g, "," for comma-delimited. Variable includeWaveNames // 1 to include wave names as column labels. Variable overwriteMode // 0 to never overwrite, 1 to always overwrite, 2 to display save file dialog if file already exists. // These are used if a Save File dialog is displayed String fileFilter = "Data Files (*.csv):.csv;" fileFilter += "All Files:.*;" String prompt = "Save waves as delimited text" Variable refNum GetFileFolderInfo /P=$pathName /Q /Z filePath if (V_Flag == 0) // File or folder exists if (V_isFolder) Printf "Can not overwrite folder at \"%s\"\r", S_Path return -1 endif // File exists switch (overwriteMode) case 0: // Never overwrite Printf "File \"%s\" already exists\r", S_Path return -1 break case 1: // Always overwrite filePath = S_Path break case 2: // Display Save File dialog Open /P=$pathName /D /F=fileFilter /M=prompt refNum as filePath filePath = S_fileName // Full path to the file if (strlen(filePath) == 0) return -1 // User cancelled endif break endswitch else // File does not exist. See if we can create it. Open /P=$pathName /Z refNum as filePath if (V_flag == 0) // The file was created. filePath = S_fileName // Full path to the file Close refNum else // Display a save file dialog Open /P=$pathName /D /F=fileFilter /M=prompt refNum as filePath filePath = S_fileName // Full path to the file if (strlen(filePath) == 0) return -1 // User cancelled endif endif endif // The overwrite parameter was handled above so we can always overwrite here if (includeWaveNames) Save /J /B /W /O list as filePath else Save /J /B /O list as filePath endif // Now replace the tab delimiter with the specified delimiter // Open file and read data Open /R refNum as filePath FStatus refNum Variable numBytes = V_logEOF String text = PadString("", numBytes, 0x20 ) // FBinRead requires this FBinRead refNum, text Close refNum text = ReplaceString("\t", text, delimiter) // Rewrite file Open refNum as filePath FBinWrite refNum, text Close refNum return 0 End