Setvariable Procedure to Allow Use of Wavemetrics %w Formatting

This setvariable procedure allows use of the %W formatting code, which handles SI prefixes rationally, over a large range. However, it has, until now, not been advisable to use in a setvariable control, because, as explained in the command help, Igor reads the value back without interpreting the extra text, so if you have 1 mm showing in the setvariable, and you type in 2, you get 2 m, i.e., 1000 times more than you wanted. This procedure provides a work-around for that behaviour.

// Code for using SI units and handling Wavemetrics' %w formatting code in setvarariable controls
// The key point is use of a second variable to hold the absolute value of the previous value so we know order of magnitude
// and can adjust for it when user types in a new value. The second copy of the variable is assumed to be named the same
// as the main setvariable variable plus "SIS" and to be in the same datafolder.
// The name of an additional function to run, if required, is stored in user data.


//to make a sample test panel - make sure packages folder exists first:
	variable/G root:packages:MicrometerVal=0.15, root:packages:MicrometerValSIS =0.15
	newpanel
	SetVariable micrometerSetVal,pos={5,5},size={145,17},proc= SIformattedSetVarProcAdjustInc, title="Micrometer"
	SetVariable micrometerSetVal,font="Arial",fSize=12,format="%.2W1Pm"
	SetVariable micrometerSetVal,limits={0,inf,0.01},value= root:packages:MicrometerVal
	SetVariable micrometerSetVal, userData = "myotherProc" //name of additional procedure

// test additional function to run when value is changed (this is optional)
function myotherProc(sva) : SetVariableControl
	STRUCT WMSetVariableAction &sva
	
	print "hello, my name is ", sva.ctrlname, "and my value is ", sva.dval + "."
end

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The Setvariable procedure
Function SIformattedSetVarProc(sva) : SetVariableControl
	STRUCT WMSetVariableAction &sva
	
	variable eventCode =sva.eventCode
	string vName = sva.vName
	string ctrlName =  sva.ctrlName
	controlinfo $ctrlName 
	NVAR gVal = $S_DataFolder + vName
	FUNCREF  SIformattedProtoSetVarfunc extraFunc = $sva.userdata //reference to additional function to run, if any

	switch (eventCode)
		case 1: // mouse up  - Igor handles clicks properly, so just set back up variable
			NVAR valSIS =  $S_DataFolder + vName + "SIS"//reference to backup value
			valSIS =abs (gVal)
			break
		case 2: // Enter key 
			NVAR valSIS =  $S_DataFolder + vName + "SIS"//reference to backup value
			if (valSIS < 10^-21)
				gVal /= 10^24
			elseif (valSIS < 10^-18)
				gVal /= 10^21
			elseif (valSIS < 10^-15)
				gVal /= 10^18
			elseif (valSIS < 10^-12)
				gVal /= 10^15
			elseif (ValSIS  < 10^-9)
				gVal /= 10^12
			elseif (ValSIS  < 10^-6)
				gVal /= 10^9
			elseif (valSIS < 10^-3)
				gVal /= 10^6
			elseif (valSIS < 1)
				gVal /= 10^3
			elseif (valSIS < 10^3)
				gVal *= 1
			elseif (valSIS < 10^6)
				gVal *= 10^3
			elseif (valSIS < 10^9)
				gVal *= 10^6
			elseif (valSIS < 10^12)
				gVal *= 10^9
			elseif (valSIS > 10^15)
				gVal *= 10^12
			elseif (ValSIS > 10^18)
				gVal *= 10^15
			elseif (ValSIS > 10^21)
				gVal *= 10^18
			elseif(ValSIS > 10^24)
				gVal *= 10^21
			else
				gVal *= 10^24
			endif
			valSIS =abs (gVal)
			break
		case 3: // Live update - do nothing
		case -1: // killing -  do nothing
			break
	endswitch	
	//Run additional function, if it was given
	if (cmpstr (sva.userdata, "") != 0)
		sva.dVal = gVal //first update the struct with correct value
		extraFunc (sva)
	endif
	return 0
End

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//This version  also dynamically adjusts the setvariable increment to 1 percent of the current order of magnitude of the variable.
Function SIformattedSetVarProcAdjustInc(sva) : SetVariableControl
	STRUCT WMSetVariableAction &sva
	
	variable eventCode =sva.eventCode
	string vName = sva.vName
	string ctrlName =  sva.ctrlName
	controlinfo $ctrlName 
	NVAR gVal = $S_DataFolder + vName
	FUNCREF  SIformattedProtoSetVarfunc extraFunc = $sva.userdata //reference to additional function to run, if any

	switch (eventCode)
		case 1: // mouse up  - Igor handles clicks properly, so just set back up variable
			NVAR valSIS =  $S_DataFolder + vName + "SIS"//reference to backup value
			valSIS =abs (gVal)
			break
		case 2: // Enter key 
			NVAR valSIS =  $S_DataFolder + vName + "SIS"//reference to backup value
			if (valSIS < 10^-21)
				gVal /= 10^24
			elseif (valSIS < 10^-18)
				gVal /= 10^21
			elseif (valSIS < 10^-15)
				gVal /= 10^18
			elseif (valSIS < 10^-12)
				gVal /= 10^15
			elseif (ValSIS  < 10^-9)
				gVal /= 10^12
			elseif (ValSIS  < 10^-6)
				gVal /= 10^9
			elseif (valSIS < 10^-3)
				gVal /= 10^6
			elseif (valSIS < 1)
				gVal /= 10^3
			elseif (valSIS < 10^3)
				gVal *= 1
			elseif (valSIS < 10^6)
				gVal *= 10^3
			elseif (valSIS < 10^9)
				gVal *= 10^6
			elseif (valSIS < 10^12)
				gVal *= 10^9
			elseif (valSIS > 10^15)
				gVal *= 10^12
			elseif (ValSIS > 10^18)
				gVal *= 10^15
			elseif (ValSIS > 10^21)
				gVal *= 10^18
			elseif(ValSIS > 10^24)
				gVal *= 10^21
			else
				gVal *= 10^24
			endif
			valSIS =abs (gVal)
			break
		case 3: // Live update - do nothing
		case -1: // killing -  do nothing
			break
	endswitch	

	//Adjust the setvariable increment to 1 percent of current order of magnitude.
	//IMPORTANT - If your expected values will span 0,use non-adjusting version, as adjusting 
	// the  increment leads to a "Xeno-like paradox",  where you can never click past 0
	variable start, stop
	string limitStr
	start = strsearch  (s_recreation, "limits={", 0)
	stop =  strsearch  (s_recreation, "}", start)
	limitStr = s_recreation [start + 8, stop-1]
	start = str2num (stringFromList (0, limitStr, ","))
	stop = str2num (stringFromList (1, limitStr, ","))
	//adjust increment based on magnitude of current value
	if (valSIS < 10.0001^-12)
		SetVariable $ctrlname limits={(start),(stop),10^-14}
	elseif (valSIS < 10.0001^-11)
		SetVariable $ctrlname limits={(start),(stop),10^-13}
	elseif (valSIS < 10.0001^-10)
		SetVariable $ctrlname limits={(start),(stop),10^-12}
	elseif (valSIS < 10.0001^-9)
		SetVariable $ctrlname limits={(start),(stop),10^-11}
	elseif (valSIS < 10.0001^-8)
		SetVariable $ctrlname limits={(start),(stop),10^-10}
	elseif (valSIS < 10.0001^-7)
		SetVariable $ctrlname limits={(start),(stop),10^-9}
	elseif (valSIS < 10.0001^-6)
		SetVariable $ctrlname limits={(start),(stop),10^-8}
	elseif (valSIS  < 10.0001^-5)
		SetVariable $ctrlname limits={(start),(stop),10^-7}
	elseif (valSIS  < 10.0001^-4)
		SetVariable $ctrlname limits={(start),(stop),10^-6}
	elseif (valSIS < 10.0001^-3)
		SetVariable $ctrlname limits={(start),(stop),10^-5}
	elseif (valSIS < 10.0001^-2)
		SetVariable $ctrlname limits={(start),(stop),10^-4}
	elseif (valSIS < 10.0001^-1)
		SetVariable $ctrlname limits={(start),(stop),10^-3}
	elseif (valSIS < 10^0)
		SetVariable $ctrlname limits={(start),(stop),10^-2}
	elseif (valSIS < 9.9999^1)
		SetVariable $ctrlname limits={(start),(stop),10^-1}
	elseif (valSIS < 9.9999^2)
		SetVariable $ctrlname limits={(start),(stop),10^0}
	elseif (valSIS < 9.9999^3)
		SetVariable $ctrlname limits={(start),(stop),10^1}
	elseif (valSIS < 9.9999^4)
		SetVariable $ctrlname limits={(start),(stop),10^2}
	elseif (valSIS < 9.9999^5)
		SetVariable $ctrlname limits={(start),(stop),10^3}
	elseif (valSIS < 9.9999^6)
		SetVariable $ctrlname limits={(start),(stop),10^4}
	elseif (valSIS < 9.9999^7)
		SetVariable $ctrlname limits={(start),(stop),10^5}
	elseif (valSIS < 9.9999^8)
		SetVariable $ctrlname limits={(start),(stop),10^6}
	elseif (valSIS < 9.9999^9)
		SetVariable $ctrlname limits={(start),(stop),10^7}
	elseif (valSIS < 9.9999^10)
		SetVariable $ctrlname limits={(start),(stop),10^8}
	elseif (valSIS < 9.9999^11)
		SetVariable $ctrlname limits={(start),(stop),10^9}
	elseif (valSIS < 9.9999^12)
		SetVariable $ctrlname limits={(start),(stop),10^10}
	endif
	
	//Run additional function, if it was given
	if (cmpstr (sva.userdata, "") != 0)
		sva.dVal = gVal //first update the struct with correct value
		extraFunc (sva)
	endif
	return 0
End

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Prototype function for additional stuff do do when value changes 
function SIformattedProtoSetVarfunc (sva) : SetVariableControl
	STRUCT WMSetVariableAction &sva
	//Nothing happens here
	return 0
end

Forum

Support

Gallery

Igor Pro 10

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More