MSA112P_FastPixel(100)	//10x10 pixel live update in viewSpec

	
/******************************************************************
function: Project 3D to left
******************************************************************/
image  MSA112_Render3DtoLeft(image data, number outputFormat)
{
number width,height,depth
data.get3DSize(width,height,depth)

image uneven,final,split,half
if(outputFormat==0) 
	{
	uneven :=  MSA112_Make2DImageOfRightType(data.ImageGetDataType(),"",depth,height)
	final :=  MSA112_Make2DImageOfRightType(data.ImageGetDataType(),"",depth,height)
	}
else	//real
	{
	uneven :=  MSA112_Make2DImageOfRightType(2,"",depth,height)	//real
	final :=  MSA112_Make2DImageOfRightType(2,"",depth,height)	//real
	}
	
number s = width,width1,width2

//initial split
if(outputFormat==0) split := data.imageclone()
else			 	split = data	//real

while(s>1)
	{
	width1 = trunc(s/2)
//result("->"+w1)
	width2=2*width1
	half := split[0,0,0,width1,height,depth]
	half += split[width1,0,0,width2,height,depth]
	if(width2<s) uneven[iplane,irow] += split[width2,0,0,s,height,depth]	
	split := half
	s=width1
	}

final[iplane,irow]	= split			
final += uneven
		
return final
}

/*
image in:= realimage("",4,200,200,2000)
in= icol
number t = getOstickCount()
image spec = in.MSA112_Render3DtoLeft()
result("\n"+CalcOSsecondsBetween(t,getOstickCount()))
*/


/******************************************************************
function: Project 3D to bottom
******************************************************************/
image  MSA112_Render3DtoBottom(image data, number outputFormat)
{
//ATTENTION: depth information goes to Y-axis, increase top to bottom
number width,height,depth
data.get3DSize(width,height,depth)

image uneven,final,split,half
if(outputFormat==0) 
	{
	uneven :=  MSA112_Make2DImageOfRightType(data.ImageGetDataType(),"",width,depth)
	final :=  MSA112_Make2DImageOfRightType(data.ImageGetDataType(),"",width,depth)
	}
else	//real
	{
	uneven :=  MSA112_Make2DImageOfRightType(2,"",width,depth)	//real
	final :=  MSA112_Make2DImageOfRightType(2,"",width,depth)	//real
	}
	
number s = height,height1,height2

//initial split
if(outputFormat==0) split := data.imageclone()
else			 	split = data	//real

while(s>1)
	{
	height1 = trunc(s/2)
//result("->"+w1)
	height2=2*height1
	half := split[0,0,0,width,height1,depth]
	half += split[0,height1,0,width,height2,depth]
	if(height2<s) uneven[icol,iplane] += split[0,height2,0,width,s,depth]
	split := half
	s=height1
	}

final[icol,iplane] = split	
final += uneven
		
return final
}

/******************************************************************
function: Project 3D to front
******************************************************************/
image  MSA112_Render3DtoFront(image data, number outputFormat)
{
number width,height,depth
data.get3DSize(width,height,depth)

image uneven,final,split,half
if(outputFormat==0) 
	{
	uneven :=  MSA112_Make2DImageOfRightType(data.ImageGetDataType(),"",width,height)
	final :=  MSA112_Make2DImageOfRightType(data.ImageGetDataType(),"",width,height)
	}
else	//real
	{
	uneven :=  MSA112_Make2DImageOfRightType(2,"",width,height)
	final :=  MSA112_Make2DImageOfRightType(2,"",width,height)
	}
	
number s = depth,depth1,depth2

//initial split
if(outputFormat==0) split := data.imageclone()
else			 	split = data	//real

while(s>1)
	{
	depth1 = trunc(s/2)
//result("->"+w1)
	depth2=2*depth1
	half := split[0,0,0,width,height,depth1]
	half += split[0,0,depth1,width,height,depth2]
	if(depth2<s) uneven[icol,irow,0] += split[0,0,depth2,width,height,s]
	split := half
	s=depth1
	}

final[icol,irow] = split			
final += uneven
		
return final
}

/*
image in:= realimage("",4,200,200,2000)
in= icol
number t = getOstickCount()
image spec = in.MSA112_Render3DtoFront()
result("\n"+CalcOSsecondsBetween(t,getOstickCount()))
*/



/******************************************************************
function: Project 3D to left 3 (results in 3D, not 2D)
******************************************************************/
image  MSA112_Render3DtoLeft3(image data, number outputFormat)
{
number width,height,depth
data.get3DSize(width,height,depth)

image uneven,final,split,half
if(outputFormat==0) 
	{
	uneven :=  MSA112_Make3DImageOfRightType(data.ImageGetDataType(),"",1,height,depth)
	final :=  MSA112_Make3DImageOfRightType(data.ImageGetDataType(),"",1,height,depth)
	}
else	//real
	{
	uneven :=  MSA112_Make3DImageOfRightType(2,"",1,height,depth)
	final :=  MSA112_Make3DImageOfRightType(2,"",1,height,depth)
	}

number s = width,width1,width2

//initial split
if(outputFormat==0) split := data.imageclone()
else			 	split = data	//real

while(s>1)
	{
	width1 = trunc(s/2)
//result("->"+w1)
	width2=2*width1
	half := split[0,0,0,width1,height,depth]
	half += split[width1,0,0,width2,height,depth]
	if(width2<s) uneven += split[width2,0,0,s,height,depth]
	split := half
	s=width1
	}

final	= split		
final += uneven
		
return final
}


number MSA112_AutoC_B() return 0

/******************************************************************
function: Project 3D to Bottom 3 (results in 3D, not 2D)
******************************************************************/
image  MSA112_Render3DtoBottom3(image data, number outputFormat)
{
number width,height,depth
data.get3DSize(width,height,depth)

image uneven,final,split,half
if(outputFormat==0) 
	{
	uneven :=  MSA112_Make3DImageOfRightType(data.ImageGetDataType(),"",width,1,depth)
	final :=  MSA112_Make3DImageOfRightType(data.ImageGetDataType(),"",width,1,depth)
	}
else	//real
	{
	uneven :=  MSA112_Make3DImageOfRightType(2,"",width,1,depth)
	final :=  MSA112_Make3DImageOfRightType(2,"",width,1,depth)
	}

number s = height,height1,height2

//initial split
if(outputFormat==0) split := data.imageclone()
else			 	split = data	//real

while(s>1)
	{
	height1 = trunc(s/2)
//result("\n->"+height1)
	height2=2*height1
	half := split[0,0,0,width,height1,depth]
	half += split[0,height1,0,width,height2,depth]

	if(height2<s) uneven += split[0,height2,0,width,s,depth]
	split := half
	s = height1
	}

final	= split		
final += uneven
		
return final
}



/********************************************************
	Expanding
*********************************************************/	

image MSA112_ExpandImageVertically(image small,image large)
{
number height = large.ImageGetDimensionSize(1)

image out = imageclone(large)
out = small[icol,0]

return out
}


image MSA112_ExpandImageHorizontally(image small,image large)
{
number height = large.ImageGetDimensionSize(0)

image out = imageclone(large)
out = small[0,irow]

return out
}
/*
number height = 100000
image in := integerimage("",2,0,2000,1)
in = icol
image should = integerimage("",2,0,2000,height)

number t = getOstickCount()
image out = MSA112_ExpandImageVertically(in,should)
result("\n"+CalcOSsecondsBetween(t,getOstickCount()))
*/


/********************************************************
	Binning
*********************************************************/	
image MSA112_binningBlock(image cube,number i,number j,number d,number binX,number binY)
	{
	image binnedSpec := MSA112_Make3DImageOfRightType(cube.ImageGetDataType(),"",1,1,d)

	number i0,j0
	for (number k=0;k<binX;k++) 
		{
		for(number m=0;m<binY;m++)
			{	
			i0=i*binX+k
			j0=j*binY+m
			binnedSpec += cube[i0,j0,0,i0+1,j0+1,d]
			}
		}
	return binnedSpec	
	}


//with updating prograss bar		
image MSA112_binning(object frm, image cube, number binX, number binY,number &running,number steps,number &stepped)
	{
	number w,h,d
	cube.get3Dsize(w,h,d)
	
	number wb = trunc(w/binX)
	number hb = trunc(h/binY)
	
	image binned:= MSA112_Make3DImageOfRightType(cube.ImageGetDataType(),"",wb,hb,d)

	number t 

	number Miles = round(wb/10)	
	
stepped ++
frm.MSA112_ThreadMarkStart(stepped/steps,"bin col 0","\nbin col 0",t);		
	for (number i=0;i<wb;i++)
		{			
		for (number j=0;j<hb;j++)
			{
			binned[i,j,0,i+1,j+1,d] = cube.MSA112_binningBlock(i,j,d,binX,binY)
			}	
if((mod(i,Miles)==0)&&(i>0)) 
			{
frm.MSA112_ThreadMarkEnd(running," ",t)	
stepped ++
frm.MSA112_ThreadMarkStart(stepped/steps,"bin col "+i,"\nbin col "+i,t);
			}				
		}
frm.MSA112_ThreadMarkEnd(running," ",t)	
		
	return binned
	}
	


/********************************************************
	Gaussian filtering
*********************************************************/	
	
image MSA112_Xfiltering(object frm, image cube, number sigma,number minTail,number &running,number steps,number &stepped)
	{
	number w,h,d
	cube.get3Dsize(w,h,d)	//might generate exception if not 3D
//result("\n"+Name+":"+w+"x"+h+"x"+d)
	
	number N = MSA112_CastleClip(sigma,minTail)
	if(N==0) throw("") //no filtering
	number M = MSA112_BishopClip(sigma,minTail)	//M<=N
//result("\n\nsigma "+sigma+" castle steps "+N+" bishop steps "+M)

	//check memory
	image filtered 
	try{
	filtered = cube.imageclone()
	}
	catch{result("\nNOT ENOUGH MEMORY !!");OKdialog("NOT ENOUGH MEMORY !!");}
	number Norm = 1
	
	number t = getOStickCount()
	
stepped	++
	//castle
	for(number i=1;i<=N;i++)
		{		
		number weight = exp(-(i/sigma)**2)

frm.MSA112_ThreadMarkStart(stepped/steps,"castle | "+i,"\ncastle | "+i,t)		
		filtered += cube[icol-i,irow,iplane]*weight

		filtered += cube[icol+i,irow,iplane]*weight
stepped ++
frm.MSA112_ThreadMarkEnd(running," ",t)	
frm.MSA112_ThreadMarkStart(stepped/steps,"castle - "+i,"\ncastle - "+i,t)
		filtered += cube[icol,irow-i,iplane]*weight

		filtered += cube[icol,irow+i,iplane]*weight
stepped ++
frm.MSA112_ThreadMarkEnd(running," ",t)	
			
		Norm += 4*weight		
		}

	//bishop	
	for(number i=1;i<=M;i++)
		{
		number weight = exp(-(i*sqrt(2)/sigma)**2)
		
frm.MSA112_ThreadMarkStart(stepped/steps,"bishop \\ "+i,"\nbishop \\"+i,t)	
		filtered += cube[icol-i,irow-i,iplane]*weight

		filtered += cube[icol+i,irow+i,iplane]*weight		
stepped ++			
frm.MSA112_ThreadMarkEnd(running," ",t)

frm.MSA112_ThreadMarkStart(stepped/steps,"bishop / "+i,"\nbishop /"+i,t)
		filtered += cube[icol-i,irow+i,iplane]*weight

		filtered += cube[icol+i,irow-i,iplane]*weight		
stepped ++			
frm.MSA112_ThreadMarkEnd(running," ",t)	
		
		Norm += 4*weight
		}
		
	filtered /= norm
	
	return filtered
	}

image MSA112_Efiltering(object frm, image cube, number sigma, number minTail,number &running,number steps,number &stepped)
	{
	number w,h,d
	cube.get3Dsize(w,h,d)	//might generate exception if not 3D
	string Name = Cube.ImageGetName()
		
	number N = MSA112_CastleClip(sigma,minTail)
	if(N==0) throw("") //no filtering
//result("\n\nsigma "+sigma+" elevator steps "+N)

//result("\n\nsigma "+sigma+" N "+N+" M "+M)

	//check memory
	image filtered 
	try{
	filtered = cube.imageclone()
	}
	catch{result("\nNOT ENOUGH MEMORY !!");OKdialog("NOT ENOUGH MEMORY !!");}
	
	number Norm = 1
	
	number t = getOStickCount()

stepped ++	
	//elevator
	for(number i=1;i<=N;i++)
		{	
		number weight = exp(-(i/sigma)**2)
//result("\ni "+i+" weight "+weight)	
frm.MSA112_ThreadMarkStart(stepped/steps,"elevator "+i,"\nelevator "+i,t)
		
		filtered += cube[icol,irow,iplane+i]*weight
		
		filtered += cube[icol,irow,iplane-i]*weight
			
		Norm += 2*weight
		

stepped ++
frm.MSA112_ThreadMarkEnd(running," ",t)
		}
		
	filtered /= norm	

	return filtered
	}



/********************************
		ALS
*********************************/

image MSA112_ALStep(image D,image T,image unity)
	{
	return MSA112_ALStepBase(D,T,unity)
	}
	
image MSA112_ALStep(image D,image T,number lambda)
	{
	return MSA112_ALStepBase(D,T,lambda)
	}
	
	
	
	
/********************************
Operations numpy enchanced ERZATZ
*********************************/

string MSA112_InstallPython() return ""


number MSA112_PythonInstalled() return (-1) //1  : installed, 0 : not installed
											//-1 : not possible to install


image MSA112_matrixMultiply(image matB,image matA)
{
return matrixMultiply(matB,matA)
}

//erzats
void MSA112_SVD(image &matU,image &matV,image &matS,image matD)
{
}

void MSA112_SetLineThickness(imagedisplay imdisp, number index,number thick)
	{
	}