//This is useful to correct for z- and xy- drift across timepoints. //Uses turboreg plugin to align a hyperstack in z and/or in xy. //The alignment is based on a max projection of the xz reslice for //the z-alignment, and a regular xy max projection for xy alignment //Currently only can use one of the channels to align. //This will not align the slices of a particular individual time point, //for that use Align Z forEachTimePoint title=getTitle(); IID=getImageID(); getDimensions(w,h,chs,sls,frms); bits=bitDepth(); if(bits!=24)textLuts=getTextLUTs(); setPasteMode("Copy"); Zname=title + "-Zalign"; if(sls<2 && frms< 2) exit("Requires hyperstack with multi z and frames"); if(bits==24){ charray=newArray("all","red","green","blue"); }else{ charray=newArray(chs); for(i=0;islicesmin+zReg[k]+noslices-1)){ setSlice(n+1+i+(j*chs)+(k*chs*sls)); run("Delete Slice"); n--; } } } } run("Stack to Hyperstack...", "order=xyczt(default) channels="+chs+" slices="+noslices+" frames="+frms+" display=Composite"); mdata=""+zReg[0]; for(i=1;i0) rorl="Left"; if(ypos>0) torb="Top"; run("Canvas Size...", "width="+wid+" height="+hei+" position="+torb+"-"+rorl+" zero"); if(abs(rotangle)>0.5)run("Rotate... ", "angle="+rotangle+" grid=0 interpolation=None"); run("Concatenate...", "stack1=frm"+(i)+" stack2=frm"+(i+1)+" title=frm"+(i+1)); } selectWindow("frm"+i); run("Stack to Hyperstack...", "order=xyczt(default) channels="+chs+" slices="+sls+" frames="+frms+" display=Composite"); rename("XYalign"); if(bits!=24)setTextLuts(textLuts); selectWindow("targ"); close(); accepted=true; if(!autoaccept) { run("Z Project...", "projection=[Max Intensity] all"); zxyID=getImageID(); setLocation(800,300); selectImage(zID); setLocation(100,300); waitForUser("Check z-projections"); accepted=getBoolean("Accept xy-reg changes?"); } selectImage(zID); close(); if(!autoaccept){selectImage(zxyID); close;} if(accepted) { selectWindow("XYalign"); rename(XYname); if(doz){ rename(title+"-XYZalign"); selectWindow(Zname); close;} } else {selectWindow("XYalign"); close;} print("XY Registration concluded"); if(isOpen("Refined Landmarks")){ print("[Refined Landmarks]","\\Clear"); print("[Refined Landmarks]","\\Close"); } } //if(doxy && stilldo) wait(100); showProgress(0.5); showProgress(1.0); function getRegData(){ sourceX0 = getResult("sourceX", 0); // First line of the table. sourceY0 = getResult("sourceY", 0); targetX0 = getResult("targetX", 0); targetY0 = getResult("targetY", 0); dx1 = sourceX0 - targetX0; dy1 = sourceY0 - targetY0; //print("\\Update:Translation [pixel]: " + dx1 +" in X and "+dy1+" in Y"); //translation = sqrt(dx1 * dx1 + dy1 * dy1); // Amount of translation, in pixel units. if(nResults>1){ sourceX1 = getResult("sourceX", 1); // Second line of the table. sourceY1 = getResult("sourceY", 1); targetX1 = getResult("targetX", 1); targetY1 = getResult("targetY", 1); sourceX2 = getResult("sourceX", 2); // Third line of the table. sourceY2 = getResult("sourceY", 2); targetX2 = getResult("targetX", 2); targetY2 = getResult("targetY", 2); dx = sourceX2 - sourceX1; dy = sourceY2 - sourceY1; sourceAngle = atan2(dy, dx); dx = targetX2 - targetX1; dy = targetY2 - targetY1; targetAngle = atan2(dy, dx); rotation = targetAngle - sourceAngle; // Amount of rotation, in radian units. //print("Amount of rotation [degree]: " + (rotation * 180.0 / PI)); rotangle=(rotation * 180.0 / PI); return newArray(dx1, dy1, rotangle); } else return newArray(dx1,dy1); } function addArray(item, array){ temparray=newArray(array.length+1); for(i=0; i