//This is useful to correct for z- and xy- drift across timepoints. //Uses TurboRegplugin 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 turboregstring="TurboReg"; List.setCommands; if(List.get(turboregstring)=="")turboregstring="TurboReg "; if(List.get(turboregstring)=="") exit("This macro requires TurboReg"); stackregstr="StackReg"; if(List.get(stackregstr)=="")stackregstr="StackReg "; if(List.get(stackregstr)=="") exit("This macro requires "+stackregstr); title=getTitle(); IID=getImageID(); oIID=IID; getVoxelSize(px,py,pz,unit); getDimensions(w,h,chs,sls,frms); substack="1-"+sls; bits=bitDepth(); logarray=false; setPasteMode("Copy"); Zname=title + "-Zalign"; if(sls==1 || frms==1) exit("Requires hyperstack with multi frames"); if(bits==24){ charray=newArray("all","red","green","blue"); }else{ charray=newArray(chs); for(i=0;i-1 && indexOf(Table.headings,"SourceX1")>-1 ){ print("Results Table found: "+list[i]+" as a StackReg Table"); ptarray=true; srarray=true; } } } } } if(nResults>0 && nResults%frms==0) {ptarray=true;} if(!ptarray){ logstr=split(getInfo("log"),"\n"); ll=logstr.length; st=-1;end=-1; for(i=0;i1) run("Stack to RGB"); title=getTitle(); for(i=1;i<=frms;i++){ selectWindow(title); run("Duplicate...", "title="+i+" duplicate frames="+i); if(chs>1)Stack.setChannel(xychchoice); run(stackregstr, "transformation=Affine"); if(i!=1) run("Concatenate...", "stack1=1 stack2="+i+" title=AJZALIGNTEMP"); } rename(title+"-slicealign"); run("Stack to Hyperstack...", "order=xyczt(default) channels="chs" slices="+sls+" frames="+frms); } startsub=1; endsub=sls; if(substack!="") { if(indexOf(substack,"-")==-1){ startsub=round(substack); endsub=round(substack); } else { substa=split(substack,"-"); startsub=parseInt(substa[0]); endsub=parseInt(substa[1]); } if(startsub>endsub) {tempsub=startsub; startsub=endsub; endsub=tempsub;} } xyaccepted=true; if(doxy){ if(xymode=="Auto"){ if(srarray){ selectWindow("StackReg Results"); IJ.renameResults("StackReg Results","StackReg Results z"); } selectImage(IID); run("Z Project...", "start=startsub stop=endsub projection=[Max Intensity] all"); Stack.setFrame(1); Stack.setChannel(xychchoice); zid=getImageID(); run(stackregstr,"transformation=Translation show"); if(!autoaccept){ waitForUser("Check StackReg"); xyaccepted=getBoolean("Accept xy-reg changes?"); } selectImage(zid); close(); } if(xyaccepted) run("Image Translator by Pt", "align=[First slice] adjust"); } z=newArray(frms); if(!xyaccepted && doz){if(!getBoolean("Run Z-align anyway?"))exit();} if(doz){ zaccepted=true; if(zmode=="Auto"){ z[0]=0; bh=h*0.15; makeRectangle(0, h/2-bh/2, w, bh); run("Reslice [/]...", "start=Top"); rid=getImageID(); run("Z Project...", "projection=[Max Intensity] all"); rzid=getImageID(); selectImage(rid); close(); selectImage(rzid); Stack.setChannel(zchchoice); Stack.setFrame(1); getDimensions(rzw, rzh, rzch, rzsl, rzfrs); zfac=rzh/sls; run(stackregstr,"transformation=Translation show"); if(isOpen("Refined Landmarks")){ //print("[Refined Landmarks]","\\Clear"); //print("[Refined Landmarks]","\\Close"); } print("[Results]","\\Clear"); print("[Results]","\\Close"); selectWindow("StackReg Results"); info=getInfo("window.contents"); info=split(info,"\n"); for(i=1;i