Moment Macro J
StartupMacros.txt — Čistý text, 21 KB (21914 bytes)
Obsah souboru
var IJPath="C:\\Program Files\\ImageJ-FIJI\\"; //cestu nech v uvozovkach. Mozna budes muset separatory zmenit napriklad ve win z \ na \\. var original, originalID, name; var option; var Sn,Sx,Sy,Sxx,Syy,Sxy,rot2,density,Centrex,Centrey,Theta, R1,R2; var original, scalar, units, TA, CA, Cx, Cy, Ix, Iy, Imax, Imin, Zx, Zy, Xmaxrad, Ymaxrad, xmin, ymin, xmax, ymax; macro "Batch measure [n0]" { //zmeri vsechny pozadovane soubory v adresari if (is("Batch Mode")) setBatchMode(false); option=getOptions(); if (!File.isDirectory(option[5])) { option[5]=getDirectory("Choose a measurements output directory"); // option[4]=false; setOptions(option); } inputPath=getDirectory("Choose a directory with INPUT data"); Dialog.create("Input options"); Dialog.addMessage("Choose type of data to measure"); Dialog.addChoice("Image type:", newArray(".TIFF [images]", ".zip [selections]")); Dialog.show(); dataType = Dialog.getChoice(); //get dataType for analysis; if (dataType==".TIFF [images]") dataType=".tif"; if (dataType==".zip [selections]") dataType=".zip"; fileList=getFileList(inputPath); for (i=0; i<fileList.length; i++) { if (endsWith(fileList[i], dataType)) { roiManager("reset"); open(inputPath+fileList[i]); if (dataType==".tif") MomentMacroJ(); if (dataType==".zip") measureSelection(); close(); } } } macro "MomentMacroJ [n1]" { MomentMacroJ(); } macro "Measure Selection [n2]" { measureSelection(); } macro "Options [n3]"{ option=getOptions(); Dialog.create("MomentMacro options"); Dialog.addMessage("This plugin is considered to analyze\nMRI or Confocal bone sections"); Dialog.addChoice("Image type:", newArray("Confocal", "MRI"), option[0]); Dialog.addChoice("Boundaries creation:", newArray("Semi-Automated", "Automated", "Manual"),option[1]); Dialog.addCheckbox("Show selection", option[2]); Dialog.addCheckbox("Show principal axes", option[3]); Dialog.addCheckbox("Get destination directory", option[4]); Dialog.addMessage("Actual output directory:"); Dialog.addMessage(option[5]); Dialog.show(); option[0] = Dialog.getChoice(); //image Type; option[1] = Dialog.getChoice(); //selection method option[2] = Dialog.getCheckbox(); //show selection option[3] = Dialog.getCheckbox(); //show axes option[4] = Dialog.getCheckbox(); //read output directory // option[5] - OUTPUT directory if (option[4]==true) { option[5]=getDirectory("Choose an measurements output directory"); // option[4]=false; } if (!File.isDirectory(option[5])) option[5]="None"; setOptions(option); } //end of macro Options //******************************************************************************* FUNCTIONS *************************************************************************************************************************************** //************************** overiding functions ******************* function MomentMacroJ(){ if (is("Batch Mode")) setBatchMode(false); option=getOptions(); if (!File.isDirectory(option[5])) { option[5]=getDirectory("Choose an measurements output directory"); // option[4]=false; setOptions(option); } originalID=getImageID(); original=getTitle(); name=replace(original, ".tif", ""); // kontrola kalibrace obrazu na mm AutoCalibrateImage(); channel=findRelevantChannel(); // pripravi obrazek a relevantni kanal pro analyzu originalID=getImageID(); run("Select None"); run("Duplicate...", "title=mask1 duplicate channels="+channel); //duplikuje relevantni kanal pro vytvoreni ROI if (option[1]=="Automated") { AutoSelectOuter(); AutoSelectInner(); } else if (option[1]=="Semi-Automated"){ // semi automated method outer selection AutoSelectOuter(); index=roiManager("index"); run("Fit Spline"); resetThreshold(); waitForUser("Outer Selection Adjustment","Now adjust manually outer selection.\n Outer space"); // roiManager("Select", index); roiManager("Update"); // semi-automated method inner selection AutoSelectInner(); index=roiManager("index"); run("Fit Spline"); waitForUser("Inner Selection Adjustment","Now adjust manually inner selection.\n"); // roiManager("Select", index); roiManager("Update"); } else if (option[1]=="Manual") waitForUser("Manual Selection","Now adjust manually outer & inner selection.\nSend both to roi Manager by pressing 't'.\nThen press OK"); checkROIs(); selectImage("mask1"); close(); selectImage(originalID); checkROIs(); measureMoments(); saveResults(); } //end of momentMacroJ.... //*********************** measureSelection *************************** function measureSelection() { if (is("Batch Mode")) setBatchMode(false); option=getOptions(); if (!File.isDirectory(option[5])) { option[5]=getDirectory("Choose an measurements output directory"); // option[4]=false; setOptions(option); } // option[2]=1; // option[3]=1; name=File.nameWithoutExtension; name=replace(name, ".tif", ""); if (roiManager("count")==0) exit("No Selections in ROI Manager!!!"); newImage("examine", "8-bit Black", 1, 1, 1); checkROIs(); getSelectionBounds(x, y, width, height); selectImage("examine"); close(); newImage(name+".tif", "8-bit Black", (width+1), (height+1), 1); original=getTitle(); AutoCalibrateImage(); channel=findRelevantChannel(); originalID=getImageID(); checkROIs(); setSelectionLocation(0,0); updateSelection(); setForegroundColor(50, 50,50); Stack.setDisplayMode("color"); run("Fill", "slice"); Stack.setDisplayMode("composite"); measureMoments(); saveResults(); } //************************** findRelevantChannel ***************** function findRelevantChannel(){ if (getMetadata("info")!="prepared" || !Stack.isHyperstack) prepareImage(); // kontrola, ze obrazek je pripraveny Stack.getDimensions(width, height, channels, slices, frames); if (channels==5 || channels==3) { channel=round((channels-2)/2); } else { showMessageWithCancel("unexpected channel number","The number of channels should now be 5 or 3"); waitForUser("select channel for analysis", "Please, select the channel for analysis (e.g. set slicer on appropriate channel)"); Stack.getPosition(channel, s, f); } return(channel); } //************************** PREPAREIMAGE ********************** // pruzkum obrazku, priprava do compositu function prepareImage() { //1 obrazek je RGB image=getTitle(); if (bitDepth()==24) { run("Make Composite"); selectImage(image); getDimensions(width, height, channels, slices, frames); } hyperstack=Stack.isHyperstack; //1. je to hyperstack nebo neni if (hyperstack) { Stack.getDimensions(width, height, channels, slices, frames); } if (!hyperstack){ // Kdyz neni hyperstack getDimensions(width, height, channels, slices, frames); if (is("composite")) { run("Stack to Hyperstack...", "order=xyczt(default) channels="+channels+" slices="+slices+" frames="+frames+" display=Composite"); selectImage(image); Stack.getDimensions(width, height, channels, slices, frames); } } if (slices!=1) { //!!!!!! dotaz na projekci !!!!!!!!!!!!!1 waitForUser("Z-Projection","Now examine your stack and decide which slices to include into Z-projection.\nFirst and Last."); run("Z Project..."); max=getTitle(); selectImage(image); close(); selectImage(max); rename(image); } getDimensions(width, height, channels, slices, frames); if (is("composite")) { run("Stack to Hyperstack...", "order=xyczt(default) channels="+channels+" slices="+slices+" frames="+frames+" display=Composite"); if (getMetadata("info")!="prepared") { setSlice(nSlices); run("Add Slice"); setSlice(nSlices); run("Yellow"); setMetadata("Label", "selection"); run("Add Slice"); setSlice(nSlices); run("Cyan"); setMetadata("Label", "principal axes"); setSlice(2); setMetadata("info", "prepared"); } } else { getLut(reds, greens, blues); run("Add Slice"); run("Add Slice"); run("Stack to Hyperstack...", "order=xyczt(default) channels="+channels+2+" slices="+slices+" frames="+frames+" display=Composite"); setLut(reds, greens, blues); setSlice(nSlices-1); run("Yellow"); setMetadata("Label", "selection"); setSlice(nSlices); run("Cyan"); setMetadata("Label", "principal axes"); setSlice(1); setMetadata("info", "prepared"); } } //************************** RECALIBRATE ************************ function recalibrate(){ getVoxelSize(width, height, depth, unit); fail=true; if (unit=="pixels") { lastName=File.name; if (endsWith(lastName,".zip")) { lastName=replace(lastName, ".zip", ".tif"); lastName=replace(lastName, ".txt", ".tif"); path=File.directory; fileName=path+lastName; if (File.exists(fileName)) { open(fileName); getVoxelSize(width, height, depth, unit); close(); setVoxelSize(width, height, depth, unit); fail=false; } } else if (endsWith(lastName, ".tif")) { path=File.directory; fileName=path+lastName; if (File.exists(fileName)) { open(fileName); getVoxelSize(width, height, depth, unit); close(); setVoxelSize(width, height, depth, unit); fail=false; } } } if (unit==getInfo("micrometer.abbreviation") || unit=="um" || unit=="microns") { setVoxelSize(width/1000, height/1000, depth/1000, "mm"); fail=false; } if (unit=="m" && width!=1){ run("Properties...", "unit=um"); fail=false; } if (unit=="cm"&& width!=1) { setVoxelSize(width*10, height*10, depth*10, "mm"); fail=false; } if (fail) waitForUser("Automatic calibration failed", "Please, calibrate image manually in mm...\nThen press OK"); } //************************** AUTOCALBRATEIMAGE **************** function AutoCalibrateImage() { error=false; // pokus o automatickou kalibraci obrazku z konfokalu lastPath=File.directory; lastName=File.name; if (indexOf(lastName,"_")!=-1) { leiName=substring(lastName,0, indexOf(lastName,"_")); if (indexOf(lastName,"_z")==-1 && (indexOf(lastName,"_ch")==-1)) endString=lengthOf(lastName); else if (indexOf(lastName,"_z")!=-1) endString=indexOf(lastName, "_z"); else if (indexOf(lastName,"_z")==-1 && indexOf(lastName,"_ch")!=-1) endString=indexOf(lastName, "_ch"); imageName=substring(lastName, indexOf(lastName,"_")+1, endString); isThereLei=File.exists(lastPath+leiName+".lei"); isThereTxt=File.exists(lastPath+leiName+".txt"); if (isThereLei && isThereTxt){ TXTfile=File.openAsString(lastPath+leiName+".txt"); namePos=indexOf(TXTfile, imageName); voxPos=indexOf(TXTfile, "Voxel-Width", namePos); voxel=substring(TXTfile, voxPos+16, indexOf(TXTfile, "\n", voxPos)-1); voxel=parseFloat(voxel); zvoxPos=indexOf(TXTfile, "Voxel-Depth", namePos); zvoxel=substring(TXTfile, zvoxPos+16, indexOf(TXTfile, "\n", zvoxPos)-1); zvoxel=parseFloat(zvoxel); if (isNaN(voxel) || isNaN(zvoxel)) error=true; else { if (isOpen(lastName)) { selectImage(lastName); setVoxelSize(voxel, voxel, zvoxel, getInfo("micrometer.abbreviation")); } } } } if (error || !calControl()) errorHandle(); } //************************** ERRORHANDLE *************************** function errorHandle(){ cal=false; while (cal==false) { recalibrate(); cal=calControl(); } } //************************** CALCONTROL **************************** function calControl() { getPixelSize(unit, v, h); if (unit=="mm") return true; else return false; } //***************************GETOPTIONS****************************** function getOptions(){ keys = getList('java.properties'); // IJPath=getInfo(keys[1]); if (File.exists(IJPath+"MomentMacro.cfg")) { options=File.openAsString(IJPath+"MomentMacro.cfg"); options=split(options, "\n"); } else options=newArray("Confocal", "Semi-Automated", true, true, true, "None"); return options; } //***************************SETOPTIONS****************************** function setOptions(options){ ent="\n"; string=""; for (i=0; i<options.length; i++) string=string+options[i]+ent; keys = getList('java.properties'); // IJPath=getInfo(keys[1]); File.saveString(string, IJPath+"MomentMacro.cfg"); } //***************************estimateSize********************************* function estimateSize(){ run("Select None"); setAutoThr(); run("Create Selection"); getStatistics(area); run("Select None"); return area/3; } //************************************* AutoSelectInner ***************************************** function AutoSelectInner(){ getPixelSize(unit, pixelWidth, pixelHeight); run("Set Measurements...", " mean standard centroid redirect=None decimal=3"); List.setMeasurements; X = List.getValue("X")/pixelWidth; Y = List.getValue("Y")/pixelHeight; mean = List.getValue("Mean"); std = List.getValue("StdDev"); resetThreshold(); run("Select None"); if (option[0]=="MRI" || bitDepth()!=8) WandParam=mean; if (option[0]=="Confocal" || bitDepth()==8) WandParam=maxOf(mean,std)/minOf(mean,std); doWand(X, Y, WandParam, "legacy"); while (selectionType==-1) waitForUser("Automatic Inner Selection failed", "Please define inner selection manualy.\nThen press OK."); roiManager("Add"); roiManager("Select", roiManager("count")-1); roiManager("Rename", "Inner"); } function setAutoThr() { if (option[0]=="MRI") setAutoThreshold("Minimum dark"); if (option[0]=="Confocal") setAutoThreshold("Huang dark"); } //********************************************AutoSelectOuter() ********************************* function AutoSelectOuter(){ roiManager("reset"); run("Copy"); if (option[0]=="Confocal") run("Gaussian Blur...", "sigma=3"); estSize=estimateSize(); setAutoThr(); run("Analyze Particles...", "size="+estSize+"-Infinity circularity=0.00-1.00 show=Nothing clear add"); do { //kontrola pochodu vyberu vnejsi selekce if (roiManager("count")==0) { waitForUser("Automatic Outer Selection failed", "Please define inner selection manualy.\nThen press OK."); roiManager("Add"); } else if (roiManager("count")>1) { do {waitForUser("Automatic Outer confused", "Please select manualy appropriate selection in ROI manager.\nAlternatively add new selection by pressing 't' end select.\nThen press OK."); } while (roiManager("index")==-1); roiManager("Select", roiManager("index")); roiManager("reset"); roiManager("Add"); } }while (!roiManager("count")==1) run("Paste"); setAutoThr(); roiManager("Select", 0); roiManager("Rename", "Outer"); } //****************************************CHECKROIS******************************************** function checkROIs() { while (roiManager("count")!=2) waitForUser("Too many ROIs in Manager", "Please leave only outer and inner selection in ROI manager.\nThen press OK."); roiManager("Deselect"); resetMinAndMax(); roiManager("XOR"); } //*************************************** DRAWAXES ******************************************** function DrawAxis() { //optional function to draw major/minor axis of ellipse run("Select None"); moveTo(Centrex,Centrey); setColor(255,255,255); lineTo(Centrex-(cos((0-Theta)*3.141592654/180)*2*R1), Centrey+(sin((0-Theta)*3.141592654/180)*2*R1)); moveTo(Centrex,Centrey); lineTo(Centrex-(cos((Theta+90)*3.141592654/180)*2*R2), Centrey-(sin((Theta+90)*3.141592654/180)*2*R2)); moveTo(Centrex,Centrey); lineTo(Centrex+(cos((0-Theta)*3.141592654/180)*2*R1), Centrey-(sin((0-Theta)*3.141592654/180)*2*R1)); moveTo(Centrex,Centrey); lineTo(Centrex+(cos((Theta+90)*3.141592654/180)*2*R2), Centrey+(sin((Theta+90)*3.141592654/180)*2*R2)); } //**************************** SQR****************** function sqr(n) { return n*n; } //*******************************CALCSUMS******************************************************* function CalcSums() { Sn=0; Sx=0; Sy=0; Sxx=0; Syy=0; Sxy=0; vyska=ymin+ymax; sirka=xmin+xmax; for (y=ymin; y<=vyska; y++) { showStatus("Calculation in progress....."); showProgress(y/ymax); for (x=xmin; x<=sirka; x++) { if (selectionContains(x, y)==true){ Sn=Sn+1; Sx=Sx+(x*cos(rot2)+y*sin(rot2)); Sy=Sy+(y*cos(rot2)-x*sin(rot2)); Sxx=Sxx+sqr((x*cos(rot2)+y*sin(rot2))); Syy=Syy+sqr((y*cos(rot2)-x*sin(rot2))); Sxy=Sxy+((y*cos(rot2)-x*sin(rot2))*(x*cos(rot2)+y*sin(rot2))); } } } } //************************************ MEASURE MOMENTS******************************************* function measureMoments(){// This macro calculates the anisometry and bulkiness of binary particles // based on the dynamically equivalent ellipse as defined by Medalia (1970). setBatchMode(true); getPixelSize(unit, pixelWidth, pixelHeight); scalar=pixelWidth; units=unit; selectImage(originalID); getSelectionBounds(xmin,ymin,xmax,ymax); // ymin is measured from top,xmin from left // xmax & ymax= diameters along x & y axes //Calculate Moments CalcSums(); if (Sn==0) { showMessage("Selection too narrow. Exit calculation"); exit; } Cx=Sx/Sn-1; //x-coord. of Centroid Cy=Sy/Sn-1; //y-coord. of Centroid Centrex=Cx; Centrey=Cy; // following code calculates y (dist from neutral axis) if (((ymax + ymin) - Cy) > (Cy - ymin)) { Ymaxrad= ymax + ymin - Cy; Yminrad= Cy - ymin; BigY= Ymaxrad; } else { Ymaxrad= Cy - ymin; Yminrad= ymax + ymin - Cy; BigY= Ymaxrad; } // following code calculates x (dist from neutral axis) if (((xmax + xmin) - Cx) > (Cx - xmin)) { Xmaxrad= xmax + xmin - Cx; Xminrad= Cx - xmin; BigX= Xmaxrad; } else { Xmaxrad= Cx - xmin; Xminrad= xmax + xmin - Cx; BigX= Xmaxrad; } Xmaxrad= Xmaxrad*scalar; //calibrating radii Xminrad= Xminrad*scalar; Ymaxrad= Ymaxrad*scalar; Yminrad= Yminrad*scalar; Myy=Sxx-(Sx*Sx/Sn); Mxx=Syy-(Sy*Sy/Sn); Mxy=Sxy-(Sx*Sy/Sn); if (Mxy==0) { Theta=0; } else { Theta=atan(((Mxx-Myy)+sqrt(sqr(Mxx-Myy)+(4*sqr(Mxy))))/(2*Mxy))*180/3.141592654; } //end CA Cx = Cx*scalar; //save x-coord of centroid Cy= Cy*scalar; //save y-coord of centroid BigX= BigX*scalar; //calibrating x,y,Cx,Cy BigY= BigY*scalar; Ix= Mxx*(sqr(sqr(scalar))); //save mom about x-axis Iy= Myy*(sqr(sqr(scalar))); Zx= Ix/BigY; //save section moduli Zy= Iy/BigX; rot2=Theta*3.141592654/180; CalcSums(); Parea=Sn; M1=Sxx-(Sx*Sx/Sn); M2=Syy-(Sy*Sy/Sn); R1=sqrt(M1/Parea); R2=sqrt(M2/Parea); Imax= M1*(sqr(sqr(scalar))); Imin= M2*(sqr(sqr(scalar ))); Rmaks= R1*scalar; Rmyn= R2*scalar; rot2=0; //Theta= -Theta; //REMOVED due to no apparent function and gives incorrect principal axes (5/24/2005) //calculate TA roiManager("Deselect"); roiManager("OR"); getStatistics(Tarea); roiManager("AND"); getStatistics(Carea); TA = Tarea; CA= Tarea-Carea; //end TA setBatchMode(false); } // End of main macro "Calculating Moments" //********************************************save results******************************************************* function saveResults(){ setForegroundColor(255, 255, 255); setBackgroundColor(0,0,0); Stack.getDimensions(width, height, channels, slices, frames); //Draw selection selectImage(originalID); Stack.setDisplayMode("color"); Stack.setChannel(channels-1); clearChannel(); roiManager("Deselect"); roiManager("XOR"); run("Draw", "slice"); resetMinAndMax(); //Draw principal axes Stack.setChannel(channels); clearChannel(); DrawAxis(); resetMinAndMax(); Stack.setDisplayMode("composite"); //displays the results in the upper left corner of the text window path=option[5]; name=indexName(name); setFont('Monaco',10); tab=fromCharCode(0009); if(!isOpen("Log")) { print("Name"+tab+"Scale"+tab+"TA"+tab+"CA"+tab+"Xbar"+tab+"Ybar"+tab+"Ix"+tab+"Iy"+tab+"Imax"+tab+"Imin"+tab+"Theta"+tab+"Zx"+tab+"Zy"+tab+"MaxXrad"+tab+"MaxYrad"); } print(name+tab+scalar+units+"/pixel"+tab+TA+tab+CA+tab+Cx+tab+Cy+tab+Ix+tab+Iy+tab+Imax+tab+Imin+tab+Theta+tab+Zx+tab+Zy+tab+Xmaxrad+tab+Ymaxrad); run("Channels Tool... "); selectWindow("Log"); saveAs("Text", path+name+".txt"); // File>Save As>Text selectImage(originalID); activeChannels=activateChannels(channels); Stack.setActiveChannels(activeChannels); run("Stack to RGB"); saveAs("Tiff", path+name+".tif"); close(); roiManager("Deselect"); roiManager("Save", path+name+".zip"); selectImage(originalID); rename(name+".tif"); } // End of "saveResults" //********************** activate channels ******************** function activateChannels(channels) { array=newArray(channels); Array.fill(array, 1); if (!option[2]) array[channels-2]=0; if (!option[3]) array[channels-1]=0; string=""; for (i=0; i<array.length; i++) { string=string+d2s(array[i],0); } return string; } //********************* updateSelection ******************* function updateSelection(){ roiManager("Reset"); roiManager("add"); roiManager("Split"); roiManager("Select", 2); roiManager("Rename", "Outer"); roiManager("Select", 1); roiManager("Rename", "Inner"); roiManager("Select", 0); roiManager("Delete"); roiManager("XOR"); } //************************* indexName ******************** function indexName(name){ path=option[5]; i=1; iName=name; while (File.exists(path+iName+".tif")) { iName=name+"_"+toString(i); i++; } return iName; } //************************clearChannel********************* function clearChannel(){ run("Select All"); run("Clear", "slice"); run("Restore Selection"); }
Akce dokumentů