SNC DDG Calculator v.0.2

SNC DDG Calculator v.0.2

Contents


SNC_DDG_Calculator_v.0.2.ipf

#pragma rtGlobals=1		// Use modern global access method.

//	Function to create globals used in SNC DDG Calculator
Macro SNCGlobals()
	String /G globalVersion = "v.0.2"		// Version of macro
	String /G globalPath = ""				// Path to currently loaded file
	String /G globalTitle = "\t[ None ]\t "		// Displays currently loaded file
	
	String /G globalFileName = ""			// Filename (including path) used in calls to Open
	String /G globalMtNameList = ""		// List of mutant names found in patchdatafile
	String /G globalMtNumberList = ""		// List of mutant numbers found in patchdatafile
	String /G globalMtSolutionsList	 = ""	// List of mutant solutions found in patchdatafile
	
	String /G globalddgCaList = ""			// List of ddg Ca names [used as "ddg_Ca at %s Mg", StringFromList(index,globalddgCaList)]
	String /G globalddgMgList = ""			// List of ddg Mg names [used as "ddg_Mg at %s Ca", StringFromList(index,globalddgMgList)]
	
	String /G globalNewName = ""			// String to hold name of new user defined mutant
	String /G globalNewNumber = ""		// String to hold number of new user defined mutant
	String /G globalNewSolutions = "0:0_0:10_100:0_100:10"		// String to hold solutions list of new user defined mutant
	String /G globalWTName = "WT"		// String to hold user-defined WT name
	
	Variable /G globalMtIndex = 0			// Index to currently selected mutant in mutant lists 
	Variable /G gflagFileLoaded = 2		// Variable to indicate whether or not a file has been loaded
	Variable /G gflagNewData = 2			// Variable to indicate whether or not user has inputed new raw patch data
	Variable /G gflagReadyToAdd = 2		// Variable to indicate whether or not user can add user-entered values to raw patch data wave
	Variable /G gflagLoadFile = 0			// Variable to set disable flag for LoadFile button
	Variable /G gflagNewMutant = 0		// Variable to set disable flag for NewMutant button
	Variable /G gflagDisplay = 1			// Variable to indicate which values are currently displayed (rawpatchdata = 1, ddgvalues=-1)
	Variable /G gflagLineHandle = 0		// Variable to handle control panel line button
end

//	Function to create/reset globals for CreateGraphs function
Macro SNCCGGlobals()
	Variable /G globalNewWindow = 0		// Variable in Create Graphs function to indicate whether or not the graph is to be displayed in a new window
	Variable /G globalShowNumbers = 0	// Variable in Create Graphs function to indicate whether or not numeric values are displayed in graph
	Variable /G globalAxisLabel = 0		// Variable in Create Graphs function to select which unit to show on the X-Axis.  Mutant = 0, DDG Ion = 1
	Variable /G globalSortLabel = 0			// Variable in Create Graphs function to sort x-axis units.  -1 = no sort, 0 = sequence, 1 = number, 2 = maxDDG, 3 = minDDG
	Variable /G globalFillValue = 2
	Variable /G globalMaxAxis = 0
	Variable /G globalMinAxis = 0
	Variable /G globalSortMutants = 0
	Variable /G globalXaxisUnits = 0
	Variable /G globalNewWindowFlag = 0
	Variable /G globalShowValuesFlag= 0
	Variable /G globalColorWTBlackFlag = 0
	Variable /G globalDivideByWTFlag = 0
	Variable /G globalSubtractWTFlag = 0
	Variable /G globalStackGroupsFlag = 0
	Variable /G globalShowLegendFlag = 0
	Variable /G globalShowSEMFlag = 1
	Variable /G globalDifferentiateLabel = 0
	Variable /G globalCGColorR = 65535
	Variable /G globalCGColorG = 0
	Variable /G globalCGColorB = 0
	Variable /G globalCGWTColorR = 10000
	Variable /G globalCGWTColorG = 10000
	Variable /G globalCGWTColorB = 10000
	Variable /G globalCGDisplay = 0		// Variable in Create Graphs function to determine what is graphed.  0=Z, 1=Vh, 2=Slope
end

// Add an item to Igor's Load Waves submenu (Data menu)
Menu "SNCMacros"
	//"Load Patch Data File.../1", LoadPatchDataFile("", "", "", "", 1)
	"SNCDDGCalc/1", SNCDDGCalc()
End

//	Function to scan data file for next data line (skipping comment lines)
//	Function puts next data line into buffer and returns the first string of the buffer.
Function/S NextDataLine(refNum, sfileName, buffer, currentLine)
	Variable refNum
	String sfileName, &buffer
	Variable &currentLine
	String value
	
	do
		FReadLine refNum, buffer
		currentLine += 1
		if (strlen(buffer) ==0 )
			return "EOF"
		endif
		if( (char2num(buffer[0]) != 35) && (char2num(buffer) != 13) )
			sscanf buffer, "%s", value
			//printf "line=%d, value=%s\r", currentLine, value
			return value
		endif
	while(1)
end

//	Checks filetype assignment
//	Returns 1 if filetype assignment is correct, 0 if filetype assignment is erronous
Function CheckFileType (buffer, identifier, value, sfileName, currentLine)
	String buffer, identifier, value, sfileName
	Variable currentLine
	
	String tmpstring
	if (cmpstr(identifier,"filetype") != 0)
		printf "Error in %s, Line %d: Expected filetype declaration, found \"%s.\"   [101]\r", sfileName, currentLine, identifier
		return 0
	endif
	sscanf buffer, "filetype %s", tmpstring
	if (V_flag != 1)
		printf "Error in %s, Line %d: filetype not specified.   [102]\r", sfileName, currentLine
		return 0
	elseif (cmpstr(tmpstring,value) != 0)
		printf "Error in %s, Line %d: Incorrect filetype.   [103]\r", sfileName, currentLine
		return 0
	endif
	return 1
end

//	Parse mtinfo line
//	Sets values of nameFound, numberFound and solutionsFound
//	Stores values in tmpName, tmpNumber and tmpSolutions
//	nameFound, numberFound, solutionsFound, tmpName, tmpNumber and tmpSolutions are modified by assignment by address (treat as globals)
//	Returns 1 if mtinfo line is valid, 0 otherwise
Function ParseMtInfo(buffer, identifier, sfileName, currentLine, nameFound, numberFound, solutionsFound, tmpName, tmpNumber, tmpSolutions)
	String buffer, identifier, sfileName
	Variable currentLine
	Variable &nameFound, &numberFound, &solutionsFound, &tmpNumber
	String &tmpName, &tmpSolutions

	Variable i, n
	String tmpstring
	nameFound = 0
	numberFound = 0
	solutionsFound = 0
	i = strlen(identifier)
	//	Find which tags exist and store their information in tmp variables/strings
	do
		sscanf buffer[i,inf], "%s", tmpstring
		if(V_flag != 1)
			break
		endif
		if(stringmatch(tmpstring,"name=*"))
			sscanf tmpstring, "name=%s", tmpName
			if(V_flag == 1)
				nameFound = 1
			endif
		endif
		if(stringmatch(tmpstring,"number=*"))
			sscanf tmpstring, "number=%d", tmpNumber
			if(V_flag == 1)
				numberFound = 1
			endif
		endif
		if (stringmatch(tmpstring,"solutions=[*"))
			n = strsearch(buffer,"[",i)
			do
				n = strsearch(buffer," ",n)
				if (n != -1)
					buffer[n,n] = "_"
				endif
			while (n != -1)
			sscanf buffer[i,inf], "%s", tmpstring
			sscanf tmpstring, "solutions=%s", tmpSolutions
			tmpSolutions = tmpSolutions[1,strlen(tmpSolutions)-2]
			if(V_flag == 1)
				solutionsFound = 1
			endif
		endif
		i += (strlen(tmpstring)+1)
	while(1)
	if (solutionsFound !=1)
		tmpSolutions = "0:0_0:10_100:0_100:10"
	endif
	if (nameFound == 1)
		return 1
	else
		return 0
	endif
end
			
//	This function does the reading of lines of data, parsing data, and storing values into waves.
Function LoadPatchData(refNum, sfileName)
	Variable refNum			// Input File reference number
	String sfileName			// Input File name
	
	SVAR mtNameList = globalMtNameList
	SVAR mtNumberList = globalMtNumberList
	SVAR mtSolutionsList = globalMtSolutionsList
	String buffer					// String to hold output from FReadLine
	String tmpstring				// String to hold temporary values
	String identifier				// Used to hold value returned by the NextDataLine 
	String tmpName, tmpSolutions
	Variable tmpNumber
	String defaultSolutions = "0:0_0:10_100:0_100:10"
	Variable firstChar, currentLine, tmpvar, nameFound, numberFound, solutionsFound
	Variable valuesRead
	Variable err = 0
	Variable i = 0, n = 0
	String tmpWaveName = ""
	
	currentLine = 0
	printf "Open File Reference Number = %d\r", refNum
	
	//	Get filetype from file and check if correct
	identifier = NextDataLine(refNum, sfileName, buffer, currentLine)
	if (!CheckFileType(buffer, identifier, "sncpatchdata", sfileName, currentLine))
		err = 1
		return err
	endif
	
	//	Start reading actual identifier lines and data lines
	do
		//	Get next data line.
		identifier = NextDataLine(refNum, sfileName, buffer, currentLine)
		//	Check for EOF.
		if (cmpstr(identifier,"EOF") == 0)
			printf "EOF found\r"
			break
		endif
		//	Make sure mtinfo line is found.
		//	If found, parse mtinfo line.
		if (cmpstr(identifier,"mtinfo") != 0)
			printf "Error in %s, Line %d: Expected \"mtinfo\", found \"%s.\"   [104]\r", sfileName, currentLine, identifier
			err = 1
			return err
			break
		elseif (ParseMtInfo(buffer, identifier, sfileName, currentLine, nameFound, numberFound, solutionsFound, tmpName, tmpNumber, tmpSolutions) == 0)
			printf "Error in %s, Line %d: name parameter missing from mtinfo line.   [105]\r", sfileName, currentLine
			err = 1
			return err
			break
		endif
		tmpWaveName = "PD_"+tmpName
		// 	Test to see if mutant info already exists for particular mutant.
		//	If mutant info already exists, check to make sure mtNumber and mtSolutions match.
		//	If mutant info doesn't exist, create multidimensional text wave to store patch data.
		if (WhichListItem(tmpName,mtNameList) != -1)
			Wave tmpWave = $tmpWaveName
			if (cmpstr(StringFromList(WhichListItem(tmpName,mtNameList),mtNumberList),num2str(tmpNumber)) != 0)
				printf "Error in %s, Line %d: Mutant number does not match for previous instance of Mutant %s.   [106]\r", sfileName, currentLine, tmpName
				err = 1
				return err
				break
			endif
			if (cmpstr(StringFromList(WhichListItem(tmpName,mtNameList),mtSolutionsList),tmpSolutions) != 0)
				printf "Error in %s, Line %d: Mutant solutions do not match for previous instance of Mutant %s.   [107]\r", sfileName, currentLine, tmpName
				err = 1
				return err
				break
			endif
		else
			mtNameList = AddListItem(tmpName, mtNameList, ";", Inf)
			if (numberFound != 1)
				tmpNumber = NaN
			endif
			if (solutionsFound != 1)
				tmpSolutions = defaultSolutions
			endif
			mtNumberList = AddListItem(num2str(tmpNumber), mtNumberList, ";", Inf)
			mtSolutionsList = AddListItem(tmpSolutions, mtSolutionsList, ";", Inf)
			make /N=(0,ItemsInList(tmpSolutions,"_")*2 ) /O $tmpWaveName
			Wave tmpWave = $tmpWaveName
			for (i=0;i<ItemsInList(tmpSolutions,"_");i+=1)
				sprintf tmpString, "Vh_%s", StringFromList(i,tmpSolutions,"_")
				SetDimLabel 1, i, $tmpString, $tmpWaveName
				sprintf tmpString, "Slope_%s", StringFromList(i,tmpSolutions,"_")
				SetDimLabel 1, i+ItemsInList(tmpSolutions,"_"), $tmpString, $tmpWaveName
			endfor
		endif
		//printf "mtNameList=%s\rmtNumberList=%s\rmtSolutionsList=%s\r", mtNameList, mtNumberList, mtSolutionsList
		//	Add patch data to multidimensional wave.
		do
			identifier = NextDataLine(refNum, sfileName, buffer, currentLine)
			if (cmpstr(identifier,"EOF") == 0)
				printf "Error in %s, Line %d: Unexpected end of file.   [108]", sfileName, currentLine, tmpName
				err = 1
				return err
				break
			endif			
			if (cmpstr(identifier, "\mtinfo") == 0)
				//printf "\\mtinfo line found\r"
				break
			endif
			InsertPoints /M=0 DimSize(tmpWave,0), 1, tmpWave
			n = 0
			for (i=0; i<(ItemsInList(tmpSolutions,"_")*2); i+=1)
				sscanf buffer[n,inf], "%s", tmpstring
				tmpWave[DimSize(tmpWave,0)-1][i] = str2num(tmpstring)
				n = strsearch(buffer,tmpstring,n) + strlen(tmpstring)
			endfor
		while(1)
	while(1)
	return err
End

//	Function to load patch data from a previously saved file
Function LoadPatchDataFile(ctrlName) : ButtonControl
	String ctrlName
	
	SVAR newTitle = globalTitle
	SVAR path = globalPath
	SVAR fileName = globalFileName
	SVAR mtNameList = globalMtNameList
	SVAR mtNumberList = globalMtNumberList
	SVAR mtSolutionsList = globalMtSolutionsList
	NVAR flagFileLoaded = gflagFileLoaded
	NVAR mtIndex = globalMtIndex
	String titlePath
	String pathName
	Variable err, i, n, tmpvar
	Variable refNum
	String sfileName, tmpstring
	String message = "Select file containing raw patch data:"
	Open/R/Z=2/M=message refNum
	err = V_flag
	
	if (err == -1)
		return err			// User cancelled.
	endif
	
	sfileName = S_fileName
	path = S_fileName
	fileName = S_fileName
	
	//  Extract filename from S_fileName
	do
		i = strsearch(sfileName," ",0)
		if (i != -1)
			sfileName[i,i] = "_"
		endif
	while (i != -1)
	sfileName = StringFromList((ItemsInList(sfileName,":")-1),sfileName,":")
	
	//  Convert path into a Windows directory format string
	i = strsearch(path,":",0)
	path[i,i] = ":\\"
	do
		i = strsearch(path,":",i+1)
		if (i != -1)
			path[i,i] = "\\"
		endif
	while (i != -1)
	
	//  Convert titlePath into a Windows directory format string that can be read by the Igor TitleBox function
	titlePath = path
	i = 0
	do
		i = strsearch(titlePath,"\\",i+1)
		if (i != -1)
			titlepath[i,i] = "\\\\"
			i+=1
		endif
	while (i != -1)
	
	Printf "Loading example data from \"%s\"\r", path
	mtNameList=""
	mtNumberList=""
	mtSolutionsList=""
	err = LoadPatchData(refNum, sfileName)
		
	Close refNum		// Close the file.

	printf "\rerr=%d\r",err
	if (err != 0)
		return err
	endif
	
	flagFileLoaded = 0
	sprintf newTitle, "\t%s\t ", titlePath
	ControlUpdate mtSelect
	sprintf tmpString, "Button EditFile disable=gflagFileLoaded"
	Execute tmpString

	for (mtIndex=(ItemsInList(mtNameList)-1); mtIndex>=0; mtIndex-=1)
		SNCGetDDGLists()
		SNCddgMenu()
		SNCddgSpace()
		SNCRawMenu()
		SNCRawSpace()
	endfor
	mtIndex = 0
	SNCInputDialogues()
	sprintf tmpString, "Button AddData disable=0, help={\"Add patch data above to current patch data wave  (PD_%s).\"}, title=\"Add above values to current patch data wave  (PD_%s)\"", StringFromList(mtIndex,mtNameList), StringFromList(mtIndex,mtNameList)
	Execute tmpString
	sprintf tmpString, "Button ToggleDisplay disable=0"
	Execute tmpString
	sprintf tmpString, "PopupMenu mtSelect pos={10,25}, size={200,20},  mode=1, help={\"Select which mutant data from the currently loaded file you want to load.\"}, title=\"Select Mutant: \", value=globalMtNameList, proc=SNCMtSelect"
	Execute tmpString
	sprintf tmpString, "Button EditPDWave disable=0, title=\"Edit PD_\"+StringFromList(globalMtIndex,globalMtNameList)+\" Wave\""
	Execute tmpString
	sprintf tmpString, "Button CreateDDGGraphs disable=0"
	Execute tmpString
	sprintf tmpString, "Button CreateOtherGraphs disable=0"
	Execute tmpString
	sprintf tmpString, "Button EditPDWave disable=0"
	Execute tmpString

	return err			// Zero signifies no error.	
End

//	Function to open current patch data file in Notepad.exe for editing (Windows only)
Function SNCEditFile(ctrlName) : ButtonControl
	String ctrlName
	
	SVAR path = globalPath
	String tmppath
	String cmd

	sprintf cmd, "Notepad.exe %s", path
	printf "%s\r", cmd
	ExecuteScriptText cmd
end

//	Function to open current patch data wave in a table for editing
Function SNCEditPDWave(ctrlName) : ButtonControl
	String ctrlName
	
	SVAR mtNameList = globalMtNameList
	NVAR mtIndex = globalMtIndex
	String tmpWaveName
	
	sprintf tmpWaveName, "PD_%s", StringFromList(mtIndex, mtNameList)
	Wave tmpWave = $tmpWaveName
	edit tmpWave
end


//	Function to display a dropdown menu of which mutants are available from currently loaded patch data file, and allows user to select a mutant from the list
Function SNCMtSelect(ctrlName,popNum,popStr) : PopupMenuControl
	String ctrlName
	Variable popNum		// Which item is currently selected (1-based)
	String popStr			// Contents of current popup item as string

	NVAR mtIndex = globalMtIndex
	SVAR mtNameList = globalMtNameList
	String tmpString
	
	mtIndex = popNum-1
	SNCGetDDGLists()
	SNCddgMenu()
	SNCddgSpace()
	SNCRawMenu()
	SNCRawSpace()
	SNCInputDialogues()
	sprintf tmpString, "Button AddData help={\"Add patch data above to current patch data wave  (PD_%s).\"}, title=\"Add above values to current patch data wave  (PD_%s)\"", StringFromList(mtIndex,mtNameList), StringFromList(mtIndex,mtNameList)
	Execute tmpString
	sprintf tmpString, "Button EditPDWave disable=0, title=\"Edit PD_\"+StringFromList(globalMtIndex,globalMtNameList)+\" Wave\""
	Execute tmpString
end

//	Function to create and save ddg lists (globalddgCaList and globalddgMgList)
Function SNCGetDDGLists()
	NVAR mtIndex = globalMtIndex
	SVAR mtSolutionsList = globalMtSolutionsList
	SVAR ddgCaList = globalddgCaList
	SVAR ddgMgList = globalddgMgList
	String tmpString, tmpList
	Variable n, i, tmpVar1, tmpVar2
	
	ddgCaList = ""
	ddgMgList = ""
	tmpString = StringFromList(mtIndex, mtSolutionsList)
	for (n=0; n<ItemsInList(tmpString,"_"); n+=1)
		sscanf StringFromList(n,tmpString,"_"), "%d:%d", tmpVar1, tmpVar2
		for (i=n+1; i<ItemsInList(tmpString,"_"); i+=1)
			if(cmpstr(num2str(tmpVar1), StringFromList(0,StringFromList(i,tmpString,"_"),":")) == 0)
				tmpList = SortList(StringFromList(i,tmpString,"_")+"_"+StringFromList(n,tmpString,"_"),"_",2)
				tmpList = tmpList[0,strlen(tmpList)-2]
				ddGMgList = AddListItem(tmpList,ddGMgList,";",Inf)
			endif
			if(cmpstr(num2str(tmpVar2), StringFromList(1,StringFromList(i,tmpString,"_"),":")) == 0)
				tmpList = SortList(StringFromList(i,tmpString,"_")+"_"+StringFromList(n,tmpString,"_"),"_",2)
				tmpList = tmpList[0,strlen(tmpList)-2]
				ddgCaList = AddListItem(tmpList,ddGCaList,";",Inf)
			endif
		endfor
	endfor
	ddgCaList = SortList(ddgCaList)
	ddgMgList = SortList(ddgMgList)
end

//	Function to create and display new rawmenu textbox
Function SNCRawMenu()
	NVAR mtIndex = globalMtIndex
	NVAR flagDisplay = gflagDisplay
	SVAR mtNameList = globalMtNameList
	SVAR mtSolutionsList = globalMtSolutionsList
	String tmpString, tmpString2
	Variable i, tmpVar1, tmpVar2
	
	tmpString = "\\Z09 Patch #\\M"
	tmpString2 = StringFromList(mtIndex, mtSolutionsList)
	for (i=0; i<ItemsInList(tmpString2,"_"); i+=1)
		sscanf StringFromList(i, tmpString2,"_"), "%d:%d", tmpVar1, tmpVar2
		sprintf tmpString, "%s\tV_h\\B%d/%d\\M", tmpString, tmpVar1, tmpVar2
	endfor
	sprintf tmpString, "%s\t", tmpString
	for (i=0; i<ItemsInList(tmpString2,"_"); i+=1)
		sscanf StringFromList(i, tmpString2,"_"), "%d:%d", tmpVar1, tmpVar2
		sprintf tmpString, "%s\tSlope\\B%d/%d\\M", tmpString, tmpVar1, tmpVar2
	endfor
	TextBox /C /N=rawmenu /V=1 /A=LT /T=50 /F=1 tmpString
	TextBox /C /N=ddgmenu /V=0
	flagDisplay = 1
	sprintf tmpString, "Button ToggleDisplay title=\"Show DG and DDG\""
	Execute tmpString
end

//	Function to create and display new ddgmenu textbox
Function SNCddgMenu()
	NVAR mtIndex = globalMtIndex
	NVAR flagDisplay = gflagDisplay
	SVAR mtNameList = globalMtNameList
	SVAR mtSolutionsList = globalMtSolutionsList
	SVAR ddgCaList = globalddgCaList
	SVAR ddgMgList = globalddgMgList
	String tmpString, tmpString2
	Variable n,i, tmpVar1, tmpVar2
	
	tmpString = "\\Z09 Patch #\\M"
	tmpString2 = StringFromList(mtIndex, mtSolutionsList)
	for (i=0; i<ItemsInList(tmpString2,"_"); i+=1)
		sscanf StringFromList(i,tmpString2,"_"), "%d:%d", tmpVar1, tmpVar2
		sprintf tmpString, "%s\tdG\\B%d/%d\\M", tmpString, tmpVar1, tmpVar2
	endfor
	sprintf tmpString, "%s\t", tmpString
	for (i=0; i<ItemsInList(ddgCaList); i+=1)
		sprintf tmpString, "%s\tddG\\BCa_%sM\\M", tmpString, StringFromList(1,StringFromList(0,StringFromList(i,ddgCaList),"_"),":")
	endfor
	for (i=0; i<ItemsInList(ddgMgList); i+=1)
		sprintf tmpString, "%s\tddG\\BMg_%sC\\M", tmpString, StringFromList(0,StringFromList(0,StringFromList(i,ddgMgList),"_"),":")
	endfor
	TextBox /C /N=ddgmenu /V=1 /A=LT /T=50 /F=1 tmpString
	TextBox /C /N=rawmenu /V=0
	flagDisplay = -1
	sprintf tmpString, "Button ToggleDisplay title=\"Show V_h and Slope\""
	Execute tmpString
end

//	Function to create and display rawspace textbox
Function SNCRawSpace()
	NVAR mtIndex = globalMtIndex
	NVAR flagDisplay = gflagDisplay
	SVAR mtNameList = globalMtNameList
	String tmpString, tmpString2, tmpWaveName, tmpPDWaveName, tmpAZWaveName, tmpAVWaveName, tmpASWaveName
	Variable n,i,tmpVar
	
	//  Display raw data
	TextBox /C /N=rawspace /V=1 /A=LT /T=50 /Y=15 /F=0 "\\Z09" 
	sprintf tmpPDWaveName, "PD_%s", StringFromList(mtIndex,mtNameList)
	Wave tmpPDWave = $tmpPDWaveName
	tmpString = ""
	tmpString2 = ""
	for (n=0; n<DimSize(tmpPDWave,0); n+=1)
		sprintf tmpString, "%d", n+1
		sprintf tmpString2, "\\K(%d,%d,%d) \t  \t \t \t", 1,1,1
		for (i=0; i<DimSize(tmpPDWave,1); i+=1)
			sprintf tmpString, "%s\t\\K(%d,%d,%d)%g", tmpString, n,n,n, tmpPDWave[n][i]
			sprintf tmpString2, "%s\t ", tmpString2
			if ( (i+1) == (DimSize(tmpPDWave,1)/2) )
				sprintf tmpString, "%s\t ", tmpString
				sprintf tmpString2, "%s\t ", tmpString2
			endif
		endfor
		sprintf tmpString, "%s\\K(0,0,0)", tmpString
		sprintf tmpString2, "%s\\L1400", tmpString2
		AppendText /N=rawspace tmpString
	endfor
	AppendText /N=rawspace tmpString2
	
	//  Create waves to store averaged Z, Vh and slope values
	sprintf tmpAZWaveName, "AZ_%s", StringFromList(mtIndex,mtNameList)
	make /O /N=(3,DimSize(tmpPDWave,1)/2) $tmpAZWaveName = NaN
	Wave tmpAZWave = $tmpAZWaveName
	sprintf tmpAVWaveName, "AV_%s", StringFromList(mtIndex,mtNameList)
	make /O /N=(3,DimSize(tmpPDWave,1)/2) $tmpAVWaveName = NaN
	Wave tmpAVWave = $tmpAVWaveName
	sprintf tmpASWaveName, "AS_%s", StringFromList(mtIndex,mtNameList)
	make /O /N=(3,DimSize(tmpPDWave,1)/2) $tmpASWaveName = NaN
	Wave tmpASWave = $tmpASWaveName
	
	//	Calculate the average Z, Vh and Slope values and store them in appropriate waves
	for (n=0;n<DimSize(tmpAZWave,1);n+=1)
		if (DimSize(tmpPDWave,0) > 0)
			make /O /N=(DimSize(tmpPDWave,0)) tmpWave = tmpPDWave[p][n]
			WaveStats /Q tmpWave
			tmpAVWave[0][n] = V_avg
			tmpAVWave[1][n] = V_sdev
			tmpAVWave[2][n] = (V_sdev/sqrt(3))
			tmpString = GetDimLabel(tmpPDWave,1,n)
			tmpString = StringFromList(1,tmpString,"_")
			sprintf tmpString, "%dCa, %dMg", str2num(StringFromList(0,tmpString,":")), str2num(StringFromList(1,tmpString,":"))
			SetDimLabel 1,n,$tmpString, tmpAVWave
			tmpVar = DimSize(tmpPDWave,1)-DimSize(tmpAZWave,1)
			make /O /N=(DimSize(tmpPDWave,0)) tmpWave = tmpPDWave[p][n+tmpVar]
			WaveStats /Q tmpWave
			tmpASWave[0][n] = V_avg
			tmpASWave[1][n] = V_sdev
			tmpASWave[2][n] = (V_sdev/sqrt(3))
			tmpString = GetDimLabel(tmpPDWave,1,n+tmpVar)
			tmpString = StringFromList(1,tmpString,"_")
			sprintf tmpString, "%dCa, %dMg", str2num(StringFromList(0,tmpString,":")), str2num(StringFromList(1,tmpString,":"))
			SetDimLabel 1,(n),$tmpString, tmpASWave
			make /O /N=(DimSize(tmpPDWave,0)) tmpWave = 25.5*tmpPDWave[p][n]/tmpPDWave[p][n+tmpVar]
			WaveStats /Q tmpWave
			tmpAZWave[0][n] = V_avg
			tmpAZWave[1][n] = V_sdev
			tmpAZWave[2][n] = (V_sdev/sqrt(3))
			tmpString = GetDimLabel(tmpPDWave,1,n)
			tmpString = StringFromList(1,tmpString,"_")
			sprintf tmpString, "%dCa, %dMg", str2num(StringFromList(0,tmpString,":")), str2num(StringFromList(1,tmpString,":"))
			SetDimLabel 1,n,$tmpString,tmpAZWave
		endif
	endfor
	
	//  Display the averaged Vh and Slope values
	sprintf tmpString, "Avg.\t"
	for (n=0;n<DimSize(tmpAVWave,1);n+=1)
		sprintf tmpString, "%s%*.*g\t", tmpString, 0,5,tmpAVWave[0][n]
	endfor
	sprintf tmpString, "%s\t ", tmpString
	for (n=0;n<DimSize(tmpASWave,1);n+=1)
		sprintf tmpString, "%s%*.*g\t", tmpString, 0,5,tmpASWave[0][n]
	endfor
	AppendText /N=rawspace tmpString
	sprintf tmpString, "\r\K(30464,30464,30464)%s", StringFromList(mtIndex, mtNameList)
	AppendText /N=rawspace tmpString
	
	TextBox /C /N=ddgspace /V=0
	flagDisplay = 1
	sprintf tmpString, "Button ToggleDisplay title=\"Show DG and DDG\""
	Execute tmpString
end

//	Function to create and display ddgspace textbox
//	Calculates dg and ddg values and creates waves to hold these values
//	Calculates wavestats on ddg values and saves them to ADD waves
Function SNCddgSpace()
	NVAR mtIndex = globalMtIndex
	NVAR flagDisplay = gflagDisplay
	SVAR mtNameList = globalMtNameList
	SVAR mtSolutionsList = globalMtSolutionsList
	SVAR ddgCaList = globalddgCaList
	SVAR ddgMgList = globalddgMgList
	String tmpString, tmpString2 = "", tmpDDWaveName, tmpPDWaveName, tmpADDWaveName
	Variable n, i, j, k, tmpVar
	
	TextBox /C /N=ddgspace /V=1 /A=LT /T=50 /Y=15 /F=0 "\\Z09"
	sprintf tmpPDWaveName, "PD_%s", StringFromList(mtIndex,mtNameList)
	sprintf tmpDDWaveName, "DD_%s", StringFromList(mtIndex,mtNameList)
	sprintf tmpADDWaveName, "ADD_%s", StringFromList(mtIndex,mtNameList)
	Wave tmpPDWave = $tmpPDWaveName
	make /O /N=(0,ItemsInList(StringFromList(mtIndex,mtSolutionsList),"_")+ItemsInList(ddgCaList)+ItemsInList(ddgMgList)) $tmpDDWaveName
	Wave tmpDDWave = $tmpDDWaveName
	make /O /N=(3,ItemsInList(ddgCaList)+ItemsInList(ddgMgList)) $tmpADDWaveName
	Wave tmpADDWave = $tmpADDWaveName
	Wave tmpWave
	
	//	Calculate the DG and DDG values and store them into tmpDDWave
	for (n=0;n<DimSize(tmpPDWave,0);n+=1)
		InsertPoints /M=0 DimSize(tmpDDWave,0),1,tmpDDWave
		for (i=0; i<(DimSize(tmpPDWave,1)/2);i+=1)
			if (tmpPDWave[n][i] < Inf)
				tmpDDWave[n][i] = (25.5*tmpPDWave[n][i]/tmpPDWave[n][i+dimsize(tmpPDWave,1)/2])*(1.602*10^-19)*(6.023*10^23)/(10^6)
			else
				tmpDDWave[n][i] = NaN
			endif
		endfor
		for (j=0; j<ItemsInList(ddgCaList); j+=1)
			tmpDDWave[n][j+i] = tmpDDWave[n][WhichListItem(StringFromList(0,StringFromList(j,ddgCaList),"_"),StringFromList(mtIndex,mtSolutionsList),"_")] - tmpDDWave[n][WhichListItem(StringFromList(1,StringFromList(j,ddgCaList),"_"),StringFromList(mtIndex,mtSolutionsList),"_")]
			//printf "\r\tStringFromList(j,ddgCaList)=[%s]", StringFromList(j,ddgCaList)
			//printf "\r\tStringFromList(0,StringFromList(j,ddgCaList)\"_\")=[%s]", StringFromList(0,StringFromList(j,ddgCaList),"_")
			//printf "\r\tWhichListItem(StringFromList(0,StringFromList(j,ddgCaList)\"_\"),mtSolutionsList)=[%d]", WhichListItem(StringFromList(0,StringFromList(j,ddgCaList),"_"), StringFromList(mtIndex,mtSolutionsList),"_")
			//printf "\r\tWhichListItem(StringFromList(1,StringFromList(j,ddgCaList)\"_\"),mtSolutionsList)=[%d]", WhichListItem(StringFromList(1,StringFromList(j,ddgCaList),"_"),mtSolutionsList)
			//printf "\rn=[%d], j=[%d], value=%g",n,j, tmpDDWave[n][WhichListItem(StringFromList(0,StringFromList(j,ddgCaList)),mtSolutionsList)] - tmpDDWave[n][WhichListItem(StringFromList(1,StringFromList(j,ddgCaList)),mtSolutionsList)]
		endfor
		for (k=0;k<ItemsInList(ddgMgList);k+=1)
			tmpDDWave[n][k+j+i] = tmpDDWave[n][WhichListItem(StringFromList(0,StringFromList(k,ddgMgList),"_"),StringFromList(mtIndex,mtSolutionsList),"_")] - tmpDDWave[n][WhichListItem(StringFromList(1,StringFromList(k,ddgMgList),"_"),StringFromList(mtIndex,mtSolutionsList),"_")]
		endfor
	endfor

	//	Read the contents of tmpDDWave and display them in ddgspace textbox
	for (n=0; n<DimSize(tmpDDWave,0); n+=1)
		sprintf tmpString, "%d", n+1
		sprintf tmpString2, "\\K(%d,%d,%d) \t  \t", 1,1,1
		for (i=0; i<DimSize(tmpDDWave,1); i+=1)
			sprintf tmpString, "%s\t\\K(%d,%d,%d)%*.*g", tmpString, n,n,n, 0,5,tmpDDWave[n][i]
			sprintf tmpString2, "%s\t     ", tmpString2
			if ( (i+1) == (DimSize(tmpPDWave,1)/2) )
				sprintf tmpString, "%s\t", tmpString
				sprintf tmpString2, "%s\t .", tmpString2
			endif
		endfor
		sprintf tmpString, "%s\\K(0,0,0)", tmpString
		sprintf tmpString2, "%s\\L1400", tmpString2
		AppendText /N=ddgspace tmpString
	endfor

	//	Calculate, display and store the average and sdev ddg values
	AppendText /N=ddgspace tmpString2
	for (i=0; i<ItemsInList(ddgCaList); i+=1)
		sprintf tmpString, "Ca at %s Mg", StringFromList(1,StringFromList(0,StringFromList(i,ddgCaList),"_"),":")
		SetDimLabel 1,i,$tmpString, tmpADDWave
		//tmpADDWave[0][i] = tmpString
	endfor
	for (j=0; j<ItemsInList(ddgMgList); j+=1)
		sprintf tmpString, "Mg at %s Ca", StringFromList(0,StringFromList(0,StringFromList(j,ddgMgList),"_"),":")
		SetDimLabel 1,(j+i),$tmpString, tmpADDWave
		//tmpADDWave[0][j+i] = tmpString
	endfor
	sprintf tmpString, "Avg."
	for (i=0;i<(DimSize(tmpDDWave,1)-DimSize(tmpADDWave,1)+2);i+=1)
		sprintf tmpString, "%s\t ", tmpString
	endfor
	for (n=0;n<DimSize(tmpADDWave,1);n+=1)
		if (DimSize(tmpDDWave,0) > 0)
			make /O /N=(DimSize(tmpDDWave,0)) tmpWave = tmpDDWave[p][n+DimSize(tmpDDWave,1)-DimSize(tmpADDWave,1)]
			WaveStats /Q tmpWave
			tmpADDWave[0][n] = V_avg
			tmpADDWave[1][n] = V_sdev
			tmpADDWave[2][n] = (V_sdev/sqrt(3))
			sprintf tmpString, "%s%*.*g\t", tmpString, 0,5,tmpADDWave[0][n]
		else
			sprintf tmpString, "%sNaN\t", tmpString
		endif
	endfor
	killwaves tmpWave
	AppendText /N=ddgspace tmpString
	sprintf tmpString, "\r\K(30464,30464,30464)%s", StringFromList(mtIndex, mtNameList)
	AppendText /N=ddgspace tmpString
	
	TextBox /C /N=rawspace /V=0
	flagDisplay = -1
	sprintf tmpString, "Button ToggleDisplay title=\"Show V_h and Slope\""
	Execute tmpString
end

//	Function to display input dialogues for V_half and Slope values
Function SNCInputDialogues()
	SVAR mtSolutionsList = globalMtSolutionsList
	SVAR mtNameList = globalMtNameList
	NVAR mtIndex = globalMtIndex
	
	String tmpString, tmpSolutionsList
	Variable i, tmpVar
	
	tmpSolutionsList = StringFromList(mtIndex,mtSolutionsList)
	tmpVar = ItemsInList(tmpSolutionsList,"_")
	Make /O /N=(2*tmpVar) tmpIDWave = NaN
	for (i=0; i<10; i+=1)
		sprintf tmpString, "KillControl setvar%da", i
		Execute tmpString
		sprintf tmpString, "KillControl setvar%db", i
		Execute tmpString
		sprintf tmpString, "KillControl setvar%dTitle", i
		Execute tmpString
	endfor
	for (i=0;i<tmpVar;i+=1)
		sprintf tmpString, "SetVariable setvar%da bodyWidth=80, size={100,30}, limits={-Inf,Inf,0}, font=\"Verdana\", fsize=10, frame=1, pos={%d,100}, title=\" \", value=tmpIDWave[%d], proc=SNCCheckSetVar", i, 175+100*i, i
		Execute tmpString
		sprintf tmpString, "SetVariable setvar%db bodyWidth=80, size={100,30}, limits={-Inf,Inf,0}, font=\"Verdana\", fsize=10, frame=1, pos={%d,130}, title=\" \", value=tmpIDWave[%d], proc=SNCCheckSetVar", i, 175+100*i, tmpVar+i
		Execute tmpString
		sprintf tmpString, "TitleBox setvar%dTitle frame=0, size={100,30}, pos={%d,75}, title=\"%sCa, %sMg\"", i, 200+100*i, StringFromList(0,StringFromList(i,tmpSolutionsList,"_"),":"), StringFromList(1,StringFromList(i,tmpSolutionsList,"_"),":")
		Execute tmpString
	endfor
	sprintf tmpString, "TitleBox VhTitle disable=0"
	Execute tmpString
	sprintf tmpString, "TitleBox SlopeTitle disable=0"
	Execute tmpString
end

//	Function to check if user-entered values are valid to be added to raw patch data wave
//	Also change Igor's interpretation of user-inputed "NaN" values to actual NaN values instead of -Inf
Function SNCCheckSetVar(ctrlName,varNum,varStr,varName) : SetVariableControl
	String ctrlName
	Variable varNum	// value of variable as number
	String varStr		// value of variable as string
	String varName	// name of variable
	
	NVAR flagReadyToAdd = gflagReadyToAdd
	Variable i
	String tmpWaveName = "tmpIDWave", tmpString
	Wave tmpWave = $tmpWaveName
	
	for (i=0; i<numpnts(tmpWave); i+=1)
		if (tmpWave[i]==-Inf)
			printf "woohahaha i am the king orange peel yoooo\r"
			tmpWave[i] = NaN
			//ControlUpdate 
		endif
	endfor
	for (i=0; i<(numpnts(tmpWave)/2);i+=1)
		if ( (tmpWave[i]<Inf) && (tmpWave[i+numpnts(tmpWave)/2]<Inf) )
			flagReadyToAdd = 0
		endif
		if ( (!(tmpWave[i]<Inf) && (tmpWave[i+numpnts(tmpWave)/2]<Inf)) || ((tmpWave[i]<Inf) && !(tmpWave[i+numpnts(tmpWave)/2]<Inf)) )
			flagReadyToAdd = 2
			break
		endif
	endfor
	sprintf tmpString, "Button AddData disable=gflagReadyToAdd"
	Execute tmpString
end

//	Function to save current raw patch data to a file
Function SNCSaveFile(ctrlName) : ButtonControl
	String ctrlName

	SVAR mtNameList = globalMtNameList
	SVAR mtNumberList = globalMtNumberList
	SVAR mtSolutionsList = globalMtSolutionsList
	SVAR mtIndex = globalMtIndex
	SVAR path = globalPath
	SVAR titlePath = globalTitle
	NVAR flagNewData = gflagNewData
	NVAR flagFileLoaded = gflagFileLoaded
	String message, tmpWaveName, tmpString, sfileName
	Variable refNum, n, i, j
	
	sprintf message, "Select file to save for "
	for (i=0; i<(ItemsInList(mtNameList)-1); i+=1)
		sprintf message, "%s, ", StringFromList(i,mtNameList)
	endfor
	if (i == 0)
		sprintf message, "%s.", StringFromList(i,mtNameList)
	else
		sprintf message, "and %s.", StringFromList(i,mtNameList)
	endif
	Open/Z=2/M=message refNum
	if (V_flag != 0)
		return 0
	endif
	sfileName = S_fileName
	path = S_fileName
	//  Extract filename from S_fileName
	do
		i = strsearch(sfileName," ",0)
		if (i != -1)
			sfileName[i,i] = "_"
		endif
	while (i != -1)
	sfileName = StringFromList((ItemsInList(sfileName,":")-1),sfileName,":")
	//  Convert path into a Windows directory format string
	i = strsearch(path,":",0)
	path[i,i] = ":\\"
	do
		i = strsearch(path,":",i+1)
		if (i != -1)
			path[i,i] = "\\"
		endif
	while (i != -1)
	//  Convert titlePath into a Windows directory format string that can be read by the Igor TitleBox function
	titlePath = path
	i = 0
	do
		i = strsearch(titlePath,"\\",i+1)
		if (i != -1)
			titlepath[i,i] = "\\\\"
			i+=1
		endif
	while (i != -1)
	printf "titlePath=%s\r",titlepath
	
	fprintf refNum, "# Auto-generated SNCRawPatchDataFile created on %s at %s.  \n# For more info, visit http://igor.qiguang.net\n\n", date(), time()
	fprintf refNum, "filetype\tsncpatchdata\n\n"
	for (n=0;n<ItemsInList(mtNameList);n+=1)
		fprintf refNum, "mtInfo\tname=%s\tnumber=%s\tsolutions=[%s]\n", StringFromList(n,mtNameList), StringFromList(n,mtNumberList), StringFromList(n,mtSolutionsList)
		sprintf tmpWaveName, "PD_%s", StringFromList(n,mtNameList)
		Wave tmpWave = $tmpWaveName
		for (i=0;i<DimSize(tmpWave,0);i+=1)
			for (j=0;j<DimSize(tmpWave,1);j+=1)
				fprintf refNum, "%g\t", tmpWave[i][j]
			endfor
			fprintf refNum, "\n"
		endfor
		fprintf refNum, "\\mtinfo\n\n"
	endfor
	fprintf refNum, "# End of file\n"
	close refNum
	
	Printf "Patch data saved to \"%s\"\r", path
	flagFileLoaded = 0
	sprintf titlePath, "\t%s\t ", titlePath
	ControlUpdate /A
	flagNewData = 2
	sprintf tmpString, "Button SaveFile disable=gflagNewData"
	Execute tmpString
end 

//	Function to create a new mutant in current project
//	Creates a new control panel for user to input new mutant name, number and solutions, and stores these strings in global mutant lists
Function SNCNewMutant(ctrlName) : ButtonControl
	String ctrlName
	
	SVAR newName = globalNewName
	SVAR newNumber = globalNewNumber
	SVAR newSolutions = globalNewSolutions
	String tmpString
	Variable i
	
	newName = ""
	newNumber = ""
	newSolutions = "0:0_0:10_100:0_100:10"
	
	sprintf tmpString, "Button NMOK disable=2, pos={250,160}, size={60,20}, title=\"OK\", proc=SNCNMOK"
	Execute tmpString
	sprintf tmpString, "Button NMCancel disable=0, pos={358,160}, size={60,20}, title=\"Cancel\", proc=SNCNMCancel"
	Execute tmpString
	
	tmpString = "TitleBox NewMutantTitle frame=0, pos={250,60}, size={200,40}, title=\"\\F'Verdana'\\Z12\\JL Enter Information for new mutant:\"" 
	Execute tmpString
	sprintf tmpString, "SetVariable setvarNewName bodyWidth=60, size={90,25}, font=\"Verdana\", fsize=10, frame=1, pos={220,80}, title=\"Name\", value=globalNewName, proc=SNCCheckNMName, activate"
	Execute tmpString
	sprintf tmpString, "SetVariable setvarNewNumber bodyWidth=40, size={70,25}, font=\"Verdana\", fsize=10, frame=1, pos={220,105}, title=\"Number\", value=globalNewNumber, noproc"
	Execute tmpString
	sprintf tmpString, "SetVariable setvarNewSolutions bodyWidth=170, size={200,25}, font=\"Verdana\", fsize=10, frame=1, pos={220,130}, title=\"Solutions\", value=globalNewSolutions, noproc"
	Execute tmpString
	sprintf tmpString, "TitleBox setvarNewNameDesc frame=0, pos={320,80}, size={200,25}, title=\"\\F'Verdana'\\Z10\\JL Mandatory mutant name, i.e. E323A\""
	Execute tmpString
	sprintf tmpString, "TitleBox setvarNewNumberDesc frame=0, pos={300,105}, size={200,25}, title=\"\\F'Verdana'\\Z10\\JL Optional mutant number, i.e. 62\""
	Execute tmpString
	sprintf tmpString, "TitleBox setvarNewSolutionsDesc1 frame=0, pos={430,125}, size={200,20}, title=\"\\F'Verdana'\\Z10\\JL Format = Ca:Mg_Ca:Mg_Ca:Mg_Ca:Mg\""
	Execute tmpString
	sprintf tmpString, "TitleBox setvarNewSolutionsDesc2 frame=0, pos={430,138}, size={200,20}, title=\"\\F'Verdana'\\Z10\\JL If blank, defaults to 0:0_0:10_100:0_100:10\""
	Execute tmpString
	
	sprintf tmpString, "Button NewMutant disable=2"
	Execute tmpString
	sprintf tmpString, "Button LoadFile disable=2"
	Execute tmpString
	sprintf tmpString, "Button EditFile disable=2"
	Execute tmpString
	sprintf tmpString, "Button SaveFile disable=2"
	Execute tmpString
	sprintf tmpString, "Button AddData disable=1"
	Execute tmpString
	sprintf tmpString, "PopupMenu mtSelect disable=2"
	Execute tmpString
	
	for (i=0; i<10; i+=1)
		sprintf tmpString, "KillControl setvar%da", i
		Execute tmpString
		sprintf tmpString, "KillControl setvar%db", i
		Execute tmpString
		sprintf tmpString, "KillControl setvar%dTitle", i
		Execute tmpString
	endfor
	sprintf tmpString, "TitleBox VhTitle disable=1"
	Execute tmpString
	sprintf tmpString, "TitleBox SlopeTitle disable=1"
	Execute tmpString
	
	sprintf tmpString, "Button ToggleDisplay disable=2"
	Execute tmpString
	sprintf tmpString, "Button CreateDDGGraphs disable=2"
	Execute tmpString
	sprintf tmpString, "Button CreateOtherGraphs disable=2"
	Execute tmpString
	sprintf tmpString, "Button EditPDWave disable=2"
	Execute tmpString
end

//	Function to handle case when user presses "OK" after calling SNCNewMutant
Function SNCNMOK(ctrlName) : ButtonControl
	String ctrlName

	SVAR newName = globalNewName
	SVAR newNumber = globalNewNumber
	SVAR newSolutions = globalNewSolutions
	SVAR mtNameList = globalMtNameList
	SVAR mtNumberList = globalMtNumberList
	SVAR mtSolutionsList = globalMtSolutionsList
	NVAR mtIndex = globalMtIndex
	String tmpString, tmpString2, tmpWaveName
	Variable i, j, a, b, tmpVar1, tmpVar2, err = 0
	
	// 	Check for mutant name errors
	if (WhichListItem(LowerStr(newName), LowerStr(mtNameList)) != -1)
		sprintf tmpString, "The mutant name already exists in the currently loaded file."
		sprintf tmpString, "%s\rTo append patch data, click CANCEL and select the mutant name from the dropdown menu at the top.", tmpString
		sprintf tmpString, "%s\rOtherwise, either enter a new name or start a new session.", tmpString 
		Beep
		DoAlert 0, tmpString
		return 0
	endif
	
	//	Check for mutant solution errors
	if (cmpstr(newSolutions,"") == 0)
		newSolutions = "0:0_0:10_100:0_100:10"
	endif
	i = ItemsInList(newSolutions,"_")
	if (i<2)
		err = 1
	else
		for (j=0;j<i;j+=1)
			sscanf StringFromList(j,newSolutions,"_"), "%d:%d", a, b
			if (V_flag != 2)
				err = 1
			endif
		endfor
	endif
	if (err == 1)
		Beep
		DoAlert 0, "Your entry for [Solutions] is INVALID.\rPlease check and fix your entry."
		sprintf tmpString, "SetVariable setvarNewSolutions activate"
		Execute tmpString
		return 0
	endif
	
	//	Add mutant info to mutant lists and create multidimensional mutant patch data wave
	mtNameList = AddListItem(newName, mtNameList, ";", Inf)
	if (cmpstr(newNumber,"") == 0)
		newNumber = "NaN"
	endif
	mtNumberList = AddListItem(newNumber, mtNumberList, ";", Inf)
	mtSolutionsList = AddListItem(newSolutions, mtSolutionsList, ";", Inf)
	sprintf tmpWaveName, "PD_%s", newName
	make /N=(0,ItemsInList(newSolutions,"_")*2 ) /O $tmpWaveName
	Wave tmpWave = $tmpWaveName
	for (i=0;i<ItemsInList(newSolutions,"_");i+=1)
		sprintf tmpString, "Vh_%s", StringFromList(i,newSolutions,"_")
		SetDimLabel 1, i, $tmpString, $tmpWaveName
		sprintf tmpString, "Slope_%s", StringFromList(i,newSolutions,"_")
		SetDimLabel 1, i+ItemsInList(newSolutions,"_"), $tmpString, $tmpWaveName
	endfor

	//	Restore window GUI
	sprintf tmpString, "KillControl NewMutantTitle"
	Execute tmpString
	sprintf tmpString, "KillControl setvarNewName"
	Execute tmpString
	sprintf tmpString, "KillControl setvarNewNumber"
	Execute tmpString
	sprintf tmpString, "KillControl setvarNewSolutions"
	Execute tmpString
	sprintf tmpString, "KillControl setVarNewNameDesc"
	Execute tmpString
	sprintf tmpString, "KillControl setVarNewNumberDesc"
	Execute tmpString
	sprintf tmpString, "KillControl setVarNewSolutionsDesc1"
	Execute tmpString
	sprintf tmpString, "KillControl setVarNewSolutionsDesc2"
	Execute tmpString
	
	sprintf tmpString, "Button NewMutant disable=0"
	Execute tmpString
	sprintf tmpString, "Button LoadFile disable=gflagLoadFile"
	Execute tmpString
	sprintf tmpString, "Button EditFile disable=gflagFileLoaded"
	Execute tmpString
	sprintf tmpString, "Button SaveFile disable=gflagNewData"
	Execute tmpString
	sprintf tmpString, "Button AddData disable=gflagReadyToAdd"
	Execute tmpString
	sprintf tmpString, "PopupMenu mtSelect disable=0"
	Execute tmpString
	sprintf tmpString, "Button ToggleDisplay disable=0"
	Execute tmpString
	
	sprintf tmpString, "KillControl NMOK"
	Execute tmpString
	sprintf tmpString, "KillControl NMCancel"
	Execute tmpString
	
	mtIndex = ItemsInList(mtNameList) - 1
	ControlUpdate mtSelect

	SNCGetDDGLists()
	SNCddgMenu()
	SNCddgSpace()
	SNCRawMenu()
	SNCRawSpace()
	
	sprintf tmpString, "Button AddData help={\"Add patch data above to current patch data wave  (PD_%s).\"}, title=\"Add above values to current patch data wave  (PD_%s)\"", StringFromList(mtIndex,mtNameList), StringFromList(mtIndex,mtNameList)
	Execute tmpString
	sprintf tmpString, "Button EditPDWave disable=0, title=\"Edit PD_\"+StringFromList(globalMtIndex,globalMtNameList)+\" Wave\""
	Execute tmpString
	sprintf tmpString, "Button ToggleDisplay disable=0"
	Execute tmpString
	
	sprintf tmpString, "Button ToggleDisplay disable=0"
	Execute tmpString
	sprintf tmpString, "Button CreateDDGGraphs disable=0"
	Execute tmpString
	sprintf tmpString, "Button CreateOtherGraphs disable=0"
	Execute tmpString
	sprintf tmpString, "Button EditPDWave disable=0"
	Execute tmpString
	
	sprintf tmpString, "PopupMenu mtSelect mode=1, popvalue=\"%s\"", newName
	Execute tmpString
	SNCInputDialogues()
end

//	Function to handle case when user presses "Cancel" after calling SNCNewMutant
Function SNCNMCancel(ctrlName) : ButtonControl
	String ctrlName

	NVAR flagFileLoaded = gflagFileLoaded
	String tmpString
	
	sprintf tmpString, "KillControl NewMutantTitle"
	Execute tmpString
	sprintf tmpString, "KillControl setvarNewName"
	Execute tmpString
	sprintf tmpString, "KillControl setvarNewNumber"
	Execute tmpString
	sprintf tmpString, "KillControl setvarNewSolutions"
	Execute tmpString
	sprintf tmpString, "KillControl setVarNewNameDesc"
	Execute tmpString
	sprintf tmpString, "KillControl setVarNewNumberDesc"
	Execute tmpString
	sprintf tmpString, "KillControl setVarNewSolutionsDesc1"
	Execute tmpString
	sprintf tmpString, "KillControl setVarNewSolutionsDesc2"
	Execute tmpString
	
	sprintf tmpString, "Button NewMutant disable=0"
	Execute tmpString
	sprintf tmpString, "Button LoadFile disable=gflagLoadFile"
	Execute tmpString
	sprintf tmpString, "Button EditFile disable=gflagFileLoaded"
	Execute tmpString
	sprintf tmpString, "Button SaveFile disable=gflagNewData"
	Execute tmpString
	sprintf tmpString, "Button AddData disable=gflagReadyToAdd"
	Execute tmpString
	sprintf tmpString, "PopupMenu mtSelect disable=0"
	Execute tmpString
	sprintf tmpString, "Button ToggleDisplay disable=0"
	Execute tmpString
	
	if (flagFileLoaded == 0)
		SNCInputDialogues()
	endif
	
	sprintf tmpString, "KillControl NMOK"
	Execute tmpString
	sprintf tmpString, "KillControl NMCancel"
	Execute tmpString
	
	sprintf tmpString, "Button ToggleDisplay disable=0"
	Execute tmpString
	sprintf tmpString, "Button CreateDDGGraphs disable=0"
	Execute tmpString
	sprintf tmpString, "Button CreateOtherGraphs disable=0"
	Execute tmpString
	sprintf tmpString, "Button EditPDWave disable=0"
	Execute tmpString
end

//	Function to check setvarNewName from SNCNewMutant
Function SNCCheckNMName(ctrlName,varNum,varStr,varName) : SetVariableControl
	String ctrlName
	Variable varNum	// value of variable as number
	String varStr		// value of variable as string
	String varName	// name of variable
	
	String tmpString
	
	printf "varStr=[%s]",varstr
	if (!cmpstr(varStr,""))
		sprintf tmpString, "Button NMOK disable=2"
	else
		sprintf tmpString, "Button NMOK disable=0"
	endif
	Execute tmpString
end

//	Function to add new data to currently selected mutant raw patch data file
Function SNCAddData(ctrlName) : ButtonControl
	String ctrlName

	SVAR mtNameList = globalMtNameList
	SVAR mtSolutionsList = globalMtSolutionsList
	NVAR mtIndex = globalMtIndex
	NVAR flagNewData = gflagNewData
	String tmpWaveName, tmpString
	Variable i
	Wave tmpIDWave 
	
	sprintf tmpWaveName, "PD_%s", StringFromList(mtIndex,mtNameList)
	Wave tmpWave = $tmpWaveName
	InsertPoints /M=0 DimSize(tmpWave,0), 1, tmpWave
	for (i=0; i<(ItemsInList(StringFromList(mtIndex,mtSolutionsList),"_")*2); i+=1)
		tmpWave[DimSize(tmpWave,0)-1][i] = tmpIDWave[i]
	endfor
	tmpIDWave = NaN
	SNCddgSpace()
	SNCRawMenu()
	SNCRawSpace()
	flagNewData = 0
	sprintf tmpString, "Button SaveFile disable=gflagNewData"
	Execute tmpString
	//	The below commands have been commented out because in retrospect they might confuse the user.
	//	sprintf tmpString, "Button AddData disable=2"
	//	Execute tmpString
	SNCInputDialogues()
end

//	Function to toggle display between raw patch data and calculated ddg values
Function SNCToggleDisplay(ctrlName) : ButtonControl
	String ctrlName
	
	NVAR flagDisplay = gflagDisplay
	String tmpString, tmpList = "Show V_h and Slope;Show DG and DDG"

	flagDisplay = -flagDisplay
	sprintf tmpString, "Button ToggleDisplay title=\"%s\"", StringFromList(0.5+0.5*flagDisplay,tmpList)
	Execute tmpString 
	TextBox /C /N=rawmenu /V=(0.5+0.5*flagDisplay)
	TextBox /C /N=rawspace /V=(0.5+0.5*flagDisplay)
	TextBox /C /N=ddgmenu /V=(0.5-0.5*flagDisplay)
	TextBox /C /N=ddgspace /V=(0.5-0.5*flagDisplay)
end

//	Function to create custom graphs from ddg data
Function SNCCreateGraphs(ctrlName) : ButtonControl
	String ctrlName
	
	SVAR mtNameList = globalMtNameList
	SVAR mtNumberList = globalMtNumberList
	SVAR mtSolutionsList = globalMtSolutionsList
	SVAR ddgCaList = globalddgCaList
	SVAR ddgMgList = globalddgMgList
	NVAR mtIndex = globalMtIndex
	NVAR cgDisplay = globalCGDisplay
	
	String tmpString, tmpString2, tmpList, tmpList2, tmpWaveName
	Wave cgNselWave, cgDselWave
	Wave /T cgNlistWave, cgDlistWave
	Variable i,n,tmpVar

	sprintf tmpString, "SNCCGGlobals()"
	Execute tmpString
	sprintf tmpString, "Button NewMutant disable=2"
	Execute tmpString
	sprintf tmpString, "Button LoadFile disable=2"
	Execute tmpString
	sprintf tmpString, "Button EditFile disable=2"
	Execute tmpString
	sprintf tmpString, "Button SaveFile disable=2"
	Execute tmpString
	sprintf tmpString, "Button AddData disable=1"
	Execute tmpString
	sprintf tmpString, "PopupMenu mtSelect disable=2"
	Execute tmpString
	sprintf tmpString, "Button toggleDisplay disable=2"
	Execute tmpString
	sprintf tmpString, "Button EditPDWave disable=2"
	Execute tmpString
	
	for (i=0; i<10; i+=1)
		sprintf tmpString, "KillControl setvar%da", i
		Execute tmpString
		sprintf tmpString, "KillControl setvar%db", i
		Execute tmpString
		sprintf tmpString, "KillControl setvar%dTitle", i
		Execute tmpString
	endfor
	sprintf tmpString, "TitleBox VhTitle disable=1"
	Execute tmpString
	sprintf tmpString, "TitleBox SlopeTitle disable=1"
	Execute tmpString
	
	sprintf tmpString, "Button CGOK disable=0, pos={580,160}, size={59,20}, title=\"Draw\", proc=SNCCGOK"
	Execute tmpString
	sprintf tmpString, "Button CGCancel disable=0, pos={642,160}, size={59,20}, title=\"Cancel\", proc=SNCCGCancel"
	Execute tmpString
	TitleBox CGWTSelectTitle disable=1, title="Select WT", frame=0, pos={580,115}, size={110,30}
	sprintf tmpString, "PopupMenu CGWTSelect disable=1, value=globalMtNameList, bodyWidth=70, pos={580,130}, size={70,20}, popvalue=globalWTName, font=\"Verdana\", fsize=8, help={\"Select WT for WT sensitive options\"}, mode=1, proc=SNCCGWTSelect, title=\"\""
	Execute tmpString
	sprintf tmpString, "PopupMenu CGWTColorMenu disable=1, pos={650,130}, size={20,20}, proc=SNCCGWTColorMenu, title=\"\", mode=1, popColor=(globalCGWTColorR,globalCGWTColorG,globalCGWTColorB), frame=0, value=\"*COLORPOP*\""
	Execute tmpString
	
	//  Create wave for mutant listbox items and mutant listbox selections
	make /O /N=(ItemsInList(mtNameList),1) cgNselWave = 0
	make /O /T /N=(ItemsInList(mtNameList),1) cgNlistWave
	SetDimLabel 1,0,Mutant, cgNlistWave
	tmpList = ""
	for (n=0; n<ItemsInList(mtNameList); n+=1)
		cgNlistWave[n] = StringFromList(n,mtNameList)
		sprintf tmpWaveName, "ADD_%s", StringFromList(n,mtNameList)
		Wave tmpWave = $tmpWaveName
		for (i=0;i<DimSize(tmpWave,1);i+=1)
			if(WhichListItem(GetDimLabel(tmpWave,1,i),tmpList) == -1)
				tmpList = AddListItem(GetDimLabel(tmpWave,1,i), tmpList,";",Inf)				// Create list of solutions for DDG graphs
			endif
		endfor
	endfor
	if (cmpstr(ctrlName, "CreateDDGGraphs") != 0)
		tmplist = ""
		tmplist2 = ""
		for (n=0; n<ItemsInList(mtSolutionsList); n+=1)
			tmpString = StringFromList(n,mtSolutionsList)
			for (i=0; i<ItemsInList(tmpString,"_"); i+=1)
				if (WhichListItem(StringFromList(i,tmpString,"_"),tmpList) == -1)
					tmpList = AddListItem(StringFromList(i,tmpString,"_"),tmpList,";",Inf)
					tmpString2 = StringFromList(i,tmpString,"_")
					sprintf tmpString2, "%dCa, %dMg", str2num(StringFromList(0,tmpString2,":")), str2num(StringFromList(1,tmpString2,":"))
					tmpList2 = AddListItem(tmpString2,tmpList2,";",Inf)
				endif
			endfor
		endfor
		tmplist = tmplist2
	endif
	make /O/N=(ItemsInList(tmpList),1) cgDselWave = 0
	make /O /T /N=(ItemsInList(tmpList),1) cgDlistWave
	if (cmpstr(ctrlName, "CreateDDGGraphs") == 0)
		sprintf tmpString, "Ion (DDG)"
	else
		sprintf tmpString, "Solution"
	endif
	SetDimLabel 1,0,$tmpString, cgDlistWave
	for (i=0;i<ItemsInList(tmpList);i+=1)
		cgDlistWave[i][0] = StringFromList(i,tmpList)
	endfor
	cgDselWave[0][0] = 1
	cgNselWave[0][0] = 1

	ListBox CGNameList disable=0, font="Verdana", fsize=8, frame=1, listWave=root:cgNlistWave, selWave=cgNselWave, mode=4, pos={150,65}, size={70,115}, proc=SNCCGNameListCheck
	ListBox CGDDGList disable=0, font="Verdana", fsize=8, frame=1, listWave=root:cgDlistWave, selWave=cgDselWave, mode=4, pos={230,65}, size={100,115}, proc=SNCCGDDGListCheck

	sprintf tmpString, "PopupMenu CGColorMenu disable=0, pos={328,64}, size={20,20}, proc=SNCCGColorMenu, title=\"\", mode=1, popColor=(globalCGColorR,globalCGColorG,globalCGColorB), frame=0, value=\"*COLORPOP*\""
	Execute tmpString
	Slider CGFillSlider disable=0, limits={0,4,1}, pos={370,85}, size={100,20}, ticks=0, vert=0, variable=globalFillValue
	TitleBox CGSliderTick0 disable=0, title="|", frame=0, pos={377,93}, size={5,5}
	TitleBox CGSliderTick1 disable=0, title="|", frame=0, pos={397,93}, size={5,5}
	TitleBox CGSliderTick2 disable=0, title="|", frame=0, pos={418,93}, size={5,5}
	TitleBox CGSliderTick3 disable=0, title="|", frame=0, pos={438,93}, size={5,5}
	TitleBox CGSliderTick4 disable=0, title="|", frame=0, pos={459,93}, size={5,5}
	
	CheckBox CGNewWindow disable=0, fsize=8, help={"Chose whether to display graph in current window (below) are new window"}, mode=0, pos={390,65}, value=0, variable=globalNewWindowFlag, noproc, title="New Window"
	CheckBox CGShowLegend disable=0, fsize=8, help={"Show legend in graph"}, mode=0, pos={485,65}, value=0, variable=globalShowLegendFlag, noproc, title="Show Legend"
	CheckBox CGShowSEM disable=0, fsize=8, help={"Show error bars for standard error of mean"}, mode=0, pos={485,80}, value=0, variable=globalShowSEMFlag, noproc, title="Show SEM"

	CheckBox CGWTBlack disable=0, fsize=8, help={"Color all WT graphs black"}, mode=0, pos={580,65}, value=0, variable=globalColorWTBlackFlag, proc=WTCheckBoxControl, title="Specify WT color"
	CheckBox CGWTDivide disable=0, fsize=8, help={"Divide all DDG values by WT DDG"}, mode=0, pos={580,80}, value=0, variable=globalDivideByWTFlag, proc=WTCheckBoxControl, title="Divide by WT"
	CheckBox CGWTSubtract disable=0, fsize=8, help={"Subtract all DDG values from WT DDG"}, mode=0, pos={580,95}, value=0, variable=globalSubtractWTFlag, proc=WTCheckBoxControl, title="Subtract WT"

	TitleBox CGAxisLabel disable=0, title="X-axis label:", frame=0, pos={340,110}, size={80,20}
	CheckBox CGAxisLabelMutant disable=0, fsize=8, help={"x-axis is mutant name"}, mode=0, pos={410,110}, value=1, proc=SNCCGAxisCheck, title="Mutant"
	CheckBox CGAxisLabelDDG disable=0, fsize=8, help={"x-axis is ion"}, mode=0, pos={493,110}, value=0, proc=SNCCGAxisCheck, title="Ion"
	
	TitleBox CGSortBy disable=0, title="Sort mutants:", frame=0, pos={340,130}, size={80,20}
	CheckBox CGSortSequence disable=0, fsize=8, help={"sort by mutant sequence"}, mode=0, pos={410,130}, value=1, proc=SNCCGSortCheck, title="Sequence"
	CheckBox CGSortNumber disable=0, fsize=8, help={"sort by mutant number"}, mode=0, pos={493,130}, value=0, proc=SNCCGSortCheck, title="Number"
	CheckBox CGSortMax disable=0, fsize=8, help={"sort by max value"}, mode=0, pos={410,145}, value=0, proc=SNCCGSortCheck, title="Descending"
	CheckBox CGSortMin disable=0, fsize=8, help={"sort by min value"}, mode=0, pos={493,145}, value=0, proc=SNCCGSortCheck, title="Ascending"
	
	if (cmpstr(ctrlName, "CreateOtherGraphs") == 0)
		TitleBox CGDisplayTitle disable=0, title="Display:", frame=0, pos={340,165}, size={80,20}
		CheckBox CGDisplayZ disable=0, fsize=8, help={"graph Z"}, mode=1, pos={410,165}, value=1, proc=SNCCGDisplaySelect, title="Z"
		CheckBox CGDisplayVh disable=0, fsize=8, help={"graph Vh"}, mode=1, pos={449,165}, value=0, proc=SNCCGDisplaySelect, title="Vh"
		CheckBox CGDisplaySlope disable=0, fsize=8, help={"graph Slope"}, mode=1, pos={493,165}, value=0, proc=SNCCGDisplaySelect, title="Slope"
	else
		sprintf tmpString, "KillControl CGDisplayTitle"
		Execute tmpString
		sprintf tmpString, "KillControl CGDisplayZ"
		Execute tmpString
		sprintf tmpString, "KillControl CGDisplayVh"
		Execute tmpString
		sprintf tmpString, "KillControl CGDisplaySlope"
		Execute tmpString
		cgDisplay = -1
	endif
	
	CheckBox CGNSelectAll disable=0, fsize=8, help={"select all mutants"}, mode=0, pos={148,181}, value=0, proc=SNCCGNSelectAll, title="Select All"
	CheckBox CGDSelectAll disable=0, fsize=8, help={"select all ions or solutions"}, mode=0, pos={230,181}, value=0, proc=SNCCGDSelectAll, title="Select All"
end

//	Function to select all mutants in Nlist
Function SNCCGNSelectAll(ctrlName,checked) : CheckBoxControl
	String ctrlName
	Variable checked
	
	String tmpNselWaveName = "cgNselWave"
	Wave tmpNselWave = $tmpNselWaveName

	tmpNselWave = checked
end

//	Function to select all ions or solutions in Dlist
Function SNCCGDSelectAll(ctrlName,checked) : CheckBoxControl
	String ctrlName
	Variable checked
	
	String tmpDselWaveName = "cgDselWave"
	Wave tmpDselWave = $tmpDselWaveName
	
	tmpDselWave = checked
end

//	Function to handle the CGDisplay checkboxes.
//	Only one option can be checked at any time
Function SNCCGDisplaySelect(ctrlName,checked) : CheckBoxControl
	String ctrlName
	Variable checked

	NVAR cgDisplay = globalCGDisplay
	
	strswitch (ctrlName)
		case "CGDisplayZ":
			cgDisplay = 0
			break
		case "CGDisplayVh":
			cgDisplay = 1
			break
		case "CGDisplaySlope":
			cgDisplay = 2
			break
	endswitch
	
	CheckBox CGDisplayZ, value=(cgDisplay==0)
	CheckBox CGDisplayVh, value=(cgDisplay==1)
	CheckBox CGDisplaySlope, value=(cgDisplay==2)
end
	
//	Function to display/hide "Select WT" popups
Function WTCheckBoxControl(ctrlName,checked) : CheckBoxControl
	String ctrlName
	Variable checked
	
	NVAR wtblack = globalColorWTBlackFlag
	NVAR wtdivide = globalDivideByWTFlag
	NVAR wtsubtract = globalSubtractWTFlag
	
	TitleBox CGWTSelectTitle disable=1
	PopupMenu CGWTSelect disable=1
	PopupMenu CGWTColorMenu disable=1
		
	if(wtblack == 1)
		TitleBox CGWTSelectTitle disable=0
		PopupMenu CGWTSelect disable=0
		PopupMenu CGWTColorMenu disable=0
	elseif((wtdivide == 1) || (wtsubtract == 1))
		TitleBox CGWTSelectTitle disable=0
		PopupMenu CGWTSelect disable=0
	endif

	strswitch (ctrlName)
		case "CGWTDivide":
			if (wtsubtract)
				wtsubtract=0
				CheckBox CGWTSubtract,value=0
			endif
			break
		case "CGWTSubtract":
			if (wtdivide)
				wtdivide=0
				CheckBox CGWTDivide,value=0
			endif
			break
	endswitch
end
	
//	Function to handle CGColorMenu popupmenu
Function SNCCGColorMenu(ctrlName,popNum,popStr) : PopupMenuControl
	String ctrlName
	Variable popNum
	String popStr

	NVAR colorR = globalCGColorR
	NVAR colorG = globalCGColorG
	NVAR colorB = globalCGColorB
	
	ControlInfo $ctrlName
	colorR = V_Red
	colorG = V_Green
	colorB = V_Blue
End

//	Function to handle CGWTColorMenu popupmenu
Function SNCCGWTColorMenu(ctrlName,popNum,popStr) : PopupMenuControl
	String ctrlName
	Variable popNum
	String popStr

	NVAR colorR = globalCGWTColorR
	NVAR colorG = globalCGWTColorG
	NVAR colorB = globalCGWTColorB
	
	ControlInfo $ctrlName
	colorR = V_Red
	colorG = V_Green
	colorB = V_Blue
End

//	Function to handle CGWTSelect popupmenu
Function SNCCGWTSelect (ctrlName,popNum,popStr) : PopupMenuControl
	String ctrlName
	Variable popNum	// which item is currently selected (1-based)
	String popStr		// contents of current popup item as string

	SVAR WTName = globalWTName
	sprintf WTName, "%s", popStr
End

//	Function to control Sort By checkboxes
Function SNCCGSortCheck(name,value)
	String name
	Variable value
	
	NVAR sortCheckVal= globalSortLabel
	
	strswitch (name)
		case "CGSortSequence":
			if (sortCheckVal == 0)
				sortCheckVal = -1
			else
				sortCheckVal= 0
			endif	
			break
		case "CGSortNumber":
			if (sortCheckVal == 1)
				sortCheckVal = -1
			else
				sortCheckVal= 1
			endif	
			break
		case "CGSortMax":
			if (sortCheckVal == 2)
				sortCheckVal = -1
			else
				sortCheckVal= 2
			endif	
			break
		case "CGSortMin":
			if (sortCheckVal == 3)
				sortCheckVal = -1
			else
				sortCheckVal= 3
			endif	
			break
	endswitch
	CheckBox CGSortSequence,value= sortCheckVal==0
	CheckBox CGSortNumber,value= sortCheckVal==1
	CheckBox CGSortMax,value= sortCheckVal==2
	CheckBox CGSortMin,value= sortCheckVal==3
End

//	Function to control X-Axis Label checkboxes
Function SNCCGAxisCheck(name,value)
	String name
	Variable value
	
	NVAR axisCheckVal= globalAxisLabel
	
	strswitch (name)
		case "CGAxisLabelMutant":
			axisCheckVal= 0
			TitleBox CGSortBy disable=0
			CheckBox CGSortSequence disable=0
			CheckBox CGSortNumber disable=0
			CheckBox CGSortMax disable=0
			CheckBox CGSortMin disable=0
			break
		case "CGAxisLabelDDG":
			axisCheckVal= 1
			TitleBox CGSortBy disable=2
			CheckBox CGSortSequence disable=2
			CheckBox CGSortNumber disable=2
			CheckBox CGSortMax disable=2
			CheckBox CGSortMin disable=2
			break
	endswitch
	CheckBox CGAxisLabelMutant,value= axisCheckVal==0
	CheckBox CGAxisLabelDDG,value= axisCheckVal==1
End

//	Function to call when user selects an Item from the CGNameList ListBox
//	On double click, main textbox is updated with DDG values of the mutant that was double clicked
Function SNCCGNameListCheck(ctrlName,row,col,event)
	String ctrlName     // name of this control
	Variable row        // row if click in interior, -1 if click in title
	Variable col        // column number
	Variable event      // event code
	
	NVAR mtIndex = globalMtIndex
	String tmpString
	Variable tmpMtIndex
	
	//printf "event=%d, row=%d, col=%d\r", event, row, col
	if (event == 3)
		tmpMtIndex = mtIndex
		mtIndex = row
		SNCGetDDGLists()
		SNCDDGMenu()
		SNCDDGSpace()
		mtIndex = tmpMtIndex
	endif
end

//	Function to call when user selects an Item from the CGDDGList ListBox
Function SNCCGDDGListCheck(ctrlName,row,col,event)
	String ctrlName     // name of this control
	Variable row        // row if click in interior, -1 if click in title
	Variable col        // column number
	Variable event      // event code
	
end

//	Function to handle CGOK button
Function SNCCGOK(ctrlName) : ButtonControl
	String ctrlName
	
	SVAR mtNameList = globalMtNameList
	SVAR mtNumberList = globalMtNumberList
	SVAR wtName = globalWTName
	NVAR maxAxis = globalMaxAxis
	NVAR minAxis = globalMinAxis
	NVAR AxisLabel = globalAxisLabel
	NVAR SortLabel = globalSortLabel
	NVAR newWindowFlag = globalNewWindowFlag
	NVAR showValuesFlag = globalShowValuesFlag
	NVAR divideByWTFlag = globalDivideByWTFlag
	NVAR subtractWTFlag = globalSubtractWTFlag
	NVAR stackGroupsFlag = globalStackGroupsFlag
	NVAR colorWTBlackFlag = globalColorWTBlackFlag
	NVAR showLegendFlag = globalShowLegendFlag
	NVAR showSEMFlag = globalShowSEMFlag
	NVAR colorR = globalCGColorR
	NVAR colorG = globalCGColorG
	NVAR colorB = globalCGColorB
	NVAR wtcolorR = globalCGWTColorR
	NVAR wtcolorG = globalCGWTColorG
	NVAR wtcolorB = globalCGWTColorB
	NVAR cgDisplay = globalCGDisplay
	NVAR fillValue = globalFillValue
	String tmpString, tmpString2, tmpNselWaveName, tmpDselWaveName, tmpDlistWaveName, tmpNlistWaveName, tmpWaveName, tmpWaveName2, tmpWaveName3, tmpADDWaveName, tmpList
	String catY_WaveList = "", catY_Dlist = "", catY_Nlist="", catY_GraphList = "", cat_DisplayCmd = "", cat_Options = "", catY_WT_GraphList = ""
	Variable n,i,j,tmpVar, tmpVar1, tmpVar2
	Wave /T catX_Units
	
	tmpNselWaveName = "cgNselWave"
	tmpNlistWaveName = "cgNlistWave"
	tmpDselWaveName = "cgDselWave"
	tmpDlistWaveName = "cgDlistWave"
	Wave tmpNselWave = $tmpNselWaveName
	Wave tmpDselWave = $tmpDselWaveName
	Wave /T tmpNlistWave = $tmpNlistWaveName
	Wave /T tmpDlistWave = $tmpDlistWaveName
	Make /O /T /N=0 catX_Units
	
	//  Make catY waves depending on whether user selected to have mutant or ion be on the x-Axis label
	//  If user chose mutant to be the x-Axis label, then create catY waves based on DDG Ion values
	//  If user chose DDG Ion to be the x-Axis label, then create catY waves based on mutant names
	if (axisLabel)			
		for (i=0; i<DimSize(tmpNselWave,0); i+=1)			//  Get list of Mutant Name labels and make waves for each one
			if (tmpNselWave[i] == 1)
				tmpString = tmpNlistWave[i][0]
				n=0
				do
					n = strsearch(tmpString," ",n)
					if (n != -1)
						tmpString[n,n] = "_"
					endif
				while (n != -1)
				n=0
				do
					n = strsearch(tmpString,",",n)
					if (n != -1)
						tmpString[n,n] = "_"
					endif
				while (n != -1)
				catY_Nlist = AddListItem(tmpNlistWave[i][0], catY_Nlist, ";", ItemsInList(catY_Nlist))
				catY_WaveList = AddListItem(tmpString, catY_WaveList, ";", ItemsInList(catY_WaveList))
				sprintf tmpWaveName, "catY_%s", tmpString
				make /O /N=0 $tmpWaveName
				Wave tmpWave = $tmpWaveName
				sprintf tmpWaveName, "%s_sem", tmpWaveName
				make /O /N=0 $tmpWaveName
			endif
		endfor
	else
		for (i=0; i<DimSize(tmpDselWave,0); i+=1)			//  Get list of DDG labels and make waves for each one
			if (tmpDselWave[i] == 1)
				tmpString = tmpDlistWave[i][0]
				n=0
				do
					n = strsearch(tmpString," ",n)
					if (n != -1)
						tmpString[n,n] = "_"
					endif
				while (n != -1)
				n=0
				do
					n = strsearch(tmpString,",",n)
					if (n != -1)
						tmpString[n,n] = "_"
					endif
				while (n != -1)
				sprintf tmpWaveName, "catY_%s", tmpString
				catY_Dlist = AddListItem(tmpDlistWave[i][0], catY_Dlist, ";", ItemsInList(catY_Dlist))
				catY_WaveList = AddListItem(tmpString, catY_WaveList, ";", ItemsInList(catY_WaveList))
				make /O /N=0 $tmpWaveName
				Wave tmpWave = $tmpWaveName
				sprintf tmpWaveName, "%s_sem", tmpWaveName
				make /O /N=0 $tmpWaveName
			endif
		endfor
	endif
	
	n=0
	//  Get a list of the x-units and store them into catX_Units
	//  Also store catY values into catY waves
	if (axisLabel)
		for (i=0; i<DimSize(tmpDselWave,0); i+=1)
			if (tmpDselWave[i][0] == 1)									// Add string to catX_Units wave
				InsertPoints /M=0 numpnts(catX_Units), 1, catX_Units
				catX_Units[n] = tmpDlistWave[i][0]
				for (j=0; j<ItemsInList(catY_WaveList); j+=1)				//  Store the DDG values for current x-unit into the catY (mutant name) waves
					if (cgDisplay == -1)
						sprintf tmpADDWaveName, "ADD_%s", StringFromList(j,catY_Nlist)		// use average ddg waves
					elseif (cgDisplay == 0)
						sprintf tmpADDWaveName, "AZ_%s", StringFromList(j,catY_Nlist)			// use average z waves
					elseif (cgDisplay == 1)
						sprintf tmpADDWaveName, "AV_%s", StringFromList(j,catY_Nlist)			// use average vh waves
					elseif (cgDisplay == 2)
						sprintf tmpADDWaveName, "AS_%s", StringFromList(j,catY_Nlist)			// use average slope waves
					endif
					Wave tmpADDWave = $tmpADDWaveName
					sprintf tmpWaveName, "catY_%s", StringFromList(j,catY_WaveList)
					Wave tmpWave = $tmpWaveName 
					InsertPoints /M=0 numpnts(tmpWave), 1, tmpWave
					sprintf tmpWaveName2, "%s_sem", tmpWaveName		// Store sem values
					Wave tmpWave2 = $tmpWaveName2
					InsertPoints /M=0 numpnts(tmpWave), 1, tmpWave2
					tmpVar = FindDimLabel(tmpADDWave, 1, tmpDlistWave[i][0])
					if (tmpVar >= 0)
						tmpWave[n] = tmpADDWave[0][tmpVar]
						tmpWave2[n] = tmpADDWave[2][tmpVar]
					else
						tmpWave[n] = NaN
						tmpWave2[n] = NaN
					endif
				endfor
				n+=1		
			endif
		endfor
	else	
		for (i=0; i<DimSize(tmpNselWave,0); i+=1)
			if (tmpNselWave[i][0] == 1)									// Add string to catX_Units wave
				InsertPoints /M=0 numpnts(catX_Units), 1, catX_Units
				catX_Units[n] = tmpNlistWave[i][0]
				if (cgDisplay == -1)
					sprintf tmpADDWaveName, "ADD_%s", tmpNlistWave[i]		// use average ddg waves
				elseif (cgDisplay == 0)
					sprintf tmpADDWaveName, "AZ_%s", tmpNlistWave[i]			// use average z waves
				elseif (cgDisplay == 1)
					sprintf tmpADDWaveName, "AV_%s", tmpNlistWave[i]			// use average vh waves
				elseif (cgDisplay == 2)
					sprintf tmpADDWaveName, "AS_%s", tmpNlistWave[i]			// use average slope waves
				endif
				Wave tmpADDWave = $tmpADDWaveName
				for (j=0; j<ItemsInList(catY_WaveList); j+=1)				//  Store the DDG values for current x-unit into the catY (DDG ion) waves
					sprintf tmpWaveName, "catY_%s", StringFromList(j,catY_WaveList)
					Wave tmpWave = $tmpWaveName 
					InsertPoints /M=0 numpnts(tmpWave), 1, tmpWave
					sprintf tmpWaveName2, "%s_sem", tmpWaveName			// Store sem values
					Wave tmpWave2 = $tmpWaveName2 
					InsertPoints /M=0 numpnts(tmpWave2), 1, tmpWave2
					tmpVar = FindDimLabel(tmpADDWave, 1, StringFromList(j,catY_Dlist))
					if (tmpVar >= 0)
						tmpWave[n] = tmpADDWave[0][tmpVar]
						tmpWave2[n] = tmpADDWave[2][tmpVar]
						//printf "***SEMwave[%d]=%g\r", n, tmpADDWave[2][tmpVar]
					else
						tmpWave[n] = NaN
						tmpWave2[n] = NaN
					endif
				endfor
				n+=1		
			endif
		endfor
	endif
	
	TextBox /C /N=rawmenu /V=0
	TextBox /C /N=rawspace /V=0
	TextBox /C /N=ddgmenu /V=0
	TextBox /C /N=ddgspace /V=0
	
	//  Clear previous graph
	catY_GraphList = WaveList("catY_*",";","WIN:")
	for (i=0; i<ItemsInList(catY_GraphList); i+=1)
		sprintf tmpString, "RemoveFromGraph /Z %s", StringFromList(i,catY_GraphList)
		Execute tmpString
	endfor
	sprintf catY_GraphList, ""
	legend /K /N=CGLegend
	
	//  Display in current window or new window
	if (newWindowFlag == 1)
		sprintf cat_DisplayCmd, "Display"
	else
		sprintf cat_DisplayCmd, "AppendToGraph"
	endif
	
	//  Create WT Wave
	if ((divideByWTFlag || subtractWTFlag) && axisLabel)
		sprintf tmpWaveName, "catY_%s", wtName
		//printf "tmpWaveName[wt]=%s\r", tmpWaveName
		Wave tmpWTWave = $tmpWaveName
		sprintf tmpWaveName, "%s_SEM", tmpWaveName
		Wave tmpWTSEMWave = $tmpWaveName
	endif
	String tmpUnitsList = ""
	for (i=0; i<numpnts(catX_Units); i+=1)
		tmpUnitsList = AddListItem(catX_Units[i], tmpUnitsList, ";", inf)
	endfor
	
	//  Get graph wave list and divide or subtract WT if necessasry
	for (i=0; i<ItemsInList(catY_WaveList); i+=1)
		sprintf tmpWaveName, "catY_%s", StringFromList(i,catY_WaveList)
		//  Divide by WT
		if (divideByWTFlag)
			Wave tmpWave = $tmpWaveName
			sprintf tmpWaveName, "%s_dWT", tmpWaveName
			if (axisLabel)
				Make /O /N=(numpnts(tmpWave)) $tmpWaveName = tmpWave/tmpWTWave
			else
				Make /O /N=(numpnts(tmpWave)) $tmpWaveName = tmpWave/tmpWave[(WhichListItem(wtName,tmpUnitsList))]
				//printf "We're dividing by [%g]\r", tmpWave[(WhichListItem(wtName,tmpUnitsList))]
			endif
			if (ShowSEMFlag)
				sprintf tmpWaveName3, "%s_SEM", tmpWaveName
				sprintf tmpWaveName2, "catY_%s_SEM", StringFromList(i,catY_WaveList)
				Wave tmpWave2 = $tmpWaveName2
				if (axisLabel)
					Make /O /N=(numpnts(tmpWave)) $tmpWaveName3 = tmpWave2/tmpWTWave
				else
					Make /O /N=(numpnts(tmpWave)) $tmpWaveName3 = tmpWave2/tmpWave[(WhichListItem(wtName,tmpUnitsList))]
				endif
			endif
		//  Subtract by WT
		elseif (subtractWTFlag)
			Wave tmpWave = $tmpWaveName
			sprintf tmpWaveName, "%s_sWT", tmpWaveName
			if (axisLabel)
				Make /O /N=(numpnts(tmpWave)) $tmpWaveName = tmpWave - tmpWTWave
			else
				Make /O /N=(numpnts(tmpWave)) $tmpWaveName = tmpWave - tmpWave[(WhichListItem(wtName,tmpUnitsList))]
			endif
			if (ShowSEMFlag)
				sprintf tmpWaveName3, "%s_SEM", tmpWaveName
				sprintf tmpWaveName2, "catY_%s_SEM", StringFromList(i,catY_WaveList)
				Wave tmpWave2 = $tmpWaveName2
				Make /O /N=(numpnts(tmpWave)) $tmpWaveName3 = tmpWave2
			endif
		endif
		sprintf catY_GraphList, "%s%s", catY_GraphList, tmpWaveName
		if (i<(ItemsInList(catY_WaveList)-1))
			sprintf catY_GraphList, "%s,", catY_GraphList
		endif
	endfor

	//  Sort graph wave list based on user-defined parameter
	if (!axisLabel)									// Mutant names are used for x-axis label
		tmpList = catY_GraphList
		for(i=strsearch(tmpList,",",0); i>=0; i=strsearch(tmpList,",",0))				// Convert tmpList to a normal synatx (with ; as separator)
			tmpList[i,i] = ";"
		endfor
		if (ShowSEMFlag)
			for(i=0; i<ItemsInList(catY_GraphList); i+=1)
				sprintf tmpString, "%s_sem", StringFromList(i, catY_GraphList)
				tmpList = AddListItem(tmpString, tmpList)
			endfor
		endif
		if (sortLabel == 0)								// Sort based on sequence
			make /o /t /n=(numpnts(catX_Units)) catX_Sequence
			for (i=0; i<numpnts(catX_Units); i+=1)
				sprintf tmpString, "%s", catX_Units[i]
				for (j=0; j<strlen(tmpString); j+=1)
					if ((char2num(tmpString[j]) > 47) & (char2num(tmpString[j]) < 58))
						break
					endif
				endfor
				if (j == strlen(tmpString))
					sprintf tmpString2, "0%s", tmpString
					catX_Sequence[i] = tmpString2
				else
					catX_Sequence[i] = tmpString[j,(strlen(tmpString)-1)]
				endif
				//printf "catX_Sequence[%d] = %s\r", i, catX_Sequence[i]
			endfor
			SNCQuickSort("catX_Sequence", tmpList, "catX_Units", 0, numpnts(catX_Units)-1)
		elseif (sortLabel == 1)							// Sort based on number
			make /o /t /n=(numpnts(catX_Units)) catX_Numbers
			for (i=0; i<numpnts(catX_Units); i+=1)
				n = WhichListItem(catX_Units[i], mtNameList)
				catX_Numbers[i] = StringFromList(n,mtNumberList)
			endfor
			SNCQuickSort("catX_Numbers", tmpList, "catX_Units", 0, numpnts(catX_Numbers)-1)
		elseif (sortLabel == 2)
			sprintf tmpString, "Sort /R %s, catX_Units", StringFromList(0,catY_GraphList)
			for (i=0; i<ItemsInList(tmpList); i+=1)
				sprintf tmpString, "%s, %s", tmpString, StringFromList(i,tmpList)
			endfor
			Execute tmpString
			//SNCQuickSort("MaxValueSort", tmpList, "catX_Units", 0, numpnts(catX_Units)-1)
		elseif (sortLabel == 3)
			sprintf tmpString, "Sort %s, catX_Units", StringFromList(0,catY_GraphList)
			for (i=0; i<ItemsInList(tmpList); i+=1)
				sprintf tmpString, "%s, %s", tmpString, StringFromList(i,tmpList)
			endfor
			Execute tmpString
		endif
	endif

	//  Get maxAxis and minAxis
	maxAxis=0
	minAxis=0
	for (i=0; i<ItemsInList(catY_GraphList,","); i+=1)
		tmpVar1 = 0
		tmpVar2 = 0
		sprintf tmpWaveName, "%s", StringFromList(i,catY_GraphList,",")
		WaveStats /Q $tmpWaveName
		tmpVar1 += V_max
		tmpVar2 +=V_min
		if (showSEMFlag)
			sprintf tmpWaveName, "%s_sem", tmpWaveName
			WaveStats /Q $tmpWaveName
			tmpVar1 += V_max
			tmpVar2 -= V_min
		endif
		if (tmpVar1>maxAxis)
			maxAxis = tmpVar1
		endif
		if (tmpVar2<minAxis)
			minAxis = tmpVar2
		endif
	endfor
	
	//  Create graph display command and option commands
	sprintf tmpString, "%s %s vs catX_Units", cat_DisplayCmd, catY_GraphList
	Execute tmpString
	if (showSEMFlag)
		//printf "catY_GraphList = %s\r", catY_GraphList
		for (i=0; i<ItemsInList(catY_GraphList,","); i+=1)
			String s = StringFromList(i,catY_GraphList,",")
			sprintf tmpString, "ErrorBars /T=1 /L=1 /Y=%d %s Y, wave=(%s_sem,%s_sem)", 100/(ItemsInList(catY_GraphList,",")+numpnts(catX_Units)), s,s,s
			Execute tmpString
		endfor
	endif
	//printf "%s\r", tmpString	
	sprintf tmpString, "SetAxis left globalMinAxis,globalMaxAxis"
	Execute tmpString
	sprintf tmpString, "ModifyGraph rgb=(%d,%d,%d)", colorR, colorG, colorB
	Execute tmpString
	
	//  Color WT black
	if(colorWTBlackFlag)
		if(axislabel)
			if(divideByWTFlag)
				sprintf tmpString2, "catY_%s_dWT", wtName
			elseif(subtractWTFlag)
				sprintf tmpString2, "catY_%s_sWT", wtName
			else
				sprintf tmpString2, "catY_%s", wtName
			endif
			if(exists(tmpString2))
				sprintf tmpString, "ModifyGraph rgb(%s)=(%d,%d,%d)", tmpString2, wtcolorR, wtcolorG, wtcolorB
				//printf "%s\r", tmpString
				Execute tmpString
			else
				DoAlert 0, "Please choose your WT name from the list of mutant names."
			endif
		else
			n=-1
			for(i=0; i<numpnts(catX_Units); i+=1)				// Get index of WT name in catX_Units
				if(cmpstr(wtName,catX_Units[i])==0)
					n=i
				endif
			endfor
			if(n==-1)
				DoAlert 0,"WT data was not selected to be graphed.\rUser-specified WT color will be ignored."
			else
				for(i=0; i<ItemsInList(catY_GraphList,","); i+=1)
					sprintf tmpWaveName, "%s", stringFromList(i,catY_GraphList,",")
					Wave tmpWave = $tmpWaveName
					sprintf tmpWaveName, "%s_WT", stringFromList(i,catY_GraphList,",")
					make /O /N=(numpnts(catX_Units)) $tmpWaveName = NaN
					Wave tmpWave2 = $tmpWaveName
					tmpWave2[n] = tmpWave[n]
					tmpWave[n] = NaN
					sprintf catY_WT_GraphList, "%s%s", catY_WT_GraphList, tmpWaveName
					if(i<(ItemsInList(catY_WaveList)-1))
						sprintf catY_WT_GraphList, "%s,", catY_WT_GraphList
					endif
				endfor
				
				sprintf tmpString, "AppendToGraph %s vs catX_Units", catY_WT_GraphList
				Execute tmpString
				for(i=0; i<ItemsInList(catY_WT_GraphList,","); i+=1)
					sprintf tmpString, "ModifyGraph rgb(%s)=(%d,%d,%d)", StringFromList(i,catY_WT_GraphList,","), wtcolorR, wtcolorG, wtcolorB
					Execute tmpString
				endfor
				sprintf tmpString, "ReorderTraces %s,{%s}", StringFromList(0,catY_GraphList,","), catY_WT_GraphList
				Execute tmpString
				//printf "%s\r", tmpString
			endif
		endif
	endif
	
	//  Modify hbfill value based on user selection
	if (FillValue == 0)
		tmpVar = 0
	elseif (FillValue == 1)
		tmpVar = 5
	elseif (FillValue == 2)
		tmpVar = 4
	elseif (FillValue == 3)
		tmpVar = 3
	elseif (FillValue == 4)
		tmpVar = 2
	endif
	sprintf tmpString, "ModifyGraph hbfill=%d", tmpVar
	Execute tmpString
	
	//  Display legend if showlegendflag is set
	if (showLegendFlag == 1)
		legend /N=CGLegend
	endif 
	
end

//	Variant of quicksort
//	Sorts the items in a set of waves defined by NumericWaveList and TextWaveList based on the actual sorting of the wave SortWaveName
//	The dimensions and dimsizes of the waves in NumericWaveList and TextWaveList and the wave SortWaveName must be the same
//	The wave SortWaveName must be a text wave, and is also sorted along with the waves in NumericWaveList and TextWaveList
//	NumericWaveList must contain a list of Numeric Wave Names. Use " " for no waves.
//	TextWaveList must contain a list of TextWaveNames. Use " " for no waves.
//	SortWaveName must not be included in TextWaveList or NumericWaveList
//	This function calls the function SNCPartition and calls itself recursively
Function SNCQuickSort(SortWaveName, NumericWaveList, TextWaveList, left, right)
	String SortWaveName, NumericWaveList, TextWaveList
	Variable left, right
	//printf "------------------- right=%d\r",right
	if (right>left)
		Variable k = SNCPartition(SortWaveName, NumericWaveList, TextWaveList, left, right)
		SNCQuickSort(SortWaveName, NumericWaveList, TextWaveList, left, k-1)
		SNCQuickSort(SortWaveName, NumericWaveList, TextWaveList, k+1, right)
	endif
end

//	Function to partition a list (used in quicksort)
Function SNCPartition(SortWaveName, NumericWaveList, TextWaveList, i, j)
	String SortWaveName, NumericWaveList, TextWaveList
	Variable i, j
	
	Wave/T SortWave = $SortWaveName
	Variable tmpVar, m, k=j
	String tmpString, tmpWaveName, value = SortWave[k]
	
	do
		for (;cmpstr(SortWave[i],value)<0;i+=1)
		endfor
		j-=1
		for (;(cmpstr(SortWave[j],value)>0) && (j>i); j-=1)
		endfor
		if (i<j)
			tmpString = SortWave[i]
			SortWave[i] = SortWave[j]
			SortWave[j] = tmpString
			if (cmpstr(NumericWaveList,"") != 0)
				for (m=0; m<ItemsInList(NumericWaveList); m+=1)
					tmpWaveName = StringFromList(m, NumericWaveList)
					Wave tmpWave = $tmpWaveName
					tmpVar = tmpWave[i]
					tmpWave[i] = tmpWave[j]
					tmpWave[j] = tmpVar
				endfor
			endif
			if (cmpstr(TextWaveList,"") != 0)
				for (m=0; m<ItemsInList(TextWaveList); m+=1)
					tmpWaveName = StringFromList(m, TextWaveList)
					Wave /T tmpTWave = $tmpWaveName
					tmpString = tmpTWave[i]
					tmpTWave[i] = tmpTWave[j]
					tmpTWave[j] = tmpString
				endfor
			endif
		endif
	while (i<j)
	SortWave[k] = SortWave[i]
	SortWave[i] = value
	if (cmpstr(NumericWaveList,"") != 0)
		for (m=0; m<ItemsInList(NumericWaveList); m+=1)
			tmpWaveName = StringFromList(m, NumericWaveList)
			Wave tmpWave = $tmpWaveName
			tmpVar = tmpWave[k]
			tmpWave[k] = tmpWave[i]
			tmpWave[i] = tmpVar
		endfor
	endif
	if (cmpstr(TextWaveList,"") != 0)
		for (m=0; m<ItemsInList(TextWaveList); m+=1)
			tmpWaveName = StringFromList(m, TextWaveList)
			Wave /T tmpTWave = $tmpWaveName
			tmpString = tmpTWave[k]
			tmpTWave[k] = tmpTWave[i]
			tmpTWave[i] = tmpString
		endfor
	endif
	tmpString = "**SortWave\t"
	for (m=0; m<numpnts(SortWave); m+=1)
		sprintf tmpString, "%s\t[%d]=%s", tmpString, m, SortWave[m]
	endfor
	//printf "%s\r", tmpString
	//printf "k=%d, i=%d\r", k,i
	return i
end

//	Function to handle CGCancel button
Function SNCCGCancel(ctrlName) : ButtonControl
	String ctrlName
	
	String tmpString, catY_GraphList
	Variable i
	
	//  Clear existing graph
	catY_GraphList = WaveList("catY_*",";","WIN:")
	for (i=0; i<ItemsInList(catY_GraphList); i+=1)
		sprintf tmpString, "RemoveFromGraph /Z %s", StringFromList(i,catY_GraphList)
		Execute tmpString
	endfor
	sprintf catY_GraphList, ""
	legend /K /N=CGLegend
	
	sprintf tmpString, "Button NewMutant disable=0"
	Execute tmpString
	sprintf tmpString, "Button LoadFile disable=gflagLoadFile"
	Execute tmpString
	sprintf tmpString, "Button EditFile disable=gflagFileLoaded"
	Execute tmpString
	sprintf tmpString, "Button SaveFile disable=gflagNewData"
	Execute tmpString
	sprintf tmpString, "Button AddData disable=gflagReadyToAdd"
	Execute tmpString
	sprintf tmpString, "PopupMenu mtSelect disable=0"
	Execute tmpString
	sprintf tmpString, "Button ToggleDisplay disable=0"
	Execute tmpString
	sprintf tmpString, "Button EditPDWave disable=0"
	Execute tmpString
	
	SNCGetDDGLists()
	SNCRawMenu()
	SNCRawSpace()
	SNCddgMenu()
	SNCddgSpace()
	SNCInputDialogues()
	
	sprintf tmpString, "KillControl CGNewWindow"
	Execute tmpString
	sprintf tmpString, "KillControl CGShowNumbers"
	Execute tmpString
	sprintf tmpString, "KillControl CGNameList"
	Execute tmpString
	sprintf tmpString, "KillControl CGDDGList"
	Execute tmpString
	sprintf tmpString, "KillControl CGOK"
	Execute tmpString
	sprintf tmpString, "KillControl CGCancel"
	Execute tmpString
	
	sprintf tmpString, "KillControl CGWTSelect"
	Execute tmpString
	sprintf tmpString, "KillControl CGWTColorMenu"
	Execute tmpString
	sprintf tmpString, "KillControl CGColorMenu"
	Execute tmpString
	sprintf tmpString, "KillControl CGFillSlider"
	Execute tmpString
	sprintf tmpString, "KillControl CGSliderTick0"
	Execute tmpString
	sprintf tmpString, "KillControl CGSliderTick1"
	Execute tmpString
	sprintf tmpString, "KillControl CGSliderTick2"
	Execute tmpString
	sprintf tmpString, "KillControl CGSliderTick3"
	Execute tmpString
	sprintf tmpString, "KillControl CGSliderTick4"
	Execute tmpString
	sprintf tmpString, "KillControl CGShowLegend"
	Execute tmpString
	sprintf tmpString, "KillControl CGShowSEM"
	Execute tmpString
	sprintf tmpString, "KillControl CGWTBlack"
	Execute tmpString
	sprintf tmpString, "KillControl CGWTDivide"
	Execute tmpString
	sprintf tmpString, "KillControl CGWTSubtract"
	Execute tmpString
	sprintf tmpString, "KillControl CGAxisLabel"
	Execute tmpString
	sprintf tmpString, "KillControl CGAxisLabelMutant"
	Execute tmpString
	sprintf tmpString, "KillControl CGAxisLabelDDG"
	Execute tmpString
	sprintf tmpString, "KillControl CGSortBy"
	Execute tmpString
	sprintf tmpString, "KillControl CGSortSequence"
	Execute tmpString
	sprintf tmpString, "KillControl CGSortNumber"
	Execute tmpString
	sprintf tmpString, "KillControl CGSortMax"
	Execute tmpString
	sprintf tmpString, "KillControl CGSortMin"
	Execute tmpString
	sprintf tmpString, "KillControl CGDisplayTitle"
	Execute tmpString
	sprintf tmpString, "KillControl CGDisplayZ"
	Execute tmpString
	sprintf tmpString, "KillControl CGDisplayVh"
	Execute tmpString
	sprintf tmpString, "KillControl CGDisplaySlope"
	Execute tmpString
	sprintf tmpString, "KillControl CGNSelectAll"
	Execute tmpString
	sprintf tmpString, "KillControl CGDSelectAll"
	Execute tmpString

End

//	Function to display help
Function SNCHelp(ctrlName) : ButtonControl
	String ctrlName
	String url = "http://igor.qiguang.net"
	BrowseURL /Z url
end

//	Function to handle control panel line button
Function SNCLineHook(ctrlName) : ButtonControl
	String ctrlName
	NVAR gline = gflagLineHandle
	Variable i
	gline +=1
	if (gline == 10)
		DoAlert 0, "Yes, this is a button. \rBut its real purpose is to serve as a separator line."
	elseif (gline == 20)
		DoAlert 0, "Bored, huh? ;p"
	elseif (gline == 50)
		DoAlert 0, "Wow, I'm actually kinda flattered that you find this so amusing... ^_^"
	elseif (gline == 100)
		do
			DoAlert 1, "Aren't I just the sexiest program you've ever seen?"
			i = V_flag
		while (i != 1)
		DoAlert 0, "Why, thank you! ^_^\r*blushes*"
	elseif (gline == 200)
		for (gline=42; gline<100; gline+=1)
			Beep
			for (i=0;i<12345;i+=1)
				i-=0.9
			endfor
		endfor
		DoAlert 0, "Now wasn't that just oodles of fun? ^_~"
	elseif (gline == 300)
		DoAlert 0, "Okay, okay, you win.\rYou're the champion.\rYou rock. You 0wnz. j00 R 1337.\rYou are so cool, I wish I could go out with you baby."
	elseif (gline == 500)
		DoAlert 0, "Alright buddy, you officially have NO LIFE."
	elseif (gline == 501)
		DoAlert 0, "I was just kidding, sweetie. =)\rI <3 you!\r*huggles*\rBut seriously, please stop before you develop RSI... ^^;;"
	endif
end

//	Function to start a new sesion
//	Kills all raw patch data waves
//	Resets the global mutant lists
Function SNCNewSession(ctrlName) : ButtonControl
	String ctrlName
	
	String tmpString, tmpWaveName, catY_GraphList
	SVAR mtNameList = globalMtNameList
	NVAR flagNewData = gflagNewData
	Variable i
	
	if (flagNewData != 2)
		Beep
		DoAlert 2, "Warning! You will loose all information that has not been saved.\rContinue?"
		if (V_flag != 1)
			return 0
		endif
	endif
	
	for (i=0;i<ItemsInList(mtNameList);i+=1)
		sprintf tmpWaveName, "PD_%s", StringFromList(i,mtNameList)
		Wave tmpWave = $tmpWaveName
		KillWaves tmpWave
	endfor
	for (i=0; i<10; i+=1)
		sprintf tmpString, "KillControl setvar%da", i
		Execute tmpString
		sprintf tmpString, "KillControl setvar%db", i
		Execute tmpString
		sprintf tmpString, "KillControl setvar%dTitle", i
		Execute tmpString
	endfor
	
	TextBox /C /N=rawmenu /V=1 /A=LT /T=50 /F=1 ""
	TextBox /C /N=rawspace /V=1 /A=LT /T=50 /F=1 ""
	TextBox /C /N=ddgmenu /V=1 /A=LT /T=50 /F=1 ""
	TextBox /C /N=ddgspace /V=1 /A=LT /T=50 /F=1 ""
	sprintf tmpString, "SNCGlobals()"
	Execute tmpString
	sprintf tmpString, "SNCCGGlobals()"
	Execute tmpString
	sprintf tmpString, "TitleBox VhTitle disable=1"
	Execute tmpString
	sprintf tmpString, "TitleBox SlopeTitle disable=1"
	Execute tmpString
	ControlUpdate /A
	
	sprintf tmpString, "Button NewMutant disable=gflagNewMutant"
	Execute tmpString
	sprintf tmpString, "Button LoadFile disable=gflagLoadFile"
	Execute tmpString
	sprintf tmpString, "Button EditFile disable=gflagFileLoaded"
	Execute tmpString
	sprintf tmpString, "Button SaveFile disable=gflagNewData"
	Execute tmpString
	sprintf tmpString, "Button AddData disable=gflagReadyToAdd"
	Execute tmpString
	sprintf tmpString, "Button ToggleDisplay disable=2"
	Execute tmpString
	
	//  Clear existing graph
	catY_GraphList = WaveList("catY_*",";","WIN:")
	for (i=0; i<ItemsInList(catY_GraphList); i+=1)
		sprintf tmpString, "RemoveFromGraph /Z %s", StringFromList(i,catY_GraphList)
		Execute tmpString
	endfor
	sprintf catY_GraphList, ""
	legend /K /N=CGLegend
	
	sprintf tmpString, "Button NewMutant disable=0"
	Execute tmpString
	sprintf tmpString, "Button LoadFile disable=gflagLoadFile"
	Execute tmpString
	sprintf tmpString, "Button EditFile disable=gflagFileLoaded"
	Execute tmpString
	sprintf tmpString, "Button SaveFile disable=gflagNewData"
	Execute tmpString
	sprintf tmpString, "Button AddData disable=gflagReadyToAdd"
	Execute tmpString
	sprintf tmpString, "PopupMenu mtSelect disable=0"
	Execute tmpString
	sprintf tmpString, "Button ToggleDisplay disable=0"
	Execute tmpString
	sprintf tmpString, "Button EditPDWave disable=0"
	Execute tmpString
	
	sprintf tmpString, "KillControl CGNewWindow"
	Execute tmpString
	sprintf tmpString, "KillControl CGShowNumbers"
	Execute tmpString
	sprintf tmpString, "KillControl CGNameList"
	Execute tmpString
	sprintf tmpString, "KillControl CGDDGList"
	Execute tmpString
	sprintf tmpString, "KillControl CGOK"
	Execute tmpString
	sprintf tmpString, "KillControl CGCancel"
	Execute tmpString
	
	sprintf tmpString, "KillControl CGWTSelect"
	Execute tmpString
	sprintf tmpString, "KillControl CGWTColorMenu"
	Execute tmpString
	sprintf tmpString, "KillControl CGColorMenu"
	Execute tmpString
	sprintf tmpString, "KillControl CGFillSlider"
	Execute tmpString
	sprintf tmpString, "KillControl CGSliderTick0"
	Execute tmpString
	sprintf tmpString, "KillControl CGSliderTick1"
	Execute tmpString
	sprintf tmpString, "KillControl CGSliderTick2"
	Execute tmpString
	sprintf tmpString, "KillControl CGSliderTick3"
	Execute tmpString
	sprintf tmpString, "KillControl CGSliderTick4"
	Execute tmpString
	sprintf tmpString, "KillControl CGShowLegend"
	Execute tmpString
	sprintf tmpString, "KillControl CGShowSEM"
	Execute tmpString
	sprintf tmpString, "KillControl CGWTBlack"
	Execute tmpString
	sprintf tmpString, "KillControl CGWTDivide"
	Execute tmpString
	sprintf tmpString, "KillControl CGWTSubtract"
	Execute tmpString
	sprintf tmpString, "KillControl CGAxisLabel"
	Execute tmpString
	sprintf tmpString, "KillControl CGAxisLabelMutant"
	Execute tmpString
	sprintf tmpString, "KillControl CGAxisLabelDDG"
	Execute tmpString
	sprintf tmpString, "KillControl CGSortBy"
	Execute tmpString
	sprintf tmpString, "KillControl CGSortSequence"
	Execute tmpString
	sprintf tmpString, "KillControl CGSortNumber"
	Execute tmpString
	sprintf tmpString, "KillControl CGSortMax"
	Execute tmpString
	sprintf tmpString, "KillControl CGSortMin"
	Execute tmpString
	sprintf tmpString, "KillControl CGDisplayTitle"
	Execute tmpString
	sprintf tmpString, "KillControl CGDisplayZ"
	Execute tmpString
	sprintf tmpString, "KillControl CGDisplayVh"
	Execute tmpString
	sprintf tmpString, "KillControl CGDisplaySlope"
	Execute tmpString
	sprintf tmpString, "KillControl CGNSelectAll"
	Execute tmpString
	sprintf tmpString, "KillControl CGDSelectAll"
	Execute tmpString
end

Function SNCDDGCalc ()

	Variable i, n
	SVAR thisTitle = globalTitle
	SVAR mtNameList = globalMtNameList
	SVAR mtNumberList = globalMtNumberList
	SVAR mtSolutionsList = globalMtSolutionsList
	SVAR thisversion = globalVersion
	NVAR mtIndex = globalMtIndex
	String tmpString, tmpSolutionsList
	
	String globalsCmd					//  Command to execute macro that creats globals for this program
	String displayCmd					//  Command to produce display box
	String titleFileTitleCmd				//  Command to produce title to indicate file loaded field
	String titleFileLoadedCmd				//  Command to produce title to display current open file
	String titleMtDropdownCmd			//  Command to produce dropdown box from which user can select which mutant data to load from current open file
	String controlBarCmd					//  Command to produce control bar in display box
	String buttonNewMutantCmd			//  Command to produce button for new mutant input
	String buttonNewSessionCmd			//  Command to produce button to start new session (from scratch)
	String buttonLoadFileCmd				//  Command to produce button to load patch data file
	String buttonSaveFileCmd				//  Command to produce button to save current patch data to a file
	String buttonEditFileCmd				//  Command to produce button to edit current patch data file with Notepad.exe (Windows only)
	String buttonEditDataCmd				//  Command to produce button to edit current patch data in Igor 
	String buttonAddDataCmd				//  Command to produce button to add user entered patch data into patch data wave
	String buttonVhTitleCmd				//  Command to produce title box for V_half input dialogues
	String buttonSlopeTitleCmd			//  Command to produce title boc for Slope input dialogues
	String buttonAverageDDGCmd			//  Command to produce button to average DDG values and save them to a wave that can be graphed later
	String buttonDisplayGraphsCmd		//  Command to produce button that will present the user with several graphing options...
	String buttonToggleDisplayCmd		//  Command to produce button that toggles display between raw patch data and calculated ddg data
	String buttonCreateDDGGraphsCmd	//  Command to produce button that allows the user to create graphs with ddg values
	String buttonCreateOtherGraphsCmd	//  Command to produce button that allows the user to greate graphs with Z, Vh and Slope values
	String buttonHelpCmd					//  Command to produce button that displays help...
	String buttonOtherGraphsCmd
	String buttonEditPDWaveCmd
	
	String solutionTitleCmd				//  Command to produce title box that displays solution type next to data input box
	
	sprintf globalsCmd, "SNCGlobals()"
	Execute globalsCmd
	sprintf globalsCmd, "SNCCGGlobals()"
	Execute globalsCmd

	sprintf displayCmd, "Display /W=(0,35,640,500) /K=1 as \"SNC DDG Calculator       \"+globalVersion"
	sprintf titleFileTitleCmd, "TitleBox fileTitle frame=0, pos={19,5}, size={90,20}, title=\"File Loaded: \""
	sprintf titleFileLoadedCmd, "TitleBox fileLoaded frame=0, pos={95,4}, size={600,22}, labelBack=(63000,62000,62000), variable=globalTitle"
	sprintf titleMtDropdownCmd, "PopupMenu mtSelect pos={10,25}, size={200,20},  mode=1, help={\"Select which mutant data from the currently loaded file you want to load.\"}, title=\"Select Mutant: \", value=globalMtNameList, proc=SNCMtSelect"
	sprintf controlBarCmd, "ControlBar 200"
	sprintf buttonNewMutantCmd, "Button NewMutant disable=gflagNewMutant, help={\"Add a new mutant to the current project\"}, pos={10,155}, size={120,25}, title=\"New Mutant\", proc=SNCNewMutant"
	sprintf buttonLoadFileCmd, "Button LoadFile disable = gflagLoadFile, help={\"Load patch data from a previously saved file.\"}, pos={10,65}, size={120,25}, title=\"Load File...\", proc=LoadPatchDataFile"
	sprintf buttonEditFileCmd, "Button EditFile disable=gflagFileLoaded, help={\"Edit patch data file with Notepad.exe (Windows only).\"}, pos={10,95}, size={120,25}, title=\"Edit File (Win only)\", proc=SNCEditFile"
	sprintf buttonSaveFileCmd, "Button SaveFile disable=gflagNewData, help={\"Save current patch data to a user specified file.\"}, pos={10,125}, size={120,25}, title=\"Save File...\", proc=SNCSaveFile"
	sprintf buttonAddDataCmd, "Button AddData disable=gflagReadyToAdd, help={\"Add new patch data to current mutant.\"}, pos={195,155}, size={380,25}, title=\"Add above values to current patch data wave (\"+StringFromList(globalMtIndex,globalMtNameList)+\")\", proc=SNCAddData"
	sprintf buttonVhTitleCmd, "TitleBox VhTitle disable=1, frame=0, pos={155,102}, size={50,30}, title=\"V_half:\""
	sprintf buttonSlopeTitleCmd, "TitleBox SlopeTitle disable=1, frame=0, pos={155,132}, size={50,30}, title=\"Slope:\""
	sprintf buttonToggleDisplayCmd, "Button ToggleDisplay disable=2, help={\"Toggle display between raw patch data and calculated DDG values.\"} , pos={720,65}, size={120,25}, title=\"Show DG and DDG\", proc=SNCToggleDisplay"
	sprintf buttonCreateDDGGraphsCmd, "Button CreateDDGGraphs disable=2, help={\"Create custom graphs with ddg values\"}, pos={720,95}, size={120,25}, title=\"Create DDG Graphs\", proc=SNCCreateGraphs"
	sprintf buttonCreateOtherGraphsCmd, "Button CreateOtherGraphs disable=2, help={\"Create custom graphs with V_h, Slope and Z values\"}, pos={720,125}, size={120,25}, title=\"Create Other Graphs\", proc=SNCCreateGraphs"
	sprintf buttonEditPDWaveCmd, "Button EditPDWave disable=2, help={\"Edit PD Waves.\"}, pos={720,155}, size={120,25}, title=\"Edit PD_\"+StringFromList(globalMtIndex,globalMtNameList)+\" Wave\", proc=SNCEditPDWave"
	
	sprintf buttonHelpCmd, "Button Help disable=0, help={\"For more information...\"}, pos={770,28}, size={70,18}, title=\"Online Help\", proc=SNCHelp"
	sprintf buttonNewSessionCmd, "Button NewSession help={\"Reset program and start inputing data from a new session.\"}, pos={770,5}, size={70,18}, title=\"Restart\", proc=SNCNewSession"

	
	Execute displayCmd
	Execute titleFileTitleCmd
	Execute titleFileLoadedCmd
	Execute titleMtDropdownCmd
	Execute controlBarCmd
	Execute buttonNewMutantCmd
	Execute buttonLoadFileCmd
	Execute buttonEditFileCmd
	Execute buttonSaveFileCmd
	Execute buttonAddDataCmd
	Execute buttonVhTitleCmd
	Execute buttonSlopeTitleCmd
	Execute buttonToggleDisplayCmd
	Execute buttonCreateDDGGraphsCmd
	Execute buttonCreateOtherGraphsCmd
	Execute buttonEditPDWaveCmd
	Execute buttonHelpCmd
	Execute buttonNewSessionCmd
	
	sprintf tmpString, "button WindowLine noproc, pos={0,50}, size={1000,5}, labelBack = (0,0,0), title=\"\", proc=SNCLineHook"
	Execute tmpString
end

Go to the Contents


Mon Sep 29 10:31:54 2003