Dependecy and data folders

Hello,

I've written a procedure to calculate a center of mass and wanted to implement a variable dependency and a folder creation in the procedure.
I would like to be able to change the variable offset (without having to alter the procedure itself), in the command window or in the button in the graph, and for each time I do it a new folder would be created.
I would apreciate very much if my mistakes could be pointed out in my code below
Thanks in advance,
Gabriel

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

Function COM(w)

Wave w

Variable pw = 1
Variable/G offset = 100
Variable i, j, k
String dfName
sprintf dfName, "offset%d", offset

NewDataFolder/O/S $dfName

MAKE /N=(512,41,61) vc
Wave vc

MAKE /N=(41,61) Tintensity
Wave Tintensity


MAKE /N=(41,61) rowXintensityXpw
Wave rowXintensityXpw


MAKE /N=(41,61) CM
Wave CM


vc = w - offset //SetFormula vc, "w - offset" => Can't get this dependency to work

for (k=0; k < 61; k += 1)
for (j=0; j < 41; j += 1)
for (i=0; i < 512; i += 1)
Tintensity[j][k] += vc[i][j][k]
rowXintensityXpw[j][k] += (i+1)*vc[i][j][k]*pw
endfor
endfor
endfor

CM = (rowXintensityXpw)/(Tintensity)

Duplicate CM, CM2
Duplicate Tintensity, TI

Redimension/N=2501 CM2
Redimension/N=2501 TI

Display CM2 vs TI
ControlBar 23
SetVariable offset,size={120, 20}, value=offset
SetVariable offset, proc=COM // Set procedure to run when value is changed
SetDataFolder ::

end

Since I received this question at WaveMetrics support, I'll send you an answer directly.
I would just like to point out that usinga triple nested loop is really inefficient for calculating a centre of mass.
andyfaff wrote: I would just like to point out that usinga triple nested loop is really inefficient for calculating a centre of mass.

Thank you for pointing that out, I'd apreciate if you told me how can I do it better.
gzvitiello wrote:
andyfaff wrote: I would just like to point out that usinga triple nested loop is really inefficient for calculating a centre of mass.

Thank you for pointing that out, I'd apreciate if you told me how can I do it better.

Which Howard did in his direct response from WM support.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
Which Howard did in his direct response from WM support.


Not really. I pointed out that this:


Variable i, j, k
for (k=0; k < 61; k += 1)
	for (j=0; j < 41; j += 1)
		for (i=0; i < 512; i += 1)
			vc[i][j][k] = w[i][j][k] - offset
		endfor
	endfor
endfor


can be written as this:


vc = w - offset


That still leaves a triple-nested loop. I don't know how to simplify that. Perhaps someone else does.

My advice on the structure of the function, which I will send directly, is to avoid the use of dependencies, and to separate calculation from graphics and user-interface.
hrodstein wrote: Since I received this question at WaveMetrics support, I'll send you an answer directly.


johnweeks wrote: Which Howard did in his direct response from WM support.


So how about adding the solutions here for the benefit of everyone else? Others could be interested as well.
741 wrote: So how about adding the solutions here for the benefit of everyone else? Others could be interested as well.


They're in my post above. I beat your post by 1 minute :)
This code assumes all your pixels have equal weighting. It's not simpler than the triple loop, but I'm thinking it should be faster. Of course, I could've opened my mouth too early.


Function test()
	make/n=(100,100, 100)/free w
	w = gauss(x, 10, 3, y, 20, 3, z, 30, 3)
	wave temp = com3D(w)
	print temp
End
 
Function/wave com3D(w)
	Wave w
	variable ii, t1, t2, t3
	make/n=(wavedims(w))/free/d COM
	switch(wavedims(w))
		case 1:
			COM[0] = Pla_peakcentroid(w)
			break
		case 2:
			imagetransform sumallrows w
			COM[0] = Pla_peakcentroid(W_sumrows)
			imagetransform sumallcols w
			COM[1] = Pla_peakcentroid(W_sumcols)
			break
		case 3:
			imagetransform sumplanes w
			Wave temp = com3D(M_SumPlanes)
			COM[0] = temp[0]
			COM[1] = temp[1]
			imagetransform/g = 2 transposeVol w
			imagetransform sumplanes M_volumetranspose
                        imagetransform sumallrows M_sumplanes
			COM[2] = Pla_peakcentroid(W_sumrows)
			break
		default:
			break
	endswitch
	return COM
End
 
Threadsafe Function Pla_peakCentroid(ywave)
	Wave ywave
	variable retval
 
	duplicate/free ywave, W_integrate
	W_integrate = 0
 
	multithread W_integrate[] = Area(tempy, 0, p)
 
	W_integrate /= W_integrate[numpnts(W_tempy)-1]
	variable centroid = binarysearchinterp(W_integrate,0.5)
	if(numtype(centroid))
		retval = NaN
	else
		retval = centroid
	endif
 
	return retval
End