#pragma rtGlobals=1 // Use modern global access method. #pragma version = 1.0 Menu "Macros" "-" "(Old methods" " Calculate Grains from Axes Histogram",findGrainsByAxesHist(NaN) End // Histograming Rodriguiez space is probably a bad idea. Stick to the total rotation angle. // so use the (Hx,Hy,Hz)(Kx,Ky,Kz)(Lx,Ly,Lz) matrix // =================================================================== // =================================================================== // =================================================================== // Most of the following functions has to do with histograming Rodriguiez space. // =================================================================== Function findGrainsByAxesHist(maxGrains) // find the grains by looking at a histogram of the axes Variable maxGrains // maximum number of grains to find if (numtype(maxGrains) || maxGrains<1) maxGrains = 10 Prompt maxGrains, "maximum number of grains to find" DoPrompt "max no. of grains",maxGrains if (V_flag) return 0 endif endif Wave axisX=:raw:axisX,axisY=:raw:axisY,axisZ=:raw:axisZ Wave indicies=indicies Variable N=numpnts(axisX) Make/N=(N,3)/O axes // make a single matrix to hold the 3 axisN components axes[][0] = axisX[p] // rotaion axis (and magnitude) for each measured voxel axes[][1] = axisY[p] axes[][2] = axisZ[p] Wave XYZindex=:raw:XYZindex Duplicate/O XYZindex grains // a 3d space to hold the grain numbers called grains grains = NaN Variable Ngrains=0 Variable delta // scaled step size in Hist3dAxes[][][] for all 3 dimensions STRUCT peak3D peak // holds peak result from Histogram3dAxisSpace() String str Variable Nixyz STRUCT boxStruct box Variable i,j, ix,iy,iz, Nadded,Ntotal=0 Make/N=(maxGrains)/O Nincrement Nincrement = NaN if (debugN) WaveStats/Q axes printf "before starting axes has %g valid triplets\r",V_npnts/3 endif Variable tick0=ticks do // Variable timer = startMSTimer str = Histogram3dAxisSpace(axes,peak) // peak position is at (peak.ix,peak.iy,peak.iz) //printf "Histogram3dAxisSpace() took %g msec\r",stopMSTimer(timer)/1000 Wave Hist3dAxes = $StringByKey("HIST",str,"=") // a 3d histogram of axes[N][3] if (Ngrains0) Redimension/N=(N,3) ixyz // trim to exact size // now ixyz[N][3] are the list of indicies into in3d[][][] that form a contiguous particle KillWaves/Z checkNext, ixyzNEW return N End // go through checkNext[][] and remove points out of range, invalid, or already identifiec Static Function Valid_checkNext(checkNext,Ncheck,Nx,Ny,Nz,ixyz,Nixyz) Wave checkNext // checkNext[Ncheck][3], triplets to check Variable Ncheck // number of points in checkNext to check Variable Nx,Ny,Nz // valid range of ix=[0,Nx-1], iy=[0,Ny-1], iz=[0,Nz-1] Wave ixyz // list of found voxels, do not want duplicates Variable Nixyz // length of ixyz[][3] Variable i,j,ix,iy,iz // check for duplicate in checkNext[Ncheck][3] for (i=0;i=Nx || iy>=Ny || iz>=Nz || ix<0 || iy<0 || iz<0) checkNext[i][0] = -Inf // this flags an invalid point to check checkNext[i][1] = -Inf checkNext[i][2] = -Inf // check that each triplet has already been identified elseif (point_in_list(ix,iy,iz,ixyz,Nixyz)) checkNext[i][0] = -Inf // this flags an invalid point to check checkNext[i][1] = -Inf checkNext[i][2] = -Inf endif endfor End Function runHist3dAxis() STRUCT peak3D peak String str = Histogram3dAxisSpace(axes,peak) print str printf "ix=%g;iy=%g;iz=%g;x=%g;y=%g;z=%g\r",peak.ix,peak.iy,peak.iz,peak.x,peak.y,peak.z End // take the set of 3vectors (axisX, axisY, axisZ), and histogram them into a 3d space named Hist3dAxes // each point in Hist3dAxes represents a single orientation. So the peak in Hist3dAxes is the biggest grain. // for each vector (axisX[i], axisY[i], axisZ[i]), the length is the angle of rotation, and the direction // the axis, so that angle ~ sqrt(axisX^2+axisY^2+axisZ^2)*180/PI/2 * 1.04386 Function/S Histogram3dAxisSpace(axes,peak) Wave axes STRUCT peak3D &peak //Variable timer = startMSTimer if (DimSize(axes,1)!=3 || DimSize(axes,2)) DoAlert 0, "dimensiont of axes must be axes[N][3]" return "" endif String fldr = GetWavesDataFolder(axes,1) Variable N = DimSize(axes,0) String wName = UniqueName("axisTemp",1,0) Make/N=(N) $wName Wave axis=$wName Variable Xmin, Xmax, Ymin,Ymax, Zmin, Zmax axis = axes[p][0] WaveStats/Q axis Xmin = V_min ; Xmax = V_max axis = axes[p][1] WaveStats/Q axis Ymin = V_min ; Ymax = V_max axis = axes[p][2] WaveStats/Q axis Zmin = V_min ; Zmax = V_max KillWaves/Z axis // printf "range of axisX is [%g, %g], Æ=%g\r",Xmin,Xmax,Xmax-Xmin // printf "range of axisY is [%g, %g], Æ=%g\r",Ymin,Ymax,Ymax-Ymin // printf "range of axisZ is [%g, %g], Æ=%g\r",Zmin,Zmax,Zmax-Zmin Variable amin = min(min(Xmin,Ymin),Zmin) Variable amax = max(max(Xmax,Ymax),Zmax) Variable Nx,Ny,Nz, NN=20 NN = 2*round(N^0.333333) Variable delta = (amax-amin)/(NN-1) Nx = ceil((Xmax-Xmin)/delta) + 1 Ny = ceil((Ymax-Ymin)/delta) + 1 Nz = ceil((Zmax-Zmin)/delta) + 1 if (ItemsInList(GetRTStackInfo(0))<2) printf "max range is [%g, %g] dimensions=(%d,%d,%d)\r",amin,amax,Nx,Ny,Nz endif String HistName = fldr+"Hist3dAxes" Make/N=(Nx,Ny,Nz)/O $HistName Wave Hist3dAxes=Hist3dAxes Hist3dAxes = 0 SetScale/P x Xmin,delta, "", Hist3dAxes SetScale/P y Ymin,delta, "", Hist3dAxes SetScale/P z Zmin,delta, "", Hist3dAxes Variable i, ix,iy,iz //printf " up to loop in Histogram3dAxisSpace() took %g msec\r",stopMSTimer(timer)/1000 //timer = startMSTimer for (i=0;ibox.xhi) return 0 endif if (yybox.yhi) return 0 endif if (zzbox.zhi) return 0 endif return 1 End Static Structure peak3D Variable ix,iy,iz Variable x,y,z EndStructure Static Structure boxStruct Variable xlo,xhi,ylo,yhi,zlo,zhi EndStructure