/* ZFBONE - Version 1.1 DEVELOPERS: Marco Tarasco & Fabrice Cordelières EMAIL: marcotar90@gmail.com & fabrice.cordelieres@u-bordeaux.fr LAST EDITED: September 4th,2020 */ macro "ZFBONE Action Tool - C012D00D01D02D06D08D09D10D13D15D16D20D23D24D25D30D37D40D43D50D55D56D57D60D64D65D67D70D71D72D74D77D79D80D81D82D84D85D86D87D89D90Da0Db0Db3Db6Db7Db8Db9Dc0Dc6Dd0Dd3Dd4Dd5Dd6De0De3Df0Df1Df2Cf00D11D12D17D18D19D21D22D26D27D28D29D31D32D35D36D38D39D41D42D44D45D48D49D51D52D53D54D58D59D61D62D63D68D69D91D92D93D94D95D96D97D98D99Da1Da2Da3Da4Da5Da6Da7Da8Da9Db1Db2Db4Db5Dc1Dc2Dc4Dc5Dd1Dd2De1De2C112D03D07D33D34D46D47D73D78D83D88Dc3Df3CfffD0aD1aD1cD1dD1eD2aD2cD2eD3aD3dD4aD4bD4cD4dD4eD4fD5aD6aD6cD6dD6eD7aD8aD8bD8cD8dD8eD8fD9aDaaDabDadDaeDafDbaDbbDbcDbeDbfDcaDdaDdbDdcDddDdeDdfDeaDfaDfcDfeC000C02fD0bD0cD0dD0eD0fD1bD1fD2bD2dD2fD3bD3cD3eD3fD5bD5cD5dD5eD5fD6bD6fD7bD7cD7dD7eD7fD9bD9cD9dD9eD9fDacDbdDcbDccDcdDceDcfDebDecDedDeeDefDfbDfdDff"{ infoAbout(); } function infoAbout(){ bioskelLink="http://bioskel.ccmar.ualg.pt/"; bioskelIcon="http://bioskel.ccmar.ualg.pt/images/bioskel.png"; bicLink="http://www.bic.u-bordeaux.fr/"; bicIcon="https://upload.wikimedia.org/wikipedia/commons/4/44/Logo_BIC.png"; neubiasLink="http://eubias.org/NEUBIAS/"; neubiasIcon="http://eubias.org/NEUBIAS/wp-content/uploads/2016/07/Logo36-300x159.png"; GitHub="https://github.com/MarcoTarasco/ZFBONE"; html="" +"" +"

ZFBONE

" +"" +"Developed by:" +"
" +"
Marco Tarasco (marcotar90@gmail.com)" +"
Fabrice Cordelières (fabrice.cordelieres@u-bordeaux.fr)" +"
" +"
" +"Version 1.1 " +"LAST EDITED: September 4th, 2020 " +"
" +"Please check our page for updates and video tutorials on " +"GitHub" +"
" +"
" +"We acknowledge NEUBIAS: Network of European BioImage Analysts, COST Action CA15124" +"
" +"
" +"
" +"
" +iconAndLink(bioskelLink, bioskelIcon, 154, 128) +iconAndLink(neubiasLink, neubiasIcon, 150, 80) +iconAndLink(bicLink, bicIcon, 158, 57) +"
" +"" +""; showMessage("About...", html); } //---------------------------------------------------------------------------------- function iconAndLink(urlLink, urlIcon, width, height){ img="\"There"; code=""+img+""; return code; } //------------------------------------------OPERCULUM MACRO--------------------------------------------------// macro "Operculum assay Action Tool - C000D17D26D27D28D29D35D38D39D3aD45D4bD54D5bD63D6cD73D76D77D7cD82D86D87D8dD92D9dDa2DadDb2DbdDc2DcdDd2DddDe2DedDf2DfdCf00Db5DbbDc5Dc6DcbDd6Dd7Dd8Dd9DdaDdbDe7De8De9DeaDf9"{ //Menu options Dialog.create("Operculum assay"); Dialog.addRadioButtonGroup("Mode", newArray("Single","Batch"),1, 2, "Single"); Dialog.addRadioButtonGroup("Adjust contrast", newArray("Yes","No"),1, 2, "Yes"); Dialog.setInsets(5, 0, 0); Dialog.addNumber("Set contrast value (0-10)", 2); Dialog.addRadioButtonGroup("Number of channels (Ch) to analyze", newArray("1","2"),1, 2, "1"); Dialog.addRadioButtonGroup("Apply threshold in Ch1", newArray("Yes","No"),1, 2, "No"); Dialog.addRadioButtonGroup("Apply threshold in Ch2", newArray("Yes","No"),1, 2, "Yes"); Dialog.setInsets(5, 10, 0); Dialog.addRadioButtonGroup("Threshold", newArray("Interactive","Not interactive"),1, 2, "Interactive"); Dialog.setInsets(5, 10, 0); Dialog.addNumber("Set threshold Ch1 (0-255)*", 0); Dialog.setInsets(5, 10, 0); Dialog.addNumber("Set threshold Ch2 (0-255)*", 0); Dialog.setInsets(5, 10, 0); Dialog.addMessage("* Threshold min value depends on \nimage aquisition parameters"); Dialog.addRadioButtonGroup("Measure head area", newArray("Yes","No"),1, 2, "Yes"); // Dialog.addMessage(" "); Dialog.setInsets(5, 10, 0); Dialog.addMessage("Set measurements"); Dialog.setInsets(5, 20, 0); Dialog.addCheckboxGroup(1, 2, newArray("Area","Intensity"), newArray(true,false)); //Help message //------ UserManualOperculum="https://github.com/MarcoTarasco/ZFBONE#operculum-assay-"; html = "" +"

Operculum assay

" +"Please check the online manual and video tutorial available on " +"GitHub" //Get user choices from menu Dialog.addHelp(html); Dialog.show(); mode=Dialog.getRadioButton(); Applycontrast=Dialog.getRadioButton(); contrastValue=Dialog.getNumber(); channel=Dialog.getRadioButton(); applyThreshold1=Dialog.getRadioButton(); applyThreshold2=Dialog.getRadioButton(); ThresholdMode=Dialog.getRadioButton(); nCh1=Dialog.getNumber();//threshold min value channel 1 nCh2=Dialog.getNumber();//threshold min value channel 2 UseHead=Dialog.getRadioButton(); ShowOpArea=Dialog.getCheckbox(); ShowInt=Dialog.getCheckbox(); // analyse single image or batch? if (mode=="Single") { doAnalysis(); } else { dir=getDirectory("Choose a Directory"); list=getFileList(dir); for (i = 0; i < list.length; i++) { if (endsWith(toLowerCase(list[i]), ".bmp")||endsWith(toLowerCase(list[i]), ".tif")||endsWith(toLowerCase(list[i]), ".jpg")){ if(!File.exists(dir+"analyzed/"+list[i]+"_analyzed.jpg")){ open(dir+list[i]); doAnalysis(); run("Close All"); } } } } function doAnalysis(){ if (channel=="1") { if (nImages==0) waitForUser("Please open an image (1 channel)"); if (nImages==0) exit("No image was opened!!"); } else { if (nImages==0) waitForUser("Please open an image (2 channel)"); if (nImages==0) exit("No image was opened!!"); } run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); roiManager("reset"); roiManager("Show None"); dir=getDirectory("image"); img=getTitle(); // adjust contrast? autoContrast(); // Are you measuring the head area? if (UseHead=="Yes") { areaHead=getRoiMeasure("polygon", "Head"); } // Decide if you work with 1 channel or 2 if (channel=="1") { setTool("freehand"); while(selectionType==-1){ waitForUser("Select "+"Operculum area Ch1"); } roiManager("Add"); List.setMeasurements; areaOperculum=List.getValue("Area"); getRawStatistics(nPixels, mean, min, max, std, histogram); TOtIntensity=nPixels*mean; if (applyThreshold1=="Yes") { thr1Ch=colorThresholding1Ch(); run("Restore Selection"); List.setMeasurements; OpChOneFluoArea=List.getValue("RawIntDen")/255; run("Create Selection"); roiManager("add"); } setResult("Label", nResults, img); // if the head was measured show ratio if (UseHead=="Yes") { Ratio=areaOperculum/areaHead; setResult("Hd area", nResults-1, areaHead); } if (ShowOpArea==true) setResult("Op area Ch1", nResults-1, areaOperculum); if (UseHead=="Yes") { setResult("Op/Hd Ch1", nResults-1, Ratio); } if (ShowInt==true)setResult("Signal intensity Ch1", nResults-1, TOtIntensity); if (applyThreshold1=="Yes") { setResult("Signal area Ch1", nResults-1, OpChOneFluoArea); if (ShowInt==true)setResult("Signal intensity Ch1", nResults-1, TOtIntensity); setResult("MIN Thr Ch1", nResults-1, thr1Ch[0]); setResult("MAX Thr Ch1", nResults-1, thr1Ch[1]); } //Rename and color ROIs if (UseHead=="Yes") { roiManager("Select", 0); roiManager("Set Color", "magenta"); roiManager("Rename", "Head area"); roiManager("Select", 1); roiManager("Set Color", "blue"); roiManager("Rename", "Operculum area"); if (applyThreshold1=="Yes") { roiManager("select", newArray(1,2)); roiManager("AND"); roiManager("add"); roiManager("Select", 3); roiManager("Set Color", "red"); roiManager("Rename", "Op signal Ch1"); roiManager("deselect"); roiManager("select", 2); roiManager("delete"); } } else { roiManager("Select", 0); roiManager("Set Color", "red"); roiManager("Rename", "Operculum area"); roiManager("Show All without labels"); if (applyThreshold1=="Yes") { roiManager("select", newArray(0,1)); roiManager("AND"); roiManager("add"); roiManager("Select", 2); roiManager("Set Color", "red"); roiManager("Rename", "Op signal Ch1"); roiManager("select", 1); roiManager("delete"); } } } // the user choose to work with 2 channels else { if (nImages==0) waitForUser("Please open an image (2 channel)"); if (nImages==0) exit("No image was opened!!"); run("Labels...", "color=white font=12 show use"); selectWindow(img); run("8-bit"); run("Split Channels"); selectWindow("C1-"+img); setTool("freehand"); while(selectionType==-1){ waitForUser("Select Operculum area Ch1"); } List.setMeasurements; OpChOneArea=List.getValue("Area"); getRawStatistics(nPixels, mean, min, max, std, histogram); OpChOneMeanIntensity=nPixels*mean; if (UseHead=="Yes") { Ratio=OpChOneArea/areaHead; } roiManager("add"); if (UseHead=="Yes") { roiManager("Select", 0); roiManager("Set Color", "magenta"); roiManager("Rename", "Head area"); roiManager("Select", 1); roiManager("Set Color", "blue"); roiManager("Rename", "Op area Ch1"); } else { roiManager("Select", 0); roiManager("Set Color", "blue"); roiManager("Rename", "Op area Ch1"); } getRawStatistics(nPixels, mean, min, max, std, histogram); OpChOneMeanIntensity=nPixels*mean; //run("Select None"); if (applyThreshold1=="Yes") { thr1Ch=colorThresholding1Ch(); run("Restore Selection"); List.setMeasurements; OpChOneFluoArea=List.getValue("RawIntDen")/255; run("Create Selection"); roiManager("add"); if (UseHead=="Yes") { roiManager("Select", 2); roiManager("Set Color", "blue"); roiManager("Rename", "Op signal Ch1"); } else { roiManager("Select", 1); roiManager("Set Color", "blue"); roiManager("Rename", "Op signal Ch1"); } } // work on the second channel selectWindow("C2-"+img); if (UseHead=="Yes") { roiManager("Select", 1); } else { roiManager("Select", 0); } getRawStatistics(nPixels, mean, min, max, std, histogram); OpChTwoMeanIntensity=nPixels*mean; selectWindow("C2-"+img); if (applyThreshold2=="Yes") { thr2Ch=colorThresholding2Ch(); run("Restore Selection"); List.setMeasurements; OpChTwoFluoArea=List.getValue("RawIntDen")/255; run("Create Selection"); roiManager("add"); if (UseHead=="Yes") { roiManager("Select", 2); roiManager("Set Color", "yellow"); roiManager("Rename", "Op signal Ch2"); } else { roiManager("Select", 1); roiManager("Set Color", "yellow"); roiManager("Rename", "Op signal Ch2"); } } //Organize ROIs if (applyThreshold1=="Yes" && applyThreshold2=="Yes") { if (UseHead=="Yes") { roiManager("select", newArray(1,2)); roiManager("AND"); roiManager("add"); roiManager("Select", 4); roiManager("Set Color", "red"); roiManager("Rename", "Op signal Ch1"); roiManager("select", newArray(1,3)); roiManager("AND"); roiManager("add"); roiManager("Select", 5); roiManager("Set Color", "green"); roiManager("Rename", "Op signal Ch2"); roiManager("Select", newArray(2,3)); roiManager("delete"); } else { roiManager("select", newArray(0,1)); roiManager("AND"); roiManager("add"); roiManager("Select", 2); roiManager("Set Color", "red"); roiManager("Rename", "Op signal Ch1"); roiManager("select", newArray(0,2)); roiManager("AND"); roiManager("add"); roiManager("Select", 3); roiManager("Set Color", "green"); roiManager("Rename", "Op signal Ch2"); roiManager("Select", newArray(1,2)); roiManager("delete"); roiManager("Select", 1); roiManager("Set Color", "red"); roiManager("Rename", "Op signal Ch1"); roiManager("Select", 2); roiManager("Set Color", "green"); roiManager("Rename", "Op signal Ch2"); } } if (applyThreshold1=="No" && applyThreshold2=="Yes") { if (UseHead=="Yes") { roiManager("select", newArray(1,2)); roiManager("AND"); roiManager("add"); roiManager("Select", 3); roiManager("Set Color", "green"); roiManager("Rename", "Op signal Ch2"); roiManager("select", 2); roiManager("delete"); } else { roiManager("select", newArray(0,1)); roiManager("AND"); roiManager("add"); roiManager("Select", 2); roiManager("Set Color", "green"); roiManager("Rename", "Op signal Ch2"); roiManager("select", 1); roiManager("delete"); } } if (applyThreshold1=="Yes" && applyThreshold2=="No") { if (UseHead=="Yes") { roiManager("select", newArray(1,2)); roiManager("AND"); roiManager("add"); roiManager("Select", 3); roiManager("Set Color", "red"); roiManager("Rename", "Op signal Ch1"); roiManager("select", 2); roiManager("delete"); } else { roiManager("select", newArray(0,1)); roiManager("AND"); roiManager("add"); roiManager("Select", 2); roiManager("Set Color", "red"); roiManager("Rename", "Op signal Ch1"); roiManager("select", 1); roiManager("delete"); } } //Set result table setResult("Label", nResults, img); if (UseHead=="Yes") { setResult("Head area", nResults-1, areaHead); } setResult("Op area 1Ch", nResults-1, OpChOneArea); if (applyThreshold1=="Yes") { setResult("Signal area Ch1", nResults-1, OpChOneFluoArea); if (UseHead=="Yes") { setResult("Op/Hd Ch1", nResults-1, Ratio); } if (ShowInt==true){ setResult("Signal intensity Ch1", nResults-1, OpChOneMeanIntensity); } setResult("MIN Thr Ch1", nResults-1, thr1Ch[0]); setResult("MAX Thr Ch1", nResults-1, thr1Ch[1]); } if (applyThreshold2=="Yes") { if (UseHead=="Yes") { setResult("Op/Hd Ch1", nResults-1, Ratio); } setResult("Signal area Ch2", nResults-1, OpChTwoFluoArea); if (ShowInt==true){ setResult("Signal intensity Ch2", nResults-1, OpChTwoMeanIntensity); } setResult("MIN Thr Ch2", nResults-1, thr2Ch[0]); setResult("MAX Thr Ch2", nResults-1, thr2Ch[1]); } } if (channel=="2") { open(dir+img); run("Make Composite"); run("Stack to RGB"); selectWindow(img+" (RGB)"); } if (channel=="1" && applyThreshold1=="Yes"){ open(dir+img); } roiManager("Deselect"); roiManager("Show All"); run("Flatten"); getDateAndTime(year, month, dayOfWeek, dayOfMonth, hour, minute, second, msec); dateTag=""+year+"-"+IJ.pad((month+1), 2)+"-"+IJ.pad((dayOfMonth), 2)+"_"; // now it is saving with the day fo the month wrong.. should i remove +1? direct=dir+"analyzed/"; File.makeDirectory(direct); roiManager("Save",direct+img+"_RoiSet.zip"); saveAs("jpeg",direct+img+"_analyzed"); Table.save(direct+dateTag+"_Operculum_Results.xls"); run("Close All"); } //------------------------------------ function getRoiMeasure(tool, name){ setTool(tool); while(selectionType==-1){ waitForUser("Select "+name+" area"); } roiManager("Add"); getStatistics(area, mean, min, max, std, histogram); run("Select None"); return area; } //------------------auto contrast---------------------------// function autoContrast(){ run("8-bit"); if(Applycontrast=="Yes"){ getStatistics(area, mean, min, max, std, histogram); setMinAndMax(maxOf(mean-contrastValue*std, min), minOf(mean+contrastValue*std, max)); run("Apply LUT"); } } //------------------Threshold functions---------------------------// function colorThresholding1Ch(){ run("Enhance Contrast", "saturated=0.35"); if (ThresholdMode=="Not interactive"){ setThreshold(nCh1, 255); } else { setAutoThreshold("IJ_IsoData dark"); } run("Threshold..."); setOption("BlackBackground", false); if (ThresholdMode=="Interactive"){ waitForUser("Adjust threshold Ch1, then press Ok"); } getThreshold(lower, upper); run("Convert to Mask"); return newArray(lower,upper); } function colorThresholding2Ch(){ run("Enhance Contrast", "saturated=0.35"); if (ThresholdMode=="Not interactive"){ setThreshold(nCh2, 255); } else { setAutoThreshold("Triangle dark"); } setOption("BlackBackground", false); run("Threshold..."); if (ThresholdMode=="Interactive") waitForUser("Adjust threshold Ch2, then press Ok"); getThreshold(lower, upper); run("Convert to Mask"); return newArray(lower,upper); } } } } //------------------------------------------SCALES ASSAY--------------------------------------------------// macro "Scale assay Action Tool - C000D02D0dD12D1dD22D2dD31D32D3dD3eD40D42D4dD4fD50D52D5dD5fD60D61D62D6dD6fD70D72D7dD7fD82D8dD8eD92D9dDa2DadDb2DbdDc2DcdDd2DddDe3De4DebDecDf3Df4DfbDfcCf00D03D05D07D09D0bD13D15D16D17D19D1aD1bD34D36D38D3aD3cD44D45D46D48D49D4aD4cD64D66D68D6aD6cD73D74D76D77D78D7aD7bD7cD93D95D97D99D9bDa3Da4Da5Da7Da8Da9DabDacDc4Dc6Dc8DcaDccDd4Dd5Dd6Dd8Dd9DdaDdcDf6Df8Dfa"{ //-------------------------------user menu setup------------------------- Dialog.create("Scale assay"); Dialog.setInsets(0, 1, 0); Dialog.addRadioButtonGroup("Staining", newArray("TRAP","von Kossa"),1, 2, "TRAP"); Dialog.setInsets(0, 1, 0); Dialog.addRadioButtonGroup("Mode", newArray("Single","Batch"),1, 2, "Single"); Dialog.setInsets(0, 1, 0); Dialog.addRadioButtonGroup("Threshold", newArray("Interactive","Not interactive"),1, 2, "Interactive"); Dialog.setInsets(0, 1, 0); Dialog.addMessage(" "); Dialog.setInsets(0, 1, 0); Dialog.addNumber("Set threshold (0-255)*", 165); Dialog.setInsets(0, 1, 0); Dialog.addMessage("* Threshold min value depends on \nimage aquisition parameters"); //------ UserManualScales="https://github.com/MarcoTarasco/ZFBONE#scales-assay-"; html = "" +"

Scale assay

" +"Please check the online manual and video tutorial available on " +"GitHub" //------ Dialog.addHelp(html); Dialog.show(); assay=Dialog.getRadioButton(); mode=Dialog.getRadioButton(); analysis=Dialog.getRadioButton(); numbtr=Dialog.getNumber(); if (mode=="Single") { if (nImages==0) waitForUser("Open an image!!"); if (nImages==0) exit("No image was opened..."); if (bitDepth()!=24) exit("Open an RGB image!!"); img=getTitle(); run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); dir=getDirectory("image"); dark=(assay=="TRAP"); getROI(); thr=process(dark); table(); measureAndTable(dark, thr); SaveOutput(dark, dir, img); } else { dir=getDirectory("Choose a Directory"); list=getFileList(dir); if(!File.exists(dir+"analyzed/")){ for (i = 0; i < list.length; i++) { if (endsWith(toLowerCase(list[i]), ".bmp")||endsWith(toLowerCase(list[i]), ".tif")){ open(dir+list[i]); run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); img=getTitle(); dir=getDirectory("image"); dark=(assay=="TRAP"); getROI(); thr=process(dark);//will give true or false table(); measureAndTable(dark, thr);//will give true or false SaveOutput(dark, dir, img); } } } else { exit("Analyses already done!!"); } } } //------------------------------------------------------------------------------------------ function getROI(){ roiManager("reset"); run("Select None"); while(roiManager("count")==0){ setTool("polygon"); waitForUser("Select scale area, then type (T) \nto add it in the ROI manager"); } for (i=0;i=2){ roiManager("Combine"); } else { roiManager("select", 0); } arg=" exclude"; if(isTrap) arg=""; run("Analyze Particles...", arg+" show=Masks"); if(!isTrap){ return THRVKossa; } else { return THRTraP; } } //---------------------------------------- function VonKossaThreshold() { run("8-bit"); run("Enhance Contrast", "saturated=0.35"); setThreshold(numbtr, 255); run("Threshold..."); //setAutoThreshold("MaxEntropy dark"); if (analysis=="Interactive"){ setAutoThreshold("MaxEntropy dark"); waitForUser("Adjust threshold, then press Ok"); } getThreshold(lower, upper); run("Convert to Mask"); return newArray(lower,upper); } function TrapThreshold(){ min=newArray(3); max=newArray(3); filter=newArray(3); img=getTitle(); call("ij.plugin.frame.ColorThresholder.RGBtoYUV"); run("RGB Stack"); run("Convert Stack to Images"); selectWindow("Red"); rename("0"); selectWindow("Green"); rename("1"); selectWindow("Blue"); rename("2"); min[0]=0; max[0]=255; filter[0]="pass"; min[1]=0; max[1]=255; filter[1]="pass"; min[2]=numbtr; max[2]=255; filter[2]="pass"; selectWindow("2"); run("Threshold..."); setThreshold(min[2], max[2]); if (analysis=="Interactive"){ setAutoThreshold("MaxEntropy dark"); waitForUser("Adjust threshold, then press Ok"); } getThreshold(lower, upper); for (i=0;i<3;i++){ selectWindow(""+i); setThreshold(min[i], max[i]); run("Convert to Mask"); if (filter[i]=="stop") run("Invert"); } imageCalculator("AND create", "0","1"); imageCalculator("AND create", "Result of 0","2"); for (i=0;i<3;i++){ selectWindow(""+i); close(); } selectWindow("Result of 0"); close(); selectWindow("Result of Result of 0"); rename(img); return newArray(lower,upper); } //------------------------------------------------------------------------------------------ function measureAndTable(isTRAP, thr){ img=replace(getTitle(), "Mask of ", ""); roiManager("Show All with labels"); roiManager("UseNames", "true"); for (i=0;iCaudal fin assay" +"Please check the online manual and video tutorial available on " +"GitHub" //------ Dialog.addHelp(html); Dialog.show(); assay= Dialog.getRadioButton(); ThresholdMode=Dialog.getRadioButton(); FinThr=Dialog.getNumber(); if (assay=="Bone mineralization (MIN)") Caudalfin(); if (assay=="Ray morphometrics (MORP)") Raymorphometrics(); if (assay=="MIN & MORP") Both(); if (assay=="TRAP signal") TRAPassay(); } //------------------------------------------------------ function Caudalfin() { roiManager("reset"); waitForUser("Open Brightfield image"); if (nImages==0) exit("Open an image!!"); brightfield=getTitle(); run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); waitForUser("Open fluorescence image"); if (nImages==0) exit("Open an image!!"); fluorescence=getTitle(); run("Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); path=getDirectory("image")+fluorescence; run("Labels...", "color=white font=12 show use"); run("Line Width...", "line=1"); setTool("line"); selectWindow(brightfield); if(bitDepth()==24) run("16-bit"); while(selectionType==-1){ waitForUser("Select STU"); } List.setMeasurements; Stu=List.getValue("Length"); roiManager("Add"); roiManager("Select", 0); roiManager("Set Color", "yellow"); roiManager("Set Line Width", 3); roiManager("Rename", "STU"); roiManager("Show All without labels"); roiManager("UseNames", "true"); setTool("polygon"); selectWindow(brightfield); while(selectionType==-1){ waitForUser("Select REG"); } List.setMeasurements; Reg=List.getValue("Area"); roiManager("Add"); roiManager("Select", 1); roiManager("Set Color", "blue"); roiManager("Rename", "REG"); //Pass to rays measuraments setTool("line"); run("Select None"); while(selectionType==-1){ waitForUser("Select RAY, then type (T) to add it to the ROI manager"); } //i starts at 2 to avoid measuring the first ROIs which are the STU, REG ROI Ray=0; for (i=2;iRay bone intensity assay" +"Please check the online manual and video tutorial available on " +"GitHub" //------ Dialog.addHelp(html); Dialog.show(); assay=Dialog.getRadioButton(); if (assay=="Ray analysis") { run ("RayAnalysis"); } else { run ("Data pooling"); } } macro "RayAnalysis" { cleanUp(); if (nImages==0) waitForUser("Open an image!!"); if (nImages==0) exit("No image was opened..."); img=getTitle(); askForROIs(); maxArray=getData(); maxPosition=shiftColumns(maxArray); normalize(maxPosition); generateXValues(); fillEmptyCells(); plotShiftedNormalized(true); generateOutput(img); saveEverything(img); run ("Close All"); //--------------------------------------------- function cleanUp(){ run("Clear Results"); roiManager("Reset"); roiManager("UseNames", "true"); close("All your data*");//close any window that has this name } //--------------------------------------------- function askForROIs(){ roiManager("Show All"); run("Line Width...", "line=30"); setTool("polyline"); waitForUser("Select each ray,then type (T) to add it to the ROI manager"); for(i=0; imax){ position=i; max=inputArray[i]; } } return newArray(position, max); } //Then we shift all the data of each ray to start at the same point (max intensity) function shiftColumns(maxArray){ Array.getStatistics(maxArray, min, maxOfMax, mean, stdDev); for(i=0; imax){ position=i; max=inputArray[i]; } } return newArray(position, max); } //Then we shift all the data of each ray to start at the same point (max intensity) function shiftColumns(maxArray){ Array.getStatistics(maxArray, min, maxOfMax, mean, stdDev); headers=split(Table.headings, "\t"); index=0; for(i=0; i