/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // ConfocalCheck1 - An ImageJ macro for the automated monitoring of confocal microscope performance // // Copyright 2009-2013 Medical Research Council // Dirk Dormann - dirk.dormann@csc.mrc.ac.uk // Medical Research Council // MRC Clinical Sciences Centre // Hammersmith Hospital Campus // Du Cane Road // London W12 0NN // UK // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // For a copy of the GNU General Public License see . // // // Tested successfully with FIJI version 1.47h and ImageJ version 1.46r and the bioformats LOCI plugin for ImageJ, release version 4.4.8, built 1.May.2013 // As we have had problems in the past with the bioformats plugins with the macro not being able to retrieve metadata due to // numerous plugin changes we recommend not to update to later versions if your current version is working fine ! // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// macro "Confocal Performance Analysis Tool Action Tool - -C000-O4499-O11ff-o8822-Cb00-L808f-L08f8" { run("Automated confocal performance analysis"); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Global variables //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// var ReadName,ReadNameNoExt, ReadFileName, ReadChannel, ReadDir, ReadFormat, WWWDir,WWWAddString; var Centroid = newArray(3), Centroid2D = newArray(2); var ImageStats = newArray(3); var TextColour = newArray("blue","green","red","black"); var MagText, NAText, SystemName; var laserlines,lasercolour,objectives,BeadLaser,Axial405Laser,Axial488Laser,PsfLaser,LambdaScanLaser; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // MAIN MACRO //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// macro "Automated confocal performance analysis" { //Check no image windows are open for analysis otherwise message to close all windows appears if (nImages() > 0) exit("ERROR ! Too many image windows open ! Close all image windows !"); //Selecting the confocal system for the subsequent analysis SelectSystem(); //Settings for compression of JPEG images: run("Input/Output...", "jpeg=90 gif=-1 file=.xls copy"); //Select confocal data file (LIF for Leica SP5, LEI for Leica SP1/SP2 or others) path = File.openDialog("Select the confocal data file (CZI,LIF,LEI,LSM,ND2,TIF...)"); ReadName = File.getName(path); ReadNameNoExt = substring(ReadName, 0,lastIndexOf(ReadName, ".")); ReadDir = File.getParent(path); ReadFormat = substring(ReadName, lastIndexOf(ReadName, ".")+1, lengthOf(ReadName)); // Clear log window print("\\Clear"); selectWindow("Log"); setLocation(0,0); print(SystemName + " performance analysis \n"); print("------------------------------------------------------ \n"); // Obtain data acquisition date from metadata, otherwise enter manually if (ReadFormat != "tif") { run("Bio-Formats Macro Extensions"); Ext.setId(path); Ext.getSeriesCount(seriesCount); Ext.setSeries(0); Ext.getImageCreationDate(DateText); if (lengthOf(DateText) == 19){ year = substring (DateText, 0, indexOf(DateText,"-")); month = substring (DateText, indexOf(DateText,"-")+1,lastIndexOf(DateText,"-")); day = substring (DateText, lastIndexOf(DateText,"-")+1,indexOf(DateText,"T")); DateText = day + "-" + month + "-" + year; } else DateText = getString("Enter date of image acquisition:", "01.01.2011"); } else DateText = getString("Enter date of image acquisition:", "01.01.2011"); print("Date:","\t",DateText); // Obtain microscope objective information from metadata, otherwise select from objectives list specified in system configuration file // For Leica SP1/SP2 systems metadata are retrieved from experiment txt file if (ReadFormat == "lei") { LeicaTextFilename = File.nameWithoutExtension + ".txt"; LeicaText = File.openAsRawString(ReadDir+"\\"+LeicaTextFilename); LensText = substring (LeicaText, indexOf(LeicaText, "Objective")+9, indexOf(LeicaText,"Order")); LensText = substring (LensText, lengthOf(LensText)/2); NAText = substring (LensText, indexOf(LensText, "x")+1, indexOf(LensText,"x")+5); MagText = substring (LensText, lastIndexOf(LensText,"x")-6, lastIndexOf(LensText,"x")); MagText = substring (MagText, lastIndexOf(MagText," ")+1, lastIndexOf(MagText,".")); if (lengthOf(LensText) > 6 ) { tmpindex = indexOf(LensText,"x"); MagText = substring(LensText, tmpindex-5, tmpindex); NAText = substring(LensText, tmpindex+1, tmpindex+5); } else LensText = GetObjective(); } // Obtain microscope objective information from Leica LIF metadata else if (ReadFormat == "lif"){ Ext.getSeriesMetadataValue("HardwareSetting|FilterSettingRecord|Objective 0",LensText); if (lengthOf(LensText) > 6 ) { tmpindex = indexOf(LensText,"x"); MagText = substring(LensText, tmpindex-5, tmpindex); NAText = substring(LensText, tmpindex+1, tmpindex+5); } else LensText = GetObjective(); } // Obtain microscope objective information from Zeiss LSM 510 metadata else if (ReadFormat == "lsm"){ Ext.getSeriesMetadataValue("Recording #1 Objective",LensText); if (lengthOf(LensText) > 6 ) { tmpindex = indexOf(LensText,"x"); MagText = substring(LensText, tmpindex-3, tmpindex); NAText = substring(LensText, tmpindex+2, tmpindex+5); if (lengthOf(NAText) == 3) NAText = NAText +"0"; } else LensText = GetObjective(); } // Obtain microscope objective information from Zeiss LSM 780 metadata else if (ReadFormat == "czi"){ Ext.getMetadataValue("Information|Instrument|Objective|Manufacturer|Model|0",LensText); if (lengthOf(LensText) > 6 ) { tmpindex = indexOf(LensText,"x"); MagText = substring(LensText, tmpindex-3, tmpindex); NAText = substring(LensText, tmpindex+2, tmpindex+5); if (lengthOf(NAText) == 3) NAText = NAText +"0"; } else LensText = GetObjective(); } // Obtain microscope objective information from Nikon A1 metadata else if (ReadFormat == "nd2"){ Ext.getMetadataValue("TextInfoItem_1",LensText); alternativeNA = 0; if (LensText == 0){ Ext.getMetadataValue("TextInfoItem_1 #2",LensText); alternativeNA = 1; } LensText = substring(LensText,indexOf(LensText,"TextInfoItem_13")+15); if (lengthOf(LensText) > 6 ) { tmpindex = indexOf(LensText,"x"); MagText = substring(LensText, tmpindex-3, tmpindex); if (alternativeNA == 0){ Ext.getMetadataValue("TextInfoItem_ #2",NAText); NAText = substring(NAText,indexOf(NAText,":")+2); } else if (alternativeNA == 1) Ext.getMetadataValue("Numerical Aperture",NAText); if (lengthOf(NAText) == 3) NAText = NAText +"0"; } else LensText = GetObjective(); } // Obtain microscope objective information from AppliedPrecision DV metadata else if (ReadFormat == "dv"){ Ext.getMetadataValue("Optics Objective",LensText); if (lengthOf(LensText) > 6 ) { tmpindex = indexOf(LensText,"X"); MagText = substring(LensText, indexOf(LensText," "), tmpindex); NAText = substring(LensText, tmpindex+2, tmpindex+6); } else LensText = GetObjective(); } // Obtain microscope objective information directly from the objective list else LensText = GetObjective(); MagText = parseFloat(MagText); print("Objective:","\t",LensText); print("Magnification:","\t",MagText); print("Numerical aperture:","\t",NAText); // Create Analysis Summary website if required and choose whether to update existing website Dialog.create("Options"); Dialog.addCheckbox("Create new summary website.", false); Dialog.addCheckbox("Update existing summary website", true); Dialog.addCheckbox("Axial resolution: Draw lines automatically", true); Dialog.show(); NewWWWSite = Dialog.getCheckbox(); UpdateWWWSite = Dialog.getCheckbox(); AxialAutomatic = Dialog.getCheckbox(); if (NewWWWSite == true) { WWWDir=getDirectory("Select directory for Website Summary files !"); CreateWWWSite(SystemName, objectives); } if (UpdateWWWSite == true && NewWWWSite == false) WWWDir=getDirectory("Select directory for Website Summary files !"); if (UpdateWWWSite == true) WWWAddString = "\n"+DateText+"\n"; axial_analysis = 0; bead_analysis = 0; field_analysis = 0; psf_analysis = 0; grid_analysis = 0; zgalvo_analysis = 0; lambda_analysis = 0; laser_analysis = 0; stage_analysis = 0; stageacc_analysis = 0; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Start Axial resolution measurement ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // First checking that 'axial' image series (405 or 488) is present: wtmp > 0 tempAxial = newArray("405","488"); axial405passed = false; axial488passed = false; WWWAxialString = ""; for (ax=0; ax -1) { // Obtain recording parameters Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblVoxelY 0",wtmp); AxialVoxelXY = parseFloat(wtmp)*1000000; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblZoom 0",wtmp); AxialZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblPinholeAiry 0",wtmp); AxialPinhole = parseFloat(wtmp); run("Bio-Formats Importer", "open=" + path +" view=[Standard ImageJ] stack_order=Default split_channels series_"+toString(seriesFound)); AxialChannelNo = nImages; for (i=0; i<=(AxialChannelNo-1); i++) { if (seriesCount == 1) { selectWindow(ReadName + " - C=" + toString(i)); rename("Channel"+toString(i)); } else { selectWindow(ReadName + " - axial"+tempAxial[ax]+" - C=" + toString(i)); rename("Channel"+toString(i)); } } } } // Checking in Leica SP1/SP2 LEI file format else if (ReadFormat == "lei") { if (indexOf(LeicaText, "Series Name:\taxial" + tempAxial[ax]) != -1) { AxialText = substring (LeicaText, indexOf(LeicaText, "Series Name:\taxial"+ tempAxial[ax]),indexOf(LeicaText, "Series Name:\taxial"+ tempAxial[ax])+2100); AxialVoxelWidth = substring (AxialText, indexOf(AxialText, "Voxel-Height")+19, indexOf(AxialText,"Voxel-Height")+26); AxialVoxelXY = parseFloat(AxialVoxelWidth); AxialZoom = substring (AxialText, indexOf(AxialText, "Zoom"), indexOf(AxialText,"Scan-Direction")); AxialZoom = substring (AxialZoom, indexOf(AxialZoom, "Zoom")+4); AxialZoom = parseFloat(AxialZoom); AxialPinhole = substring (AxialText, indexOf(AxialText, "Pinhole [airy]"), indexOf(AxialText,"Size-Width")); AxialPinhole = substring (AxialPinhole, indexOf(AxialPinhole, "]")+2); AxialPinhole = parseFloat(AxialPinhole); AxialChannels = substring (LeicaText, indexOf(LeicaText, "Series Name:\taxial"+tempAxial[ax])-150, indexOf(LeicaText,"Series Name:\taxial"+tempAxial[ax])); AxialChannels = substring (AxialChannels, indexOf(AxialChannels, "Dimension_2"), indexOf(AxialChannels,"Physical Length")); AxialChannels = substring (AxialChannels, indexOf(AxialChannels, "Logical Size:")+13, lengthOf(AxialChannels)-1); AxialChannelNo = parseInt(AxialChannels); for (i=0; i<=(AxialChannelNo-1); i++) { ReadFileName=substring(ReadName, 0,lastIndexOf(ReadName, "."))+"_axial"+tempAxial[ax]; ReadChannel = "ch0" + toString(i); OpenSeries(); rename("Channel"+toString(i)); } } } // Checking in Zeiss LSM file format, CZI format doesn't work for XZ scans use, LSM format instead for Zeiss XZ scans else if (ReadFormat == "lsm" || ReadFormat == "czi") { if (File.exists(ReadDir + "\\"+"axial"+tempAxial[ax]+".lsm") == 1) { Ext.setId(ReadDir + "\\"+"axial"+tempAxial[ax]+".lsm"); Ext.setSeries(0); Ext.getSeriesMetadataValue("Recording #1 Zoom X",wtmp); AxialZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("DetectionChannel #1 Pinhole Diameter",wtmp); AxialPinhole = parseFloat(wtmp); Ext.getSeriesMetadataValue("VoxelSizeZ",wtmp); AxialVoxelXY = parseFloat(wtmp); run("Bio-Formats Importer", "open="+ReadDir + "\\"+"axial"+tempAxial[ax]+".lsm" + " color_mode=Default split_channels view=[Standard ImageJ] stack_order=Default"); AxialChannelNo = nImages; for (i=0; i<=(AxialChannelNo-1); i++) { selectWindow("axial"+tempAxial[ax]+".lsm"+ " - C="+toString(i)); rename("Channel"+toString(i)); } } } // Checking Nikon ND2 file format else if (ReadFormat == "nd2"){ if (File.exists(ReadDir + "\\"+"axial"+tempAxial[ax]+".nd2") == 1) { Ext.setId(ReadDir + "\\"+"axial"+tempAxial[ax]+".nd2"); Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"axial"+tempAxial[ax]+".nd2"); rename("Channel"); makeRectangle(0, 0, 512, 512); run("Crop"); AxialVoxelXY = getNumber("Axial Resolution: Enter Z step size [um]", 0.2); Ext.getMetadataValue("ImagingZoom",wtmp); AxialZoom = parseFloat(wtmp); Ext.getMetadataValue("PinholeSize",wtmp); AxialPinhole = parseFloat(wtmp); run("Split Channels"); AxialChannelNo = nImages; for (i=0; i<=(AxialChannelNo-1); i++) { selectWindow("C"+toString(i+1)+"-Channel"); rename("Channel"+toString(i)); run("8-bit"); } } } // not applicable for Deltavision system else if (ReadFormat == "dv") { } // open axial images as composite TIFF image and manually enter the required parameters else if (ReadFormat == "tif"){ if (File.exists(ReadDir + "\\"+"axial"+tempAxial[ax]+".tif") == 1) { AxialVoxelXY = getNumber("Axial Resolution: Enter Z step size [um]", 0.2); AxialZoom = getNumber("Axial Resolution: Enter Zoom factor.", 1); AxialPinhole = getNumber("Axial Resolution: Enter pinhole diameter [airy units]", 0.5); open(ReadDir + "\\"+"axial"+tempAxial[ax]+".tif"); rename("Channel"); run("Split Channels"); AxialChannelNo = nImages; for (i=0; i<=(AxialChannelNo-1); i++) { selectWindow("C"+toString(i+1)+"-Channel"); rename("Channel"+toString(i)); } } } // if axial images present continue with processing if (nImages > 0) { // Print to Log Window print("\nAxial resolution measurements "+tempAxial[ax]+"nm"); print("------------------------------------------------------ \n"); print("Z dimension [um]:" ,"\t" ,d2s(AxialVoxelXY,3)); print("Zoom Factor :" , "\t" , d2s(AxialZoom,3)); if (ReadFormat == "czi" || ReadFormat == "lsm" || ReadFormat == "nd2") print("Pinhole diameter [um]:", "\t", d2s(AxialPinhole,3)); else print("Pinhole diameter [airy]:", "\t", d2s(AxialPinhole,3)); print("\n"); XWidth = getWidth(); YHeight = getHeight(); //Array with 2 channels: z resolution + laser AxialArray = newArray(AxialChannelNo * 2); //loop by number of channels for (i=0; i<=(AxialChannelNo-1); i++) { selectWindow("Channel" + toString(i)); if (tempAxial[ax] == "405") AxialArray[1+i*2] = Axial405Laser[i]; else if (tempAxial[ax] == "488") AxialArray[1+i*2] = Axial488Laser[i]; // draw vertical line only once to obtain position for intensity profile if (i == 0) { if (AxialAutomatic == false) { setTool(4); showMessage("Draw vertical line. Then press SPACE !"); run("Line Width...", "line=10"); while (isKeyDown("space")==false) getLine(x1,y1,x2,y2,linewidth); ZLength = abs(y2-y1); // Length of vertical line ZProfile = newArray(ZLength*AxialChannelNo); if (y1 < y2) yStart = y1; else yStart = y2; } else { x1 = XWidth/2; yStart = 0; y1 = 0; y2 = YHeight; ZLength = YHeight; ZProfile = newArray(ZLength*AxialChannelNo); } } //read out line profile and average over 10 lines in x direction to reduce noise and mirror scratches for (y = yStart; y < (yStart + ZLength); y++) { tempXY = 0; for (x = x1-5; x < (x1+5); x++) tempXY = tempXY + getPixel(x, y); tempXY = tempXY / 10; ZProfile[i*ZLength+y-yStart] = tempXY; } } // Calculate Minimum and Maximum intensity of line profiles tempLineStats = newArray(3); tempLineStats = GetLineStats(ZProfile); // Create intensity plots with circles on graphs marking the positions used for the calculation of the axial resolution/FWHM run("Profile Plot Options...", "width=" + XWidth-78 +" height=201 minimum=0 maximum=0 interpolate draw"); Plot.create("Profiles", "Distance[um]", "Intensity"); tempCalibPos = newArray(1); tempCalibPos[0] = ZLength * AxialVoxelXY; Plot.setLimits(0, tempCalibPos[0] , 0, tempLineStats[1]); ZPositionArray = newArray(ZLength); for (z=0; z TempZMax){ TempZMax = TempZProfile[k]; TempZMaxPlot[0] = TempZMax; TempZMaxPos = k; TempZMaxPosPlot[0]=k; } } TempFWHM = round(TempZMax/2); Plot.setLineWidth(3); tempCalibPos[0] = TempZMaxPosPlot[0] * AxialVoxelXY; Plot.add("circles", tempCalibPos, TempZMaxPlot); // move left and right from maximum to find index of FWHM TempFWHMrightPos[0] = 0; for (k=TempZMaxPos; k < lengthOf(TempZProfile); k++) { if(TempZProfile[k] <= TempFWHM){ TempFWHMrightPos[0] = k; TempFWHMrightPosInt[0] = TempZProfile[k]; k = lengthOf(TempZProfile); } } TempFWHMleftPos[0] = 0; for (k=TempZMaxPos; k > 0; k--) { if(TempZProfile[k] <= TempFWHM){ TempFWHMleftPos[0] = k; TempFWHMleftPosInt[0] = TempZProfile[k]; k = 0; } } Plot.setLineWidth(3); tempCalibPos[0] = TempFWHMleftPos[0] * AxialVoxelXY; Plot.add("circles", tempCalibPos, TempFWHMleftPosInt); tempCalibPos[0] = TempFWHMrightPos[0] * AxialVoxelXY; Plot.add("circles", tempCalibPos, TempFWHMrightPosInt); Plot.setLineWidth(2); Resolution = (TempFWHMrightPos[0]-TempFWHMleftPos[0])*AxialVoxelXY; AxialArray[0+i*2]= Resolution; Peakposition = TempZMaxPos *AxialVoxelXY; print("Axial Resolution " + AxialArray[1+i*2] + "nm [um]:\t"+ d2s(Resolution,3)); print("Peak position " + AxialArray[1+i*2] + "nm [um]:\t" + d2s(Peakposition,3)); Plot.add("line",ZPositionArray, TempZProfile); } Plot.show(); // Merge original images as RGB and save as TIFF/JPEG images if (AxialChannelNo == 1) run("RGB Color"); else if (AxialChannelNo == 2) run("Merge Channels...", "red=*None* green=Channel1 blue=Channel0 gray=*None*"); else if (AxialChannelNo >= 3) run("Merge Channels...", "red=Channel2 green=Channel1 blue=Channel0 gray=*None*"); setColor(255,255,255); setLineWidth(2); drawLine(x1,y1,x1,y2); run("Select All"); run("Copy"); close(); newImage("Axial_result", "RGB White", XWidth,XWidth + 256,1); makeRectangle(0,0, XWidth,XWidth); run("Paste"); selectWindow("Profiles"); run("Select All"); run("Copy"); close(); selectWindow("Axial_result"); makeRectangle(0,XWidth, XWidth,256); run("Paste"); run("Select None"); // Print axial resolution result on result image setFont("Monospaced", 14,"bold"); setColor(0,0,0); drawString("Axial Resolution:",70,XWidth+35); for (i=0; i= 460 && AxialArray[1+i*2] < 520) setColor(0,0,255); else if (AxialArray[1+i*2] >= 520 && AxialArray[1+i*2] < 570) setColor(0,255,0); else if (AxialArray[1+i*2] >= 570 && AxialArray[1+i*2] < 600) setColor(255,160,0); else if (AxialArray[1+i*2] >= 600) setColor(255,0,0); drawString(toString(AxialArray[1+i*2]) +"nm \t"+ d2s(AxialArray[i*2],3)+ "um", 70, XWidth+50+i*10); if (i<3) { if (i == 0) setColor(0,0,255); else if (i == 1) setColor(0,255,0); else if (i == 2) setColor(255,0,0); setFont("Monospaced", 14,"bold"); drawString(toString(AxialArray[1+i*2]) +"nm", 10, 20+i*10); } } saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText +"_AxialResolution_"+tempAxial[ax]+"nm.tif"); if (UpdateWWWSite == true){ saveAs("jpeg", WWWDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText +"_AxialResolution_"+tempAxial[ax]+"nm.jpg"); if (tempAxial[ax] == "405") axial405passed = true; if (tempAxial[ax] == "488") axial488passed = true; } axial_analysis = 1; while (nImages >= 1) close(); } } // Website Axial string update if (UpdateWWWSite == true){ if (axial405passed == true) WWWAxialString = " \n"; else WWWAxialString = WWWAxialString + "\n"; if (axial488passed == true) WWWAxialString = WWWAxialString + " \n"; else WWWAxialString = WWWAxialString + "\n"; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // End Axial resolution measurement ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Start Analysis 1um bead colocalisation analysis ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // First checking that 'bead' image series is present in the selected data file // Checking in Leica SP5 LIF file format if (ReadFormat == "lif") { seriesFound = findSeries("bead"); if ( seriesFound > -1) { setBatchMode(true); run("Bio-Formats Importer", "open=" + path +" view=[Standard ImageJ] stack_order=Default split_channels series_"+toString(seriesFound)); // Obtain recording parameters BeadChannelNo = nImages; for (i=0; i<=(BeadChannelNo-1); i++) { if (seriesCount == 1) { selectWindow(ReadName + " - C=" + toString(i)); rename("Channel"+toString(i)); } else { selectWindow(ReadName + " - bead - C=" + toString(i)); rename("Channel"+toString(i)); } } Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblVoxelX 0",wtmp); BeadVoxelXY = parseFloat(wtmp)*1000000; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblVoxelZ 0",wtmp); BeadVoxelZ = parseFloat(wtmp)*1000000; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblZoom 0",wtmp); BeadZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblPinholeAiry 0",wtmp); BeadPinhole = parseFloat(wtmp); // close windows if more than 4 channels j=0; for (i=0; i<=(BeadChannelNo-1); i++) { if (j >= 4){ selectWindow("Channel"+toString(i)); close(); } j=j+1; } BeadChannelNo = nImages; } } // Checking for bead images in Leica SP1/SP2 LEI file format else if (ReadFormat == "lei") { if (indexOf(LeicaText, "Series Name:\tbead") != -1) { BeadText = substring (LeicaText, indexOf(LeicaText, "Series Name:\tbead")); BeadVoxelWidth = substring (BeadText, indexOf(BeadText, "Voxel-Width"), indexOf(BeadText,"Voxel-Height")); BeadVoxelWidth = substring (BeadVoxelWidth, indexOf(BeadVoxelWidth, "]")+2); BeadVoxelXY = parseFloat(BeadVoxelWidth); BeadPinhole = substring (BeadText, indexOf(BeadText, "Pinhole [airy]"), indexOf(BeadText,"Size-Width")); BeadPinhole = substring (BeadPinhole, indexOf(BeadPinhole, "]")+2); BeadPinhole = parseFloat(BeadPinhole); BeadVoxelDepth = substring (BeadText, indexOf(BeadText, "Voxel-Depth"), indexOf(BeadText,"Zoom")); BeadVoxelDepth = substring (BeadVoxelDepth, indexOf(BeadVoxelDepth, "]")+2); BeadVoxelZ = parseFloat(BeadVoxelDepth); BeadChannels = substring (LeicaText, indexOf(LeicaText, "Series Name:\tbead")-300, indexOf(LeicaText,"Series Name:\tbead")); BeadChannels = substring (BeadChannels, indexOf(BeadChannels, "Dimension_2"), indexOf(BeadChannels,"Dimension_3")); BeadChannels = substring (BeadChannels, indexOf(BeadChannels, "Logical Size:")+17, indexOf(BeadChannels,"Physical Length")); BeadChannelNo = parseInt(BeadChannels); BeadZoom = substring (BeadText, indexOf(BeadText, "Zoom"), indexOf(BeadText,"Scan-Direction")); BeadZoom = substring (BeadZoom, indexOf(BeadZoom, "Zoom")+4); BeadZoom = parseFloat(BeadZoom); setBatchMode(true); for (i=0; i<=(BeadChannelNo-1); i++) { ReadFileName=substring(ReadName, 0,lastIndexOf(ReadName, "."))+"_bead"; ReadChannel = "ch0" + toString(i); OpenSeries(); rename("Channel"+toString(i)); } } } // not applicable for Deltavision system else if (ReadFormat == "dv") { } // Checking for bead images in Zeiss 510 LSM file format else if (ReadFormat == "lsm") { if (File.exists(ReadDir + "\\"+"bead.lsm") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"bead.lsm"); Ext.setSeries(0); run("Bio-Formats Importer", "open="+ReadDir + "\\"+"bead.lsm" + " color_mode=Default split_channels view=[Standard ImageJ] stack_order=Default"); getVoxelSize(BeadVoxelXY, height, BeadVoxelZ, unit); Ext.getSeriesMetadataValue("Recording #1 Zoom X",wtmp); BeadZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("DetectionChannel #1 Pinhole Diameter",wtmp); BeadPinhole = parseFloat(wtmp); BeadChannelNo = nImages; for (i=0; i<=(BeadChannelNo-1); i++) { selectWindow("bead.lsm"+ " - C="+toString(i)); rename("Channel"+toString(i)); } } } // Checking for bead images in Zeiss LSM780 file format else if (ReadFormat == "czi") { if (File.exists(ReadDir + "\\"+"bead.czi") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"bead.czi"); Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"bead.czi"); rename("Channel"); getVoxelSize(BeadVoxelXY, height, BeadVoxelZ, unit); Ext.getMetadataValue("Experiment|AcquisitionBlock|AcquisitionModeSetup|ZoomX|0",wtmp); BeadZoom = parseFloat(wtmp); Ext.getMetadataValue("Information|Image|Channel|PinholeSize|0",wtmp); BeadPinhole = parseFloat(wtmp); run("Split Channels"); BeadChannelNo = nImages; for (i=0; i<=(BeadChannelNo-1); i++) { selectWindow("C"+toString(i+1)+"-Channel"); rename("Channel"+toString(i)); } } } // Checking Nikon ND2 file format else if (ReadFormat == "nd2"){ if (File.exists(ReadDir + "\\"+"bead.nd2") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"bead.nd2"); Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"bead.nd2"); rename("Channel"); getVoxelSize(BeadVoxelXY, height, BeadVoxelZ, unit); Ext.getMetadataValue("dZStep",wtmp); BeadVoxelZ= parseFloat(wtmp); Ext.getMetadataValue("ImagingZoom",wtmp); BeadZoom = parseFloat(wtmp); Ext.getMetadataValue("PinholeSize",wtmp); BeadPinhole = parseFloat(wtmp); run("Split Channels"); BeadChannelNo = nImages; minTemp=100000; maxTemp=0; for (i=0; i<=(BeadChannelNo-1); i++) { selectWindow("C"+toString(i+1)+"-Channel"); rename("Channel"+toString(i)); for (t=1;t<=nSlices; t++) { setSlice(t); getStatistics(area, mean, min, max); if (min < minTemp) minTemp = min; if (max > maxTemp) maxTemp = max; } setMinAndMax(minTemp, maxTemp); run("8-bit"); } } } // open bead images as composite TIFF stack and manually enter the required parameters else if (ReadFormat == "tif"){ if (File.exists(ReadDir + "\\"+"bead.tif") == 1) { setBatchMode(true); BeadVoxelXY = getNumber("Bead Colocalisation: Enter XY pixelsize [um]", 0.2); BeadVoxelZ = getNumber("Bead Colocalisation: Enter Z step size [um]", 0.2); BeadZoom = getNumber("Bead Colocalisation: Enter Zoom Factor", 16.0); BeadPinhole = getNumber("Bead Colocalisation: Enter pinhole diameter [airy units]", 1); open(ReadDir + "\\"+"bead.tif"); rename("Channel"); run("Split Channels"); BeadChannelNo = nImages; for (i=0; i<=(BeadChannelNo-1); i++) { selectWindow("C"+toString(i+1)+"-Channel"); rename("Channel"+toString(i)); } } } // if bead images present continue with processing if (nImages > 0) { ResultImageID = newArray(BeadChannelNo); oriResultImageID = newArray(BeadChannelNo); MergeImageID = newArray(BeadChannelNo); oriMergeImageID = newArray(BeadChannelNo); XZScalingFactor = round(BeadVoxelZ/BeadVoxelXY); //array with channels: x,y,z coordinates + colour BeadArray = newArray(BeadChannelNo * 4); print("\nColocalisation in 1um beads"); print("------------------------------------------------------ \n"); print("XY dimension [um]:" ,"\t" ,toString(d2s(BeadVoxelXY,3))); print("Z dimension [um]:" , "\t" , toString(d2s(BeadVoxelZ,3))); print("Zoom Factor :" , "\t" , d2s(BeadZoom,3)); if (ReadFormat == "czi" || ReadFormat == "lsm" || ReadFormat == "nd2") print("Pinhole diameter [um]:", "\t", d2s(BeadPinhole,3)); else print("Pinhole diameter [airy]:", "\t", d2s(BeadPinhole,3)); //loop by number of channels and process to obtain outline and centroids for (i=0; i<=(BeadChannelNo-1); i++) { selectWindow("Channel" + toString(i)); StackID = getImageID(); StackImageWidth = getWidth(); StackNoSlices = nSlices; // noise reduction with median filter run("Median...", "radius=7 stack"); StackWindowName = getTitle(); run("Duplicate...", "title=[StackWindowName] duplicate"); OriStackID = getImageID(); selectImage(StackID); FindBrightestSlice(); BeadArray[3+i*4] = BeadLaser[i]; // binarise stack: threshold = halfmaximal intensity; calculate and print centroid information getStatistics(area, mean, min, max, std, histogram); MaxIntensity=max; MinIntensity=min; ChannelThreshold = round(max/2); setThreshold(ChannelThreshold, 255); run("Convert to Mask", " "); CalculateCentroid(); BeadArray[i*4] = Centroid[0] * BeadVoxelXY; BeadArray[1+i*4] = Centroid[1] * BeadVoxelXY; BeadArray[2+i*4] = (Centroid[2] * BeadVoxelZ)-BeadVoxelZ; print("\n"); print("Laserline [nm]:","\t", BeadArray[3+i*4]); print("Centroid X [um]:","\t", d2s(BeadArray[i*4],3)); print("Centroid Y [um]:","\t", d2s(BeadArray[1+i*4],3)); print("Centroid Z [um]:","\t", d2s(BeadArray[2+i*4],3)); //Create Result images XY, XZ, YZ for both binary and original images //plot centroid XZ makeLine(0, Centroid[1], getWidth(), Centroid[1]); run("Reslice [/]...", "input=1.000 output=1.000 slice=1 avoid"); rename("temp_XZ"); setColor(0); fillOval(Centroid[0], BeadArray[2+i*4]/BeadVoxelZ, 3, 3); run("Scale...", "x=1 y=" + d2s(XZScalingFactor,0)+" width=" + getWidth() +" height=" + d2s(getHeight()*XZScalingFactor,0) +" create title=[XZ]"); selectWindow("temp_XZ"); close(); selectImage(OriStackID); makeLine(0, Centroid[1], getWidth(), Centroid[1]); run("Reslice [/]...", "input=1.000 output=1.000 slice=1 avoid"); rename("temp_oriXZ"); run("Scale...", "x=1 y=" + d2s(XZScalingFactor,0)+" width=" + getWidth() +" height=" + d2s(getHeight()*XZScalingFactor,0) +" create title=[oriXZ]"); selectWindow("temp_oriXZ"); close(); //plot centroid YZ selectImage(StackID); makeLine(Centroid[0], 0, Centroid[0], getHeight(),Centroid[1]); run("Reslice [/]...", "input=1.000 output=1.000 slice=1 rotate avoid"); rename("temp_YZ"); setColor(0); fillOval(BeadArray[2+i*4]/BeadVoxelZ, Centroid[1], 3, 3); run("Scale...", "x=" +d2s(XZScalingFactor,0)+ " y=1 width=" + getHeight() +" height=" + d2s(getWidth()*XZScalingFactor,0) +" create title=[YZ]"); selectWindow("temp_YZ"); close(); selectImage(OriStackID); makeLine(Centroid[0], 0, Centroid[0], getHeight(),Centroid[1]); run("Reslice [/]...", "input=1.000 output=1.000 slice=1 rotate avoid"); rename("temp_oriYZ"); run("Scale...", "x=" +d2s(XZScalingFactor,0)+ " y=1 width=" + getHeight() +" height=" + d2s(getWidth()*XZScalingFactor,0) +" create title=[oriYZ]"); selectWindow("temp_oriYZ"); close(); // assemble binarised image montage selectImage(StackID); setSlice(round(Centroid[2])); //plot centroid setColor(0); fillOval(Centroid[0], Centroid[1], 3, 3); makeLine(0,0,0,0); run("Select All"); run("Copy"); selectImage(StackID); NewImageDimensions = StackImageWidth*3; close(); newImage("ChannelResult", "8-bit",NewImageDimensions,StackImageWidth,1); ResultImageID[i] = getImageID(); selectImage(ResultImageID[i]); makeRectangle(0, 0, StackImageWidth, StackImageWidth); run("Paste"); setColor(255); setFont("Monospaced", 14,"bold"); drawString(toString(BeadArray[3+i*4]) +"nm", 10, 20+i*10); setColor(0); selectWindow("YZ"); run("Rotate 90 Degrees Right"); run("Select All"); run("Copy"); selectImage(ResultImageID[i]); makeRectangle(StackImageWidth*2, (StackImageWidth/2)-((StackNoSlices * XZScalingFactor))/2, StackImageWidth, StackNoSlices * XZScalingFactor); run("Paste"); selectWindow("XZ"); run("Select All"); run("Copy"); selectImage(ResultImageID[i]); makeRectangle(StackImageWidth, (StackImageWidth/2)-((StackNoSlices * XZScalingFactor))/2, StackImageWidth, StackNoSlices * XZScalingFactor); run("Paste"); run("Select All"); run("Invert"); run("Outline"); selectWindow("XZ"); close(); selectWindow("YZ"); close(); // assemble original image montage selectImage(OriStackID); setSlice(round(Centroid[2])); makeLine(0,0,0,0); run("Select All"); run("Copy"); selectImage(OriStackID); NewImageDimensions = StackImageWidth*3; close(); newImage("ChannelOriResult"+toString(i), "8-bit black", NewImageDimensions,StackImageWidth,1); oriResultImageID[i] = getImageID(); selectImage(oriResultImageID[i]); makeRectangle(0, 0, StackImageWidth, StackImageWidth); run("Paste"); setColor(255); setFont("Monospaced", 14,"bold"); drawString(toString(BeadArray[3+i*4]) +"nm \t"+ toString(TextColour[i]), 10, 20+i*10); selectWindow("oriYZ"); run("Rotate 90 Degrees Right"); run("Select All"); run("Copy"); selectImage(oriResultImageID[i]); makeRectangle(StackImageWidth*2, (StackImageWidth/2)-((StackNoSlices * XZScalingFactor))/2, StackImageWidth, StackNoSlices * XZScalingFactor); run("Paste"); selectWindow("oriXZ"); run("Select All"); run("Copy"); selectImage(oriResultImageID[i]); makeRectangle(StackImageWidth, (StackImageWidth/2)-((StackNoSlices * XZScalingFactor))/2, StackImageWidth, StackNoSlices * XZScalingFactor); run("Paste"); run("Select None"); setMinAndMax(MinIntensity, MaxIntensity); if (MinIntensity != 0 || MaxIntensity !=255) run("Apply LUT"); selectWindow("oriXZ"); close(); selectWindow("oriYZ"); close(); } //merge different binary channels into one RGB image and save as TIFF and JPEG for (i=0; i<=(BeadChannelNo-1); i++) { newImage("WhiteImage", "8-bit white", NewImageDimensions,StackImageWidth,1); selectImage(ResultImageID[i]); mergeImageTitle = getTitle(); if (parseInt(BeadArray[3+i*4])<460) run("Merge Channels...", "red=ChannelResult green=ChannelResult blue=WhiteImage gray=*None*"); else if (parseInt(BeadArray[3+i*4])>=460 && parseInt(BeadArray[3+i*4])<520) run("Merge Channels...", "red=ChannelResult green=WhiteImage blue=ChannelResult gray=*None*"); else if (parseInt(BeadArray[3+i*4])>=520 && parseInt(BeadArray[3+i*4])<570) run("Merge Channels...", "red=WhiteImage green=ChannelResult blue=ChannelResult gray=*None*"); else if (parseInt(BeadArray[3+i*4])>=570) run("Merge Channels...", "red=ChannelResult green=ChannelResult blue=ChannelResult gray=*None*"); rename("Merged"+toString(i)); } for (i=0;i=2) { imageCalculator("Min create", "FinalResult","Merged" + toString(i)); rename("FinalResulttemp"); selectWindow("FinalResult"); close(); selectWindow("FinalResulttemp"); rename("FinalResult"); selectWindow("Merged" + toString(i)); close(); } } setColor(0,0,0); setFont("Monospaced", 20,"bold"); drawString("XY", 115, 240); drawString("XZ", 115+StackImageWidth, 240); drawString("YZ", 115+2*StackImageWidth, 240); saveAs("Tiff", ReadDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText + "_1umBead_result.tif"); if (UpdateWWWSite == true) saveAs("jpeg", WWWDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText + "_1umBead_result.jpg"); close(); // merge original images as RGB and save as TIFF/JPEG images if (BeadChannelNo == 2) run("Merge Channels...", "red=*None* green=ChannelOriResult1 blue=ChannelOriResult0 gray=*None*"); else if (BeadChannelNo > 2) run("Merge Channels...", "red=ChannelOriResult2 green=ChannelOriResult1 blue=ChannelOriResult0 gray=*None*"); setColor(255,255,255); setFont("Monospaced", 20,"bold"); drawString("XY", 115,240 ); drawString("XZ", 115+StackImageWidth, 240); drawString("YZ", 115+2*StackImageWidth, 240); saveAs("Tiff", ReadDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText +"_1umBead_ori.tif"); // Website bead string update if (UpdateWWWSite == true){ saveAs("jpeg", WWWDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText + "_1umBead_ori.jpg"); WWWBeadString = " \n"; WWWBeadString = WWWBeadString + " \n"; } while (nImages >= 1) close(); // Calculate distances between individual centroids in XY and Z print("\n"); if (BeadChannelNo == 2) { tempCalc = sqrt(pow(BeadArray[0]-BeadArray[4],2)+pow(BeadArray[1]-BeadArray[5],2)); print("XY distance ", BeadArray[3]," - ", BeadArray[7], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = "

"+BeadArray[3]+"-"+BeadArray[7]+"nm XY: "+d2s(tempCalc,3)+"um"; tempCalc = BeadArray[2]-BeadArray[6]; print("Z distance ", BeadArray[3]," - ", BeadArray[7], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString + " Z: "+d2s(tempCalc,3)+"um

"; } if (BeadChannelNo == 3) { tempCalc = sqrt(pow(BeadArray[0]-BeadArray[4],2)+pow(BeadArray[1]-BeadArray[5],2)); print("XY distance ", BeadArray[3]," - ", BeadArray[7], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = "

"+BeadArray[3]+"-"+BeadArray[7]+"nm XY: "+d2s(tempCalc,3)+"um"; tempCalc = abs(BeadArray[2]-BeadArray[6]); print("Z distance ", BeadArray[3]," - ", BeadArray[7], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString + " Z: "+d2s(tempCalc,3)+"um

"; print("\n"); tempCalc = sqrt(pow(BeadArray[0]-BeadArray[8],2)+pow(BeadArray[1]-BeadArray[9],2)); print("XY distance ", BeadArray[3]," - ", BeadArray[11], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString +"

"+BeadArray[3]+"-"+BeadArray[11]+"nm XY: "+d2s(tempCalc,3)+"um"; tempCalc = abs(BeadArray[2]-BeadArray[10]); print("Z distance ", BeadArray[3]," - ", BeadArray[11], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString + " Z: "+d2s(tempCalc,3)+"um

"; print("\n"); tempCalc = sqrt(pow(BeadArray[4]-BeadArray[8],2)+pow(BeadArray[5]-BeadArray[9],2)); print("XY distance ", BeadArray[7]," - ", BeadArray[11], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString +"

"+BeadArray[7]+"-"+BeadArray[11]+"nm XY: "+d2s(tempCalc,3)+"um"; tempCalc = abs(BeadArray[6]-BeadArray[10]); print("Z distance ", BeadArray[7]," - ", BeadArray[11], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString + " Z: "+d2s(tempCalc,3)+"um

"; } if (BeadChannelNo == 4) { tempCalc = sqrt(pow(BeadArray[0]-BeadArray[4],2)+pow(BeadArray[1]-BeadArray[5],2)); print("XY distance ", BeadArray[3]," - ", BeadArray[7], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = "

"+BeadArray[3]+"-"+BeadArray[7]+"nm XY: "+d2s(tempCalc,3)+"um"; tempCalc = abs(BeadArray[2]-BeadArray[6]); print("Z distance ", BeadArray[3]," - ", BeadArray[7], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString + " Z: "+d2s(tempCalc,3)+"um

"; print("\n"); tempCalc = sqrt(pow(BeadArray[0]-BeadArray[8],2)+pow(BeadArray[1]-BeadArray[9],2)); print("XY distance ", BeadArray[3]," - ", BeadArray[11], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString+"

"+BeadArray[3]+"-"+BeadArray[11]+"nm XY: "+d2s(tempCalc,3)+"um"; tempCalc = abs(BeadArray[2]-BeadArray[10]); print("Z distance ", BeadArray[3]," - ", BeadArray[11], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString + " Z: "+d2s(tempCalc,3)+"um

"; print("\n"); tempCalc = sqrt(pow(BeadArray[0]-BeadArray[12],2)+pow(BeadArray[1]-BeadArray[13],2)); print("XY distance ", BeadArray[3]," - ", BeadArray[15], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString+"

"+BeadArray[3]+"-"+BeadArray[15]+"nm XY: "+d2s(tempCalc,3)+"um"; tempCalc = abs(BeadArray[2]-BeadArray[14]); print("Z distance ", BeadArray[3]," - ", BeadArray[15], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString + " Z: "+d2s(tempCalc,3)+"um

"; print("\n"); tempCalc = sqrt(pow(BeadArray[4]-BeadArray[8],2)+pow(BeadArray[5]-BeadArray[9],2)); print("XY distance ", BeadArray[7]," - ", BeadArray[11], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString+"

"+BeadArray[7]+"-"+BeadArray[11]+"nm XY: "+d2s(tempCalc,3)+"um"; tempCalc = abs(BeadArray[6]-BeadArray[10]); print("Z distance ", BeadArray[7]," - ", BeadArray[11], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString + " Z: "+d2s(tempCalc,3)+"um

"; print("\n"); tempCalc = sqrt(pow(BeadArray[4]-BeadArray[12],2)+pow(BeadArray[5]-BeadArray[13],2)); print("XY distance ", BeadArray[7]," - ", BeadArray[15], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString+"

"+BeadArray[7]+"-"+BeadArray[15]+"nm XY: "+d2s(tempCalc,3)+"um"; tempCalc = abs(BeadArray[6]-BeadArray[14]); print("Z distance ", BeadArray[7]," - ", BeadArray[15], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString + " Z: "+d2s(tempCalc,3)+"um

"; print("\n"); tempCalc = sqrt(pow(BeadArray[8]-BeadArray[12],2)+pow(BeadArray[9]-BeadArray[13],2)); print("XY distance ", BeadArray[11]," - ", BeadArray[15], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString+"

"+BeadArray[11]+"-"+BeadArray[15]+"nm XY: "+d2s(tempCalc,3)+"um"; tempCalc = abs(BeadArray[10]-BeadArray[14]); print("Z distance ", BeadArray[11]," - ", BeadArray[15], "nm [um]","\t",d2s(tempCalc,3)); WWWDistanceString = WWWDistanceString + " Z: "+d2s(tempCalc,3)+"um

"; } if (UpdateWWWSite == true) WWWBeadString = WWWBeadString + WWWDistanceString; bead_analysis = 1; setBatchMode(false); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // End of 1um bead colocalisation analysis ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Start Field illumination analysis ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// field405passed = false; field488passed = false; field543passed = false; field561passed = false; field633passed = false; WWWFieldString = ""; // First checking that 'field' images are present in the selected file format: for (fd=0; fd -1) { Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblVoxelX 0",wtmp); FieldVoxelXY = parseFloat(wtmp)*1000000; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblZoom 0",wtmp); FieldZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblPinholeAiry 0",wtmp); FieldPinhole = parseFloat(wtmp); setBatchMode(true); run("Bio-Formats Importer", "open=" + path +" view=[Standard ImageJ] stack_order=Default split_channels series_"+toString(seriesFound)); } } // Checking in Leica SP1/SP2 LEI file format else if (ReadFormat == "lei") { if (indexOf(LeicaText, "Series Name:\tfield" + laserlines[fd]) != -1) { FieldText = substring (LeicaText, indexOf(LeicaText, "Series Name:\tfield"+laserlines[fd])); FieldVoxelWidth = substring (FieldText, indexOf(FieldText, "Voxel-Width"), indexOf(FieldText,"Voxel-Height")); FieldVoxelWidth = substring (FieldVoxelWidth, indexOf(FieldVoxelWidth, "]")+2); FieldVoxelXY = parseFloat(FieldVoxelWidth); FieldZoom = substring (FieldText, indexOf(FieldText, "Zoom"), indexOf(FieldText,"Scan-Direction")); FieldZoom = substring (FieldZoom, indexOf(FieldZoom, "Zoom")+4); FieldZoom = parseFloat(FieldZoom); FieldPinhole = substring (FieldText, indexOf(FieldText, "Pinhole [airy]"), indexOf(FieldText,"Size-Width")); FieldPinhole = substring (FieldPinhole, indexOf(FieldPinhole, "]")+2); FieldPinhole = parseFloat(FieldPinhole); setBatchMode(true); ReadFileName="field"+laserlines[fd]; ReadChannel = "ch00"; OpenSeries(); } } // Checking for field images in Deltavision file format else if (ReadFormat == "dv") { } // Checking for field images in Zeiss 510 LSM file format else if (ReadFormat == "lsm") { if (File.exists(ReadDir + "\\"+"field"+laserlines[fd]+".lsm") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"field"+laserlines[fd]+".lsm"); Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"field"+laserlines[fd]+".lsm"); getPixelSize(unit, FieldVoxelXY, pixelheight); Ext.getSeriesMetadataValue("Recording #1 Zoom X",wtmp); FieldZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("DetectionChannel #1 Pinhole Diameter",wtmp); FieldPinhole = parseFloat(wtmp); } } // Checking for field images in Zeiss LSM780 file format else if (ReadFormat == "czi") { if (File.exists(ReadDir + "\\"+"field"+laserlines[fd]+".czi") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"field"+laserlines[fd]+".czi") Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"field"+laserlines[fd]+".czi") rename("Channel"); getPixelSize(unit, FieldVoxelXY, pixelheight); Ext.getMetadataValue("Experiment|AcquisitionBlock|AcquisitionModeSetup|ZoomX|0",wtmp); FieldZoom = parseFloat(wtmp); Ext.getMetadataValue("Information|Image|Channel|PinholeSize|0",wtmp); FieldPinhole = parseFloat(wtmp); } } // Checking for field images in Nikon ND2 file format else if (ReadFormat == "nd2"){ if (File.exists(ReadDir + "\\"+"field"+laserlines[fd] + ".nd2") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"field"+laserlines[fd]+".nd2") Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"field"+laserlines[fd]+".nd2"); run("8-bit"); rename("Channel"); getPixelSize(unit, FieldVoxelXY, pixelheight); Ext.getMetadataValue("ImagingZoom",wtmp); FieldZoom = parseFloat(wtmp); Ext.getMetadataValue("PinholeSize",wtmp); FieldPinhole = parseFloat(wtmp); } } // Checking for field TIF images and manually enter the required parameters once, assuming all images recorded with same settings ! else if (ReadFormat == "tif"){ if (File.exists(ReadDir + "\\"+"field"+laserlines[fd]+".tif") == 1) { if (fd == 0) { FieldVoxelXY = getNumber("Field illumination: Enter XY pixelsize [um]", 0.2); FieldZoom = getNumber("Field illumination: Enter Zoom factor.", 1); FieldPinhole = getNumber("Field illumination: Enter pinhole diameter [airy units]", 1); } open(ReadDir + "\\"+"field"+laserlines[fd]+".tif"); } } // if field images present continue with processing if (nImages > 0) { setBatchMode(true); print("\nMeasurement field illumination "+laserlines[fd]+"nm"); print("------------------------------------------------------ \n"); print("XY dimension [um]:" ,"\t" ,d2s(FieldVoxelXY,8)); print("Zoom Factor :" , "\t" , d2s(FieldZoom,3)); if (ReadFormat == "czi" || ReadFormat == "lsm" || ReadFormat == "nd2") print("Pinhole diameter [um]:", "\t", d2s(FieldPinhole,3)); else print("Pinhole diameter [airy]:", "\t", d2s(FieldPinhole,3)); print("\n"); //Smoothen image run("Mean...", "sigma=5"); // get X Intensity profile averaged over 10 lines to reduce noise further xWidth = getWidth(); XProfile = newArray(xWidth); yStart = (getHeight()/2)-5; for (x = 0; x < xWidth; x++) { tempXY = 0; for (y = yStart; y < (yStart + 10); y++) { tempXY = tempXY + getPixel(x, y); } tempXY = tempXY / 10; XProfile[x] = round(tempXY); } // get Y Intensity profile averaged over 10 lines to reduce noise furthere yWidth = getHeight(); YProfile = newArray(yWidth); xStart = (yWidth/2)-5; for (y = 0; y < yWidth; y++) { tempXY = 0; for (x = xStart; x < (xStart + 10); x++) { tempXY = tempXY + getPixel(x, y); } tempXY = tempXY / 10; YProfile[y] = round(tempXY); } // Contrast stretching of original image getStatistics(area, mean, min, max, std, histogram); MaxIntensity=max; MinIntensity=min; setMinAndMax(MinIntensity, MaxIntensity); run("Apply LUT"); // Plot black lines indicating position of line profiles setColor(0); setLineWidth(3); drawLine(0, yStart+5, xWidth, yStart+5); drawLine(xStart+5, 0, xStart+5, yWidth); run("Select All"); run("Copy"); close(); newImage("Field_result", "8-bit black", xWidth+512,yWidth,1); makeRectangle(0,0, xWidth,yWidth); run("Paste"); // Get min and max intensities from X and Y intensity profiles XStats = newArray(3); XStats = GetLineStats(XProfile); minX = XStats[0]; maxX = XStats[1]; print("Minimum Intensity X Profile :" , "\t" , toString(minX)); print("Maximum Intensity X Profile :" , "\t" , toString(maxX)); dIntX = 100*(1-(minX/maxX)); print("dIntensity X [%]:"+ "\t", d2s(dIntX,1)); YStats = newArray(3); YStats = GetLineStats(YProfile); minY = YStats[0]; maxY = YStats[1]; print("Minimum Intensity Y Profile :" , "\t" , toString(minY)); print("Maximum Intensity Y Profile :" , "\t" , toString(maxY)); dIntY = 100*(1-(minY/maxY)); print("dIntensity Y [%]:"+ "\t", d2s(dIntY,1)); if (minY <= minX) minX = minY; if (maxY >= maxX) maxX = maxY; // Create plots run("Profile Plot Options...", "width=" + xWidth-78 +" height=201 minimum=0 maximum=0 interpolate draw"); Plot.create("Profiles", "Pixel", "Intensity"); Plot.setLimits(0, xWidth, minX, maxX); Plot.setLineWidth(2); Plot.setColor("lightGray"); Plot.add("line", XProfile); Plot.setColor("Black"); Plot.add("line", YProfile); Plot.show(); run("8-bit"); run("Select All"); run("Copy"); close(); selectWindow("Field_result"); makeRectangle(xWidth,0, xWidth,256); run("Paste"); run("Select None"); Plot.create("Profiles", "Pixel", "Intensity"); Plot.setLimits(0, xWidth, 0, 255); Plot.setLineWidth(2); Plot.setColor("lightGray"); Plot.add("line", XProfile); Plot.setColor("Black"); Plot.add("line", YProfile); Plot.show(); run("8-bit"); run("Select All"); run("Copy"); close(); selectWindow("Field_result"); makeRectangle(xWidth,256, xWidth,256); run("Paste"); run("Select None"); setColor(140); setFont("SansSerif", 14, "bold"); drawString("X profile dInt=" + d2s(dIntX,1)+ " %" , 580, 40); setColor(0); drawString("Y profile dInt=" + d2s(dIntY,1)+ " %", 580, 55); drawString(laserlines[fd]+"nm", 10,20); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText + "_field_"+laserlines[fd]+"nm_result.tif"); // Website field string update if (UpdateWWWSite == true){ saveAs("jpeg", WWWDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText + "_field_"+laserlines[fd]+"nm_result.jpg"); if (laserlines[fd] == "405") field405passed = true; if (laserlines[fd] == "488") field488passed = true; if (laserlines[fd] == "543") field543passed = true; if (laserlines[fd] == "561") field561passed = true; if (laserlines[fd] == "633") field633passed = true; } while (nImages >= 1) close(); field_analysis = 1; } setBatchMode(false); } if (UpdateWWWSite == true){ if (field405passed == true) WWWFieldString = WWWFieldString+ " \n"; else WWWFieldString = WWWFieldString+ "\n"; if (field488passed == true) WWWFieldString = WWWFieldString+ " \n"; else WWWFieldString = WWWFieldString+ "\n"; if (field543passed == true && field561passed == false) WWWFieldString = WWWFieldString+ " \n"; if (field543passed == false && field561passed == true) WWWFieldString = WWWFieldString+ " \n"; if (field543passed == false && field561passed == false) WWWFieldString = WWWFieldString+ "\n"; if (field633passed == true) WWWFieldString = WWWFieldString+ " \n"; else WWWFieldString = WWWFieldString+ "\n"; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // End Field illumination analysis ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Start PSF measurements ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // First checking that 'psf' image series is present: wtmp > 0 // Checking in Leica SP5 LIF file format if (ReadFormat == "lif") { seriesFound = findSeries("psf"); if ( seriesFound > -1) { // Obtain recording parameters Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblVoxelX 0",wtmp); PSFVoxelXY = parseFloat(wtmp)*1000000; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblVoxelZ 0",wtmp); PSFVoxelZ = parseFloat(wtmp)*1000000; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblZoom 0",wtmp); PSFZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblPinholeAiry 0",wtmp); PSFPinhole = parseFloat(wtmp); setBatchMode(true); run("Bio-Formats Importer", "open=" + path +" view=[Standard ImageJ] stack_order=Default split_channels series_"+toString(seriesFound)); } } // Checking in Leica SP1/SP2 LEI file format else if (ReadFormat == "lei") { if (indexOf(LeicaText, "Series Name:\tpsf") != -1) { PSFText = substring (LeicaText, indexOf(LeicaText, "Series Name:\tpsf")); // Obtain recording parameters PSFVoxelWidth = substring (PSFText, indexOf(PSFText, "Voxel-Width"), indexOf(PSFText,"Voxel-Height")); PSFVoxelWidth = substring (PSFVoxelWidth, indexOf(PSFVoxelWidth, "]")+2); PSFVoxelXY = parseFloat(PSFVoxelWidth); PSFZoom = substring (PSFText, indexOf(PSFText, "Zoom"), indexOf(PSFText,"Scan-Direction")); PSFZoom = substring (PSFZoom, indexOf(PSFZoom, "Zoom")+4); PSFZoom = parseFloat(PSFZoom); PSFPinhole = substring (PSFText, indexOf(PSFText, "Pinhole [airy]"), indexOf(PSFText,"Size-Width")); PSFPinhole = substring (PSFPinhole, indexOf(PSFPinhole, "]")+2); PSFPinhole = parseFloat(PSFPinhole); PSFVoxelDepth = substring (PSFText, indexOf(PSFText, "Voxel-Depth"), indexOf(PSFText,"Zoom")); PSFVoxelDepth = substring (PSFVoxelDepth, indexOf(PSFVoxelDepth, "]")+2); PSFVoxelZ = parseFloat(PSFVoxelDepth); setBatchMode(true); ReadFileName="psf"; ReadChannel = "ch00"; OpenSeries(); } } // Checking for psf image stack in Deltavision file format else if (ReadFormat == "dv") { } // Checking for psf image stack in Zeiss 510 LSM file format else if (ReadFormat == "lsm") { if (File.exists(ReadDir + "\\"+"psf.lsm") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"psf.lsm"); Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"psf.lsm") getVoxelSize(PSFVoxelXY, height, PSFVoxelZ, unit); Ext.getSeriesMetadataValue("Recording #1 Zoom X",wtmp); PSFZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("DetectionChannel #1 Pinhole Diameter",wtmp); PSFPinhole = parseFloat(wtmp); } } // Checking for psf images in Zeiss LSM780 file format else if (ReadFormat == "czi") { if (File.exists(ReadDir + "\\"+"psf.czi") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"psf.czi") Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"psf.czi") getVoxelSize(PSFVoxelXY, height, PSFVoxelZ, unit); Ext.getMetadataValue("Experiment|AcquisitionBlock|AcquisitionModeSetup|ZoomX|0",wtmp); PSFZoom = parseFloat(wtmp); Ext.getMetadataValue("Information|Image|Channel|PinholeSize|0",wtmp); PSFPinhole = parseFloat(wtmp); } } // Checking psf images in Nikon ND2 file format else if (ReadFormat == "nd2"){ if (File.exists(ReadDir + "\\"+"psf.nd2") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"psf.nd2"); Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"psf.nd2"); getVoxelSize(PSFVoxelXY, height, BeadVoxelZ, unit); Ext.getMetadataValue("dZStep",wtmp); PSFVoxelZ= parseFloat(wtmp); Ext.getMetadataValue("ImagingZoom",wtmp); PSFZoom = parseFloat(wtmp); Ext.getMetadataValue("PinholeSize",wtmp); PSFPinhole = parseFloat(wtmp); minTemp=100000; maxTemp=0; for (t=1;t<=nSlices; t++) { setSlice(t); getStatistics(area, mean, min, max); if (min < minTemp) minTemp = min; if (max > maxTemp) maxTemp = max; } setMinAndMax(minTemp, maxTemp); run("8-bit"); } } // Checking for psf TIF image stack and manually enter the required parameters else if (ReadFormat == "tif"){ if (File.exists(ReadDir + "\\"+"psf.tif") == 1) { setBatchMode(true); PSFVoxelXY = getNumber("PSF measurements: Enter XY pixelsize [um]", 0.2); PSFVoxelZ = getNumber("PSF measurements: Enter Z step size [um]", 0.2); PSFZoom = getNumber("PSF measurements: Enter Zoom factor.", 1); PSFPinhole = getNumber("PSF measurements: Enter pinhole diameter [airy units]", 1); open(ReadDir + "\\"+"psf.tif"); } } // if psf images present continue with processing if (nImages > 0) { XZScalingFactor = round(PSFVoxelZ/PSFVoxelXY); print("\nResolution measurements using PSF "+ PsfLaser +"nm"); print("------------------------------------------------------ \n"); print("XY dimension [um]:" ,"\t" ,d2s(PSFVoxelXY,3)); print("Z dimension [um]:" ,"\t" ,d2s(PSFVoxelZ,3)); print("Zoom Factor :" , "\t" , d2s(PSFZoom,3)); if (ReadFormat == "czi" || ReadFormat == "lsm" || ReadFormat == "nd2") print("Pinhole diameter [um]:", "\t", d2s(PSFPinhole,3)); else print("Pinhole diameter [airy]:", "\t", d2s(PSFPinhole,3)); print("\n"); // Check for Bitdepth info = getImageInfo(); BitDepth = substring(info, lastIndexOf(info,"Bits per pixel:")); BitDepth = substring(BitDepth,16, indexOf(BitDepth," (")); // Create array: xy + z resolution + colour PSFArray = newArray(3); StackID = getImageID(); StackImageWidth = getWidth(); StackNoSlices = nSlices; //duplicate stack to keep original image stack for later analysis StackWindowName = getTitle(); run("Duplicate...", "title=[StackWindowName] duplicate"); rename ("Original"); OriStackID = getImageID(); selectImage(StackID); FindBrightestSlice(); InFocusSlice = getSliceNumber(); // Dialogbox to select laserline PSFArray[2] = PsfLaser; // binarise image stack (threshold = half maximal intensity) and calculate centroid getStatistics(area, mean, min, max, std, histogram); ChannelThreshold = round(max/2); setThreshold(ChannelThreshold, 255); run("Convert to Mask", " "); CalculateCentroid(); close(); selectWindow("Original"); x = round(Centroid[0]); oriXPos = x; y = round(Centroid[1]); oriYPos = y; zProfileX = newArray(StackNoSlices); // Z-position zProfileY = newArray(StackNoSlices); // Intensity zFitX = newArray(StackNoSlices); // Fitted curve // Obtain Z intensity profile at xy centroid coordinates for (i=0; i \n"; WWWPsfString = WWWPsfString + " \n"; WWWPsfString = WWWPsfString + " \n"; WWWPsfString = WWWPsfString + " \n"; } while (nImages > 0) close(); setBatchMode(false); psf_analysis = 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // End PSF measurements ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Start grid analysis ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // First checking that 'grid' image is present: wtmp > 0 // Checking in Leica SP5 LIF file format if (ReadFormat == "lif") { seriesFound = findSeries("grid"); if ( seriesFound > -1) { // Obtain recording parameters Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblZoom 0",wtmp); GridZoom = parseFloat(wtmp); setBatchMode(true); run("Bio-Formats Importer", "open=" + path +" view=[Standard ImageJ] stack_order=Default split_channels series_"+toString(seriesFound)); } } // Checking in Leica SP1/SP2 LEI file format else if (ReadFormat == "lei") { if (indexOf(LeicaText, "Series Name:\tgrid") != -1) { GridText = substring (LeicaText, indexOf(LeicaText, "Series Name:\tgrid")); GridZoom = substring (GridText, indexOf(GridText, "Zoom"), indexOf(GridText,"Scan-Direction")); GridZoom = substring (GridZoom, indexOf(GridZoom, "Zoom")+4); GridZoom = parseFloat(GridZoom); setBatchMode(true); open(ReadDir + "\\" + substring(ReadName, 0,lastIndexOf(ReadName, "."))+"_grid_ch00.tif"); } } // not applicable to Deltavision system else if (ReadFormat == "dv") { } // Checking in Zeiss 510 LSM file format else if (ReadFormat == "lsm") { if (File.exists(ReadDir + "\\"+"grid.lsm") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"grid.lsm"); Ext.setSeries(0); setBatchMode(true); run("Bio-Formats Importer", "open="+ReadDir + "\\"+"grid.lsm" + " color_mode=Default view=[Standard ImageJ] stack_order=Default"); Ext.getSeriesMetadataValue("Recording #1 Zoom X",wtmp); GridZoom = parseFloat(wtmp); } } // Checking in Zeiss LSM780 file format else if (ReadFormat == "czi") { if (File.exists(ReadDir + "\\"+"grid.czi") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"grid.czi") Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"grid.czi") Ext.getMetadataValue("Experiment|AcquisitionBlock|AcquisitionModeSetup|ZoomX|0",wtmp); GridZoom = parseFloat(wtmp); } } // Checking for grid images in Nikon ND2 file format else if (ReadFormat == "nd2"){ if (File.exists(ReadDir + "\\"+"grid.nd2") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"grid.nd2") Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"grid.nd2"); Ext.getMetadataValue("ImagingZoom",wtmp); GridZoom = parseFloat(wtmp); } } // Checking for grid TIF image and manually enter the required parameters else if (ReadFormat == "tif"){ if (File.exists(ReadDir + "\\"+"grid.tif") == 1) { setBatchMode(true); GridZoom = getNumber("Grid Scan: Enter Zoom factor.", 1); open(ReadDir + "\\"+"grid.tif"); } } // if grid image present continue with processing if (nImages > 0) { print("\nMeasurement grid symmetry"); print("------------------------------------------------------ \n"); print("Zoom Factor :" , "\t" , d2s(GridZoom,3)); // Contrast enhancement and save result images as TIFF and JPEG files getStatistics(area, mean, min, max, std, histogram); setMinAndMax(min, max); run("8-bit"); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText + "_grid_result.tif"); // Website grid string update if (UpdateWWWSite == true){ saveAs("jpeg", WWWDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText + "_grid_result.jpg"); WWWGridString = " \n"; } while (nImages > 0) close(); setBatchMode(false); grid_analysis = 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // End grid analysis ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Start Zgalvo stability measurement ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Test that zgalvo images are present first // Checking in Leica SP5 LIF file format if (ReadFormat == "lif") { seriesFound = findSeries("zgalvo"); if ( seriesFound > -1) { Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblVoxelY 0",wtmp); ZGalvoVoxelXY = parseFloat(wtmp)*1000000; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblZoom 0",wtmp); ZGalvoZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblPinholeAiry 0",wtmp); ZGalvoPinhole = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|nDelayTime_s 0",wtmp); ZGalvoTime = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|nDelayTime_ms 0",wtmp); if (wtmp > 0) ZGalvoTime = ZGalvoTime+parseFloat(wtmp)/1000; setBatchMode(true); run("Bio-Formats Importer", "open=" + path +" view=[Standard ImageJ] stack_order=Default split_channels series_"+toString(seriesFound)); rename("Zgalvo"); } } // Checking in Leica SP1/SP2 LEI file format else if (ReadFormat == "lei") { if (indexOf(LeicaText, "Series Name:\tzgalvo") != -1) { ZGalvoText = substring (LeicaText, indexOf(LeicaText, "Series Name:\tzgalvo")); ZGalvoVoxelWidth = substring (ZGalvoText, indexOf(ZGalvoText, "Voxel-Height"), indexOf(ZGalvoText,"Zoom")); ZGalvoVoxelWidth = substring (ZGalvoVoxelWidth, indexOf(ZGalvoVoxelWidth, "]")+2); ZGalvoVoxelXY = parseFloat(ZGalvoVoxelWidth); ZGalvoZoom = substring (ZGalvoText, indexOf(ZGalvoText, "Zoom"), indexOf(ZGalvoText,"Scan-Direction")); ZGalvoZoom = substring (ZGalvoZoom, indexOf(ZGalvoZoom, "Zoom")+4); ZGalvoZoom = parseFloat(ZGalvoZoom); ZGalvoPinhole = substring (ZGalvoText, indexOf(ZGalvoText, "Pinhole [airy]"), indexOf(ZGalvoText,"Size-Width")); ZGalvoPinhole = substring (ZGalvoPinhole, indexOf(ZGalvoPinhole, "]")+2); ZGalvoPinhole = parseFloat(ZGalvoPinhole); ZGalvoTime = substring (ZGalvoText, indexOf(ZGalvoText, "Delay[s]"), indexOf(ZGalvoText,"Format-Width")); ZGalvoTime = substring (ZGalvoTime, indexOf(ZGalvoTime, "]")+5); ZGalvoTime = parseInt(ZGalvoTime); setBatchMode(true); ReadFileName="zgalvo"; ReadChannel = "ch00"; OpenSeries(); // changed for Bioformats 4.4.8 // seriesFound = findSeries("zgalvo"); // run("Bio-Formats Importer", "open=[" + path +"] view=[Standard ImageJ] stack_order=Default split_channels series_"+toString(seriesFound)); rename("Zgalvo"); } } // not applicable to Deltavision system else if (ReadFormat == "dv") { } // not applicable to Zeiss 510 system else if (ReadFormat == "lsm") { } // not applicable to Zeiss 780 system else if (ReadFormat == "czi") { } // not applicable to Nikon Air system else if (ReadFormat == "nd2") { } // Checking for Z galvo TIF stack and manually enter the required parameters else if (ReadFormat == "tif"){ if (File.exists(ReadDir + "\\"+"zgalvo.tif") == 1) { setBatchMode(true); ZGalvoVoxelXY = getNumber("Z-galvo measurements: Enter Y pixelsize [um]", 0.2); ZGalvoZoom = getNumber("Z-galvo measurements: Enter Zoom factor.", 1); ZGalvoPinhole = getNumber("Z-galvo measurements: Enter pinhole diameter [airy units]", 1); ZGalvoTime = getNumber("Z-galvo measurements: Enter image time interval [s]", 1); open(ReadDir + "\\"+"zgalvo.tif"); rename("Zgalvo"); } } // if zgalvo images present continue with processing if (nImages > 0) { print("\nMeasurement Z Galvo stability"); print("------------------------------------------------------ \n"); print("Z dimension [um]:" ,"\t" ,d2s(ZGalvoVoxelXY,3)); print("Zoom Factor :" , "\t" , toString(ZGalvoZoom)); print("Pinhole diameter [airy]:", "\t", d2s(ZGalvoPinhole,3)); print("Time interval [s]:","\t", toString(ZGalvoTime)); print("\n"); XWidth = getWidth(); YWidth = getHeight(); TimePoints = nSlices; IntensityArray = newArray(YWidth); PositionArray = newArray(TimePoints); tmpPeakFWHM = newArray(2); FWHMArray = newArray(TimePoints); FWHMMeanArray = newArray(TimePoints); MeanArray = newArray(TimePoints); TimeArray = newArray(TimePoints); xCoord = round(XWidth/2); // X position for line profile tempLineStats = newArray(3); TempFWHMleftPosInt=newArray(1); TempFWHMleftPos=newArray(1); TempFWHMrightPosInt=newArray(1); TempFWHMrightPos=newArray(1); //loop by number of timepoints - obtain Peakposition and FWHM selectWindow("Zgalvo"); for (i=1; i<=TimePoints; i++) { setSlice(i); for (y = 0; y < YWidth; y++) { tempXY = 0; for (x = xCoord-10; x < (xCoord+10); x++) tempXY = tempXY + getPixel(x, y); tempXY = tempXY / 20; IntensityArray[y] = tempXY; } tmpPeakFWHM = GetPeakFWHM(IntensityArray); PositionArray[i-1]= (YWidth-1) * ZGalvoVoxelXY - tmpPeakFWHM[0]*ZGalvoVoxelXY; FWHMArray[i-1] = tmpPeakFWHM[1]*ZGalvoVoxelXY; } selectWindow("Zgalvo"); close(); tempLineStats = GetLineStats(PositionArray); TempMin = tempLineStats[0]; TempMax = tempLineStats[1]; TempMean =tempLineStats[2]; for (i=0; i 0.8){ Plot.setLimits(0,maxTime, 0, max); } Plot.setColor("orange"); Plot.setLineWidth(1); Plot.add("curve", TimeArray, FWHMMeanArray); Plot.setColor("black"); Plot.setLineWidth(1); Plot.add("curve", TimeArray, FWHMArray); Text = "FWHM"; Plot.addText(Text, 0.01,0.07); Plot.show; newImage("Zgalvo_result", "RGB White",678,620,1); makeRectangle(0,0, 678,310); run("Paste"); selectWindow("FWHM"); run("Select All"); run("Copy"); close(); selectWindow("Zgalvo_result"); makeRectangle(0,310,678,310); run("Paste"); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText + "_Zgalvo_result.tif"); // Website grid string update if (UpdateWWWSite == true){ saveAs("jpeg", WWWDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText + "_Zgalvo_result.jpg"); WWWZgalvoString = " \n"; } while (nImages > 0) close(); run("Clear Results"); //save all peak position and FWHM data in a tab delimited text file TempString = "TIME[s]\tPEAK POSITION[um]\tFWHM[um]\n"; for (t=0; t -1) { // Obtain recording parameters Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblZoom 0",wtmp); LambdaZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblPinholeAiry 0",wtmp); LambdaPinhole = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblLambdaBeginLeft_0 0",wtmp); LambdaStart = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblLambdaBeginRight_0 0",wtmp); LambdaWindow = parseFloat(wtmp); LambdaWindow = parseInt(LambdaWindow) - parseInt(LambdaStart); LambdaStart = LambdaStart + LambdaWindow/2; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblLambdaEndLeft_0 0",wtmp); LambdaEnd = parseFloat(wtmp)+LambdaWindow/2; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|nLambdaSections 0",wtmp); LambdaStep = parseInt(wtmp); LambdaStepsize = round((parseInt(LambdaEnd)-parseInt(LambdaStart)) / LambdaStep); setBatchMode(true); p = 0; PMTGainOffset = ""; do { p = p + 1; seriesFound = findSeries("scanpmt"+toString(p)); if ( seriesFound > -1) { run("Bio-Formats Importer", "open=" + path +" view=[Standard ImageJ] stack_order=Default series_"+toString(seriesFound)); rename("PMT"+toString(p)); Ext.getSeriesMetadataValue("HardwareSetting|FilterSettingRecord|PMT "+toString(p) + " (HV) 0",wtmp); PMTGainOffset = PMTGainOffset + "PMT" + toString(p) + " Gain [V]:\t" + d2s(wtmp,2) + "\n"; Ext.getSeriesMetadataValue("HardwareSetting|FilterSettingRecord|PMT "+toString(p) + " (Offs.) 0",wtmp); PMTGainOffset = PMTGainOffset + "PMT" + toString(p) + " Offset:\t" + d2s(wtmp,2)+"\n"; } } while (nImages == p); } } // Checking in Leica SP1/SP2 LEI file format else if (ReadFormat == "lei") { if (indexOf(LeicaText, "Series Name:\tscanpmt1") != -1) { LambdaText = substring (LeicaText, indexOf(LeicaText, "Series Name:\tscanpmt1")); LambdaZoom = substring (LambdaText, indexOf(LambdaText, "Zoom"), indexOf(LambdaText,"Scan-Direction")); LambdaZoom = substring (LambdaZoom, indexOf(LambdaZoom, "Zoom")+4); LambdaZoom = parseFloat(LambdaZoom); LambdaPinhole = substring (LambdaText, indexOf(LambdaText, "Pinhole [airy]"), indexOf(LambdaText,"Size-Width")); LambdaPinhole = substring (LambdaPinhole, indexOf(LambdaPinhole, "]")+2); LambdaPinhole = parseFloat(LambdaPinhole); LambdaStart = substring (LambdaText, indexOf(LambdaText, "[LambdaBeginLeft 1]"), indexOf(LambdaText,"[LambdaBeginRight 1]")); LambdaStart = substring (LambdaStart, indexOf(LambdaStart, "]")+2); LambdaStart = parseFloat(LambdaStart); LambdaWindow = substring (LambdaText, indexOf(LambdaText, "[LambdaBeginRight 1]"), indexOf(LambdaText,"[LambdaEndLeft 1]")); LambdaWindow = substring (LambdaWindow, indexOf(LambdaWindow, "]")+2); LambdaWindow = parseFloat(LambdaWindow); LambdaWindow = LambdaWindow - LambdaStart; LambdaEnd = substring (LambdaText, indexOf(LambdaText, "[LambdaEndLeft 1]"), indexOf(LambdaText,"[LambdaEndRight 1]")); LambdaEnd = substring (LambdaEnd, indexOf(LambdaEnd, "]")+2); LambdaEnd = parseFloat(LambdaEnd); LambdaStep = substring (LambdaText, indexOf(LambdaText, "Lambda-Sections"), indexOf(LambdaText,"TIME")); LambdaStep = substring (LambdaStep, indexOf(LambdaStep, "s")+2); LambdaStep = parseInt(LambdaStep); LambdaStepsize = (LambdaEnd-LambdaStart) / LambdaStep; setBatchMode(true); PMTGainOffset = ""; p = 1; while (indexOf(LeicaText, "Series Name:\tscanpmt"+toString(p)) != -1) { run("Image Sequence...", "open=" + ReadDir + "\\" + substring(ReadName, 0,lastIndexOf(ReadName, "."))+"_scanpmt"+toString(p) + "_la000_ch00.tif number=1000 starting=1 increment=1 scale=100 file=scanpmt"+toString(p)+"_la or=[] sort"); rename("PMT"+toString(p)); //obtain Gain and Offset setting for PMTs PMTText = substring (LeicaText, indexOf(LeicaText, "Series Name:\tscanpmt"+toString(p)),indexOf(LeicaText, "Series Name:\tscanpmt"+toString(p))+600); PMTOffsetText = substring (PMTText, indexOf(PMTText, "PMT "+toString(p)+" (Offs.)")+14,indexOf(PMTText,"PMT "+toString(p)+" (HV)")); PMTOffset = parseFloat(PMTOffsetText); PMTGainText = substring (PMTText, indexOf(PMTText,"PMT "+toString(p)+" (HV)")+10, indexOf(PMTText,"PMT "+toString(p)+" (HV)")+22); PMTGain = parseFloat(PMTGainText); PMTGainOffset = PMTGainOffset + "PMT" + toString(p) + " Gain [V]:\t" + d2s(PMTGain,2) + "\n"; PMTGainOffset = PMTGainOffset + "PMT" + toString(p) + " Offset:\t" + d2s(PMTOffset,2)+"\n"; p=p+1; } } } if (nImages > 0){ // Print parameters in Log window print("\nLambda scan measurements "); print("------------------------------------------------------ \n"); print("Zoom Factor :" , "\t" , toString(LambdaZoom)); print("Pinhole diameter [airy]:", "\t", d2s(LambdaPinhole,3)); print("Scan start [nm]:","\t", toString(LambdaStart)); print("Scan end [nm]:","\t", toString(LambdaEnd)); print("Scan window width [nm]:","\t", toString(LambdaWindow)); print("Scan step size [nm]:","\t", toString(LambdaStepsize)); print("\n"); PMTNumber = nImages; XWidth = getWidth(); YWidth = getHeight(); LambdaStep = nSlices(); print (PMTGainOffset); print("\n"); // Create arrays for intensity and wavelength (lambda) IntensityArray = newArray(LambdaStep); LambdaArray = newArray(LambdaStep); TempIntensityArray = newArray(20); TempLambdaArray = newArray(20); for (j=0; j \n"; } while (nImages > 0) close(); run("Clear Results"); setBatchMode(false); lambda_analysis = 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // End lambda scan measurement ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Start laser stability measurement ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // First checking that 'laser' image series is present: // Checking in Leica SP5 LIF file format if (ReadFormat == "lif") { seriesFound = findSeries("laser"); if ( seriesFound > -1) { setBatchMode(true); run("Bio-Formats Importer", "open=" + path +" view=[Standard ImageJ] stack_order=Default split_channels series_"+toString(seriesFound)); LaserChannelNo = nImages; for (i=0; i<=(LaserChannelNo-1); i++) { if (seriesCount == 1) { selectWindow(ReadName + " - C=" + toString(i)); rename("Channel"+toString(i)); } else { selectWindow(ReadName + " - laser - C=" + toString(i)); rename("Channel"+toString(i)); } } // Obtain recording parameters Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblVoxelX 0",wtmp); LaserVoxelXY = parseFloat(wtmp)*1000000; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblZoom 0",wtmp); LaserZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|nDelayTime_s 0",wtmp); LaserTime = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|FilterSettingRecord|Scan Speed 0",wtmp); LaserScanSpeed = wtmp; } } // Checking in Leica SP1/SP2 LEI file format else if (ReadFormat == "lei") { if (indexOf(LeicaText, "Series Name:\tlaser") != -1) { LaserText = substring (LeicaText, indexOf(LeicaText, "Series Name:\tlaser")); LaserVoxelWidth = substring (LaserText, indexOf(LaserText, "Voxel-Width"), indexOf(LaserText,"Voxel-Height")); LaserVoxelWidth = substring (LaserVoxelWidth, indexOf(LaserVoxelWidth, "]")+2); LaserVoxelXY = parseFloat(LaserVoxelWidth); LaserZoom = substring (LaserText, indexOf(LaserText, "Zoom"), indexOf(LaserText,"Scan-Direction")); LaserZoom = substring (LaserZoom, indexOf(LaserZoom, "Zoom")+4); LaserZoom = parseFloat(LaserZoom); LaserTime = substring (LaserText, indexOf(LaserText, "Delay[s]"), indexOf(LaserText,"Format-Width")); LaserTime = substring (LaserTime, indexOf(LaserTime, "]")+5); LaserTime = parseInt(LaserTime); LaserChannels = substring (LeicaText, indexOf(LeicaText, "Series Name:\tlaser")-300, indexOf(LeicaText,"Series Name:\tlaser")); LaserChannels = substring (LaserChannels, indexOf(LaserChannels, "Dimension_2"), indexOf(LaserChannels,"Physical Length")); LaserChannels = substring (LaserChannels, indexOf(LaserChannels, "Logical Size:")+13, lengthOf(LaserChannels)-1); LaserChannelNo = parseInt(LaserChannels); LaserScanSpeed = substring (LaserText, indexOf(LaserText, "Scan Speed")+11, indexOf(LaserText,"Phase")); LaserScanSpeed = parseInt(LaserScanSpeed); setBatchMode(true); for (i=0; i<=(LaserChannelNo-1); i++) { ReadFileName=substring(ReadName, 0,lastIndexOf(ReadName, "."))+"_laser"; ReadChannel = "ch0" + toString(i); OpenSeries(); rename("Channel"+toString(i)); } } } // Checking for laser images in Zeiss 510 LSM file format else if (ReadFormat == "lsm") { if (File.exists(ReadDir + "\\"+"laser.lsm") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"laser.lsm"); Ext.setSeries(0); run("Bio-Formats Importer", "open="+ReadDir + "\\"+"laser.lsm" + " color_mode=Default split_channels view=[Standard ImageJ] stack_order=Default"); LaserChannelNo = nImages; for (i=0; i<=(LaserChannelNo-1); i++) { selectWindow("laser.lsm - C=" + toString(i)); rename("Channel"+toString(i)); } getPixelSize(unit, LaserVoxelXY, pixelHeight); Ext.getPixelsTimeIncrement(LaserTime); LaserTime = parseInt(LaserTime); Ext.getSeriesMetadataValue("Recording #1 Zoom X",wtmp); LaserZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("Track #1 Pixel Time",wtmp); PixelTime = parseFloat(wtmp); XWidth = getWidth(); // Laser scan speed in Hz interpolated from Pixel dwell time obtained from metadata LaserScanSpeed = 1/(PixelTime*XWidth/1000000); } } // Checking in Zeiss LSM780 file format else if (ReadFormat == "czi") { if (File.exists(ReadDir + "\\"+"laser.czi") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"laser.czi") Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"laser.czi") run("Split Channels"); LaserChannelNo = nImages; for (i=1; i<=LaserChannelNo; i++) { selectWindow("C" + toString(i)+"-laser.czi"); rename("Channel"+toString(i-1)); } getPixelSize(unit, LaserVoxelXY, pixelHeight); LaserTime = getNumber("Laser stability: Enter time interval between images [s]", 20.0); Ext.getMetadataValue("Experiment|AcquisitionBlock|AcquisitionModeSetup|PixelPeriod|0",wtmp); PixelTime = parseFloat(wtmp); XWidth = getWidth(); // Laser scan speed in Hz interpolated from Pixel dwell time obtained from metadata LaserScanSpeed = parseInt(1/(PixelTime*XWidth)); Ext.getMetadataValue("Experiment|AcquisitionBlock|AcquisitionModeSetup|ZoomX|0",wtmp); LaserZoom = parseFloat(wtmp); } } // Checking in Nikon ND2 file format else if (ReadFormat == "nd2"){ if (File.exists(ReadDir + "\\"+"laser.nd2") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"laser.nd2"); Ext.setSeries(0); Ext.openImagePlus(ReadDir + "\\"+"laser.nd2") run("Split Channels"); LaserChannelNo = nImages; selectWindow("C1-laser.nd2"); close(); selectWindow("C2-laser.nd2"); rename("Channel0"); getPixelSize(unit, LaserVoxelXY, pixelHeight); Ext.getMetadataValue("dPeriod",wtmp); LaserTime = parseFloat(wtmp); LaserTime = LaserTime/1000.0; Ext.getMetadataValue("ImagingZoom",wtmp); LaserZoom = parseFloat(wtmp); XWidth = getWidth(); PixelTime = getNumber("Laser stability: Enter laser pixel dwell time [us]", 1.2); // Laser scan speed in Hz interpolated from Pixel dwell time obtained from metadata LaserScanSpeed = parseInt(1/(PixelTime*XWidth)); } } // not applicable to Deltavision system else if (ReadFormat == "dv") { } // Checking for laser composite TIF stack and manually enter the required parameters else if (ReadFormat == "tif"){ if (File.exists(ReadDir + "\\"+"laser.tif") == 1) { LaserVoxelXY = getNumber("Laser stability: Enter XY pixelsize [um]", 0.2); LaserZoom = getNumber("Laser stability: Enter Zoom Factor", 16.0); LaserScanSpeed = getNumber("Laser stability: Enter laser scan speed [Hz]", 400.0); LaserTime = getNumber("Laser stability: Enter time interval between images [s]", 20.0); setBatchMode(true); open(ReadDir + "\\"+"laser.tif"); rename("Channel"); getDimensions(width, height, channels, slices, frames); if (channels > 1) { run("Split Channels"); LaserChannelNo = nImages; for (i=0; i<=(LaserChannelNo-1); i++) { selectWindow("C"+toString(i+1)+"-Channel"); rename("Channel"+toString(i)); } } else rename("Channel0"); } } // if laser images present continue with processing if (nImages > 0) { LaserChannelNo = nImages; XWidth = getWidth(); YWidth = getHeight(); XLineArray = newArray(XWidth); for (i=0; i 100) AnalysisPoints = 100; else AnalysisPoints = TimePoints; // Create arrays for average intensity , stdDev and time MeanIntensityArray = newArray(TimePoints); StdDevIntensityArray = newArray(TimePoints); MeanResultArray = newArray(TimePoints*LaserChannelNo); StdDevResultArray = newArray(TimePoints*LaserChannelNo); TimeArray = newArray(TimePoints); for (j=0; j 600) tenMinuteProcessedArray = newArray(TimePoints*LaserChannelNo-LaserChannelNo*600/LaserTime); // only create if more than 1h timecourse if (LaserDuration > 3600) hourProcessedArray = newArray(TimePoints*LaserChannelNo-LaserChannelNo*3600/LaserTime); // Array with channels: colour LaserArray = newArray(LaserChannelNo); dIntArray = newArray(LaserChannelNo); // Print parameters in Log window print("\nLaser stability measurements "); print("------------------------------------------------------ \n"); print("XY dimension [um]:" ,"\t" ,d2s(LaserVoxelXY,3)); print("Zoom Factor :" , "\t" , d2s(LaserZoom,3)); if (ReadFormat == "czi") print("Pixel dwell time [us]:", "\t", d2s(PixelTime*1000000,3)); else if (ReadFormat == "lsm") print("Pixel dwell time [us]:", "\t", d2s(PixelTime,3)); else if (ReadFormat == "nd2") print("Pixel dwell time [us]:", "\t", d2s(PixelTime,3)); else print("Laser Scan Speed [Hz]:", "\t", toString(LaserScanSpeed)); print("Time interval [s]:","\t", toString(LaserTime)); print("Total duration [min]:","\t",d2s(LaserTime*TimePoints/60,0)); print("\n"); // Loop by number of channels/lasers for (i=0; i 600){ stepsize = 600/LaserTime; l = 0; for (i=0; i 3600){ stepsize = 3600/LaserTime; l = 0; for (i=0; i 600){ l = 0; for (j=0; j 3600){ l = 0; for (j=0; j 600) drawString("10 Minutes", 447, 185); if (LaserDuration > 3600) drawString("1 hour", 447, 340); selectWindow("Noise_Channel"+toString(i)); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText +"_Laserstability_" +toString(LaserArray[i])+"nm.tif"); // Website lambda string update if (UpdateWWWSite == true) saveAs("jpeg", WWWDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText + "_Laserstability_" +toString(LaserArray[i])+"nm.jpg"); close(); } print("Laser noise in single horizontal line scan:"); print("------------------------------------------------------ \n"); // Obtain Min and Max intensity values for line plots LineMin = 255; LineMax = 0; for (i=0; i= LineMax) LineMax = max; } for (i=0; i 255) Plot.setLimits(0, TimePoints*LaserTime/60, 0, max); else Plot.setLimits(0, TimePoints*LaserTime/60, 0, 255); Colour = SelectPlotColour(LaserArray[i]); Plot.setColor(Colour); Plot.setLineWidth(1); Plot.add("curve", TimeArray, MeanIntensityArray); Text = toString(LaserArray[i]) +"nm"+" dInt="+d2s(dIntArray[i],1)+"%"; Plot.addText(Text, 0.01,0.07+i*0.05); Plot.show; // Generate intensity plots with different colours for each laser - rescaled between total min and max intensities run("Profile Plot Options...", "width=600 height=255 minimum=0 maximum=255 fixed interpolate draw"); Plot.create("LaserpowerMeanRescaled"+toString(i), "Time [min]", "Intensity"); Array.getStatistics(MeanResultArray, min, max, mean, stdDev); Plot.setLimits(0, TimePoints*LaserTime/60, min, max); Colour = SelectPlotColour(LaserArray[i]); Plot.setColor(Colour); Plot.setLineWidth(1); Plot.add("curve", TimeArray, MeanIntensityArray); Text = toString(LaserArray[i]) +"nm"+" dInt="+d2s(dIntArray[i],1)+"%"; Plot.addText(Text, 0.01,0.07+i*0.05); Plot.show; // Generate intensity plots with different colours for each laser - rescaled between total min and max intensities run("Profile Plot Options...", "width=600 height=255 minimum=0 maximum=255 fixed interpolate draw"); Plot.create("LaserpowerStdDev"+toString(i), "Time [min]", "StdDev"); Array.getStatistics(StdDevResultArray, min, max, mean, stdDev); if (min < 1 && max < 1) Plot.setLimits(0, TimePoints*LaserTime/60, min, max); else Plot.setLimits(0, TimePoints*LaserTime/60, min-1, max+1); Colour = SelectPlotColour(LaserArray[i]); Plot.setColor(Colour); Plot.setLineWidth(1); Plot.add("curve", TimeArray, StdDevIntensityArray); Text = toString(LaserArray[i]) +"nm"; Plot.addText(Text, 0.01,0.07+i*0.05); Plot.show; } // Merge plots and save result images as TIFF and JPEG files for (j=1; j \n"; for (j=0; j \n"; else WWWLaserString = WWWLaserString + "\n"; if (laser488passed == true) WWWLaserString = WWWLaserString + " \n"; else WWWLaserString = WWWLaserString + "\n"; if (laser543passed == true) WWWLaserString = WWWLaserString + " \n"; if (laser561passed == true) WWWLaserString = WWWLaserString + " \n"; if (laser543passed == false && laser561passed == false ) WWWLaserString = WWWLaserString + "\n"; if (laser594passed == true) WWWLaserString = WWWLaserString + " \n"; else WWWLaserString = WWWLaserString + "\n"; if (laser633passed == true) WWWLaserString = WWWLaserString + " \n"; else WWWLaserString = WWWLaserString + "\n"; } selectWindow("LaserpowerStdDev0"); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText +"_Laserpower_StdDev_Intensity_rescaled.tif"); selectWindow("LaserpowerLine0"); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText +"_Laserpower_LineScan_Intensity_rescaled.tif"); while (nImages > 0) close(); run("Clear Results"); //save all intensity and stdDev data in a tab delimited text file String.resetBuffer; String.append("TIME[s]\t"); for (j=0; j -1) { Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblVoxelX 0",wtmp); StageVoxelXY = parseFloat(wtmp)*1000000; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblZoom 0",wtmp); StageZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblPinholeAiry 0",wtmp); StagePinhole = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|nDelayTime_s 0",wtmp); StageTime = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|nDelayTime_ms 0",wtmp); if (wtmp > 0) StageTime = StageTime+parseFloat(wtmp)/1000; setBatchMode(true); StagePositionText = ""; s = 1; while (s <= 3) { // Open 'stage' image sequence, one window for each stage position, done individually as separate recordings seriesFound = findSeries("stage"+toString(s)); if (seriesFound > -1){ Ext.getSeriesMetadataValue("HardwareSetting|FilterSettingRecord|DMI6000 Stage Pos x 0hgd",wtmp); if (wtmp == 0) Ext.getPlanePositionX(wtmp,1); StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": X [mm]\t"+ d2s(wtmp*1000,6) + "\n"; Ext.getSeriesMetadataValue("HardwareSetting|FilterSettingRecord|DMI6000 Stage Pos y 0htgs",wtmp); if (wtmp == 0) Ext.getPlanePositionY(wtmp,1); StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": Y [mm]\t"+ d2s(wtmp*1000,6)+ "\n"; run("Bio-Formats Importer", "open=" + path +" view=[Standard ImageJ] stack_order=Default series_"+toString(seriesFound)); rename("Position"+toString(s)); } s = s + 1; } } } // Checking in Zeiss 510 LSM file format else if (ReadFormat == "lsm") { if (File.exists(ReadDir + "\\"+"stage.lsm") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"stage.lsm"); Ext.getSeriesCount(StagePositions); StagePositionText = ""; wtmp = 0; s = 1; while (s <= StagePositions) { Ext.setSeries(s-1); Ext.getPlanePositionX(wtmp,1); if (wtmp == 0) Ext.getSeriesMetadataValue("X position for position #"+toString(s),wtmp); StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": X [mm]\t"+ d2s(wtmp*1000,6) + "\n"; Ext.getPlanePositionY(wtmp,1); if (wtmp == 0) Ext.getSeriesMetadataValue("Y position for position #"+toString(s),wtmp); StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": Y [mm]\t"+ d2s(wtmp*1000,6)+ "\n"; run("Bio-Formats Importer", "open="+ReadDir+"\\"+"stage.lsm"+" autoscale color_mode=Default view=Hyperstack stack_order=XYCZT series_"+toString(s)); rename("Position"+toString(s)); s=s+1; } getPixelSize(unit, StageVoxelXY, pixelHeight); Ext.getPlaneTimingDeltaT(deltaT, 1); StageTime = parseFloat(deltaT); Ext.getSeriesMetadataValue("Recording #1 Zoom X",wtmp); StageZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("DetectionChannel #1 Pinhole Diameter",wtmp); StagePinhole = parseFloat(wtmp); } } // Checking in Zeiss LSM780 file format else if (ReadFormat == "czi") { if (File.exists(ReadDir + "\\"+"stage.czi") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"stage.czi") Ext.getSeriesCount(StagePositions); StagePositionText = ""; wtmp = 0; s = 1; while (s <= StagePositions) { Ext.setSeries(s-1); Ext.getPlanePositionX(wtmp,1); StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": X [mm]\t"+ d2s(wtmp*1000,6) + "\n"; Ext.getPlanePositionY(wtmp,1); StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": Y [mm]\t"+ d2s(wtmp*1000,6)+ "\n"; run("Bio-Formats Importer", "open="+ReadDir+"\\"+"stage.czi"+" autoscale color_mode=Default view=Hyperstack stack_order=XYCZT series_"+toString(s)); rename("Position"+toString(s)); s=s+1; } getPixelSize(unit, StageVoxelXY, pixelHeight); StageTime = getNumber("Stage performance: Enter time interval between images [s]", 20.0); Ext.getMetadataValue("Information|Image|Channel|PinholeSize|0",wtmp); StagePinhole = parseFloat(wtmp); Ext.getMetadataValue("Experiment|AcquisitionBlock|AcquisitionModeSetup|ZoomX|0",wtmp); StageZoom = parseFloat(wtmp); } } // Checking stage images in Nikon ND2 file format else if (ReadFormat == "nd2"){ if (File.exists(ReadDir + "\\"+"stage.nd2") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"stage.nd2"); Ext.getSizeZ(StagePositions); wtmp = 0; StagePositionText = ""; s = 1; while (s <= StagePositions) { Ext.getPlanePositionX(wtmp,s); StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": X [mm]\t"+ d2s(wtmp/1000,6) + "\n"; Ext.getPlanePositionY(wtmp,s); StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": Y [mm]\t"+ d2s(wtmp/1000,6)+ "\n"; s=s+1; } run("Bio-Formats Importer", "open="+ReadDir + "\\"+"stage.nd2"+" autoscale color_mode=Default split_focal view=[Standard ImageJ] stack_order=Default"); for (s=1; s<=nImages; s++) { selectWindow("stage.nd2 - Z="+toString(s-1)); rename("Position"+toString(s)); minTemp=100000; maxTemp=0; for (t=1;t<=nSlices; t++) { setSlice(t); getStatistics(area, mean, min, max); if (min < minTemp) minTemp = min; if (max > maxTemp) maxTemp = max; } setMinAndMax(minTemp, maxTemp); run("8-bit"); } getPixelSize(unit, StageVoxelXY, pixelHeight); Ext.getMetadataValue("dAvgPeriodDiff",wtmp); StageTime = parseFloat(wtmp)/1000; Ext.getMetadataValue("PinholeSize",wtmp); StagePinhole = parseFloat(wtmp); Ext.getMetadataValue("ImagingZoom",wtmp); StageZoom = parseFloat(wtmp); } } // Checking whether images in Deltavision DV file format present else if (ReadFormat == "dv"){ if (File.exists(ReadDir + "\\"+"stage1_R3D.dv") == 1) { Ext.setId(ReadDir + "\\"+"stage1_R3D.dv"); Ext.setSeries(0); wtmp = 0; Ext.getMetadataValue("Image Properties Pixel Size",wtmp); StageVoxelXY = substring (wtmp,0,indexOf(wtmp," ")); StageZoom = "1.0"; StagePinhole = "10.0"; Ext.getPlaneTimingDeltaT(StageTime, 1); LogFile = File.openAsString(ReadDir + "\\"+"stage1_R3D.dv.log"); CheckForPointlist = substring(LogFile, indexOf(LogFile,"#KEY DO_POINT_VISITING")+23,indexOf(LogFile,"#KEY DO_POINT_VISITING")+24); if (CheckForPointlist == "F") DVStagePositions = 1; else if (CheckForPointlist == "T") DVStagePositions = parseInt (substring(LogFile, indexOf(LogFile,"#KEY POINT_VISIT_LIST 1-")+24,indexOf(LogFile,"#KEY POINT_VISIT_LIST 1-")+25)); setBatchMode(true); StagePositionText = ""; for (s=1; s<= DVStagePositions; s++) { Ext.setId(ReadDir+"\\"+"stage"+toString(s)+"_R3D.dv"); Ext.setSeries(0); Ext.getMetadataValue("Image 1. Stage coordinates",wtmp); xtmp = parseFloat(substring(wtmp,indexOf(wtmp,"(")+1,indexOf(wtmp,","))); ytmp = parseFloat(substring(wtmp,indexOf(wtmp,",")+1,lastIndexOf(wtmp,","))); StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": X [mm]\t"+ d2s(xtmp/1000,6) + "\n"; StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": Y [mm]\t"+ d2s(ytmp/1000,6)+ "\n"; run("Bio-Formats Importer", "open="+ReadDir+"\\"+"stage"+toString(s)+"_R3D.dv"+" view=[Standard ImageJ] stack_order=Default"); rename("Position"+toString(s)); resetMinAndMax(); run("Flip Vertically", "stack"); } } } // Checking for stage images TIF files and manually enter the required parameters else if (ReadFormat == "tif"){ if (File.exists(ReadDir + "\\"+"stage1.tif") == 1) { StageVoxelXY = getNumber("XY stage repeatability: Enter XY pixelsize [um]", 0.1); StageZoom = getNumber("XY stage repeatability: Enter Zoom Factor", 16.0); StageTime = getNumber("XY stage repeatability: Enter time interval between images [s]", 20.0); StagePinhole = getNumber("XY stage repeatability: Enter pinhole diameter [airy units]", 1); QueryStagePositions = 1; for (st=2; st <= 3; st++){ if (File.exists(ReadDir + "\\"+"stage"+toString(st)+".tif") == 1) QueryStagePositions = QueryStagePositions + 1; } setBatchMode(true); StagePositionText = ""; for (st=1; st <= QueryStagePositions; st++){ open(ReadDir + "\\"+"stage"+toString(st)+".tif"); rename("Position"+toString(st)); StagePositionText = StagePositionText + "Stage position "+toString(st)+ ": X [mm]\t"+ "---\n"; StagePositionText = StagePositionText + "Stage position "+toString(st)+ ": Y [mm]\t"+ "---\n"; } } } // open stage images in other file format supported by LOCI and manually enter the required parameters else { } // if stage images present continue with processing if (nImages > 0) { print("\nMeasurement XY stage repeatability"); print("------------------------------------------------------ \n"); print("XY dimension [um]:" ,"\t" ,d2s(StageVoxelXY,3)); print("Zoom Factor :" , "\t" , d2s(StageZoom,2)); if (ReadFormat == "czi" || ReadFormat == "lsm" || ReadFormat == "nd2" ) print("Pinhole diameter [um]:", "\t", d2s(StagePinhole,3)); else print("Pinhole diameter [airy]:", "\t", d2s(StagePinhole,3)); print("Time interval [s]:","\t", toString(StageTime)); print("Number of repeats:","\t", nSlices); print("\n"); StagePositions = nImages; XYMaxDimension = getWidth()*StageVoxelXY; XCoordArray = newArray(nSlices); YCoordArray = newArray(nSlices); XmeanArray = newArray(1); YmeanArray = newArray(1); XstdDevArray = newArray(1); YstdDevArray = newArray(1); IntensityArray = newArray(nSlices); TimeArray = newArray(nSlices); LaserArray = newArray(nImages); TimePoints = nSlices; print(StagePositionText+"\n"); for (i=1; i<=StagePositions; i++) { selectWindow("Position"+toString(i)); TempString = "TIME[s]\tXCOORD[um]\tYCOORD[um]\tMIN INT\tMAX INT\tAVERAGE INT\n"; for (t=1; t<= nSlices; t++) { selectWindow("Position"+toString(i)); setSlice(t); getStatistics(area, mean, min, max, std, histogram); SliceThreshold = round(max/2); TrackedBeadStats(SliceThreshold); IntensityArray[t-1] = ImageStats[2]; TimeArray[t-1] = (t-1)*StageTime/60; XCoordArray[t-1]= Centroid2D[0]*StageVoxelXY; YCoordArray[t-1] = XYMaxDimension - Centroid2D[1]*StageVoxelXY; TempString=TempString+d2s((t-1)*StageTime,3) +"\t"+d2s(XCoordArray[t-1],3)+"\t"+ d2s(YCoordArray[t-1],3)+"\t"+ d2s(ImageStats[0],0)+"\t"+ d2s(ImageStats[1],0)+ "\t"+ d2s(ImageStats[2],3)+"\n"; } // Generate plots of XY coordinates of bead at different timepoints; red dot marks mean XY coordinates; rectangle +/- StdDev for X and Y Array.getStatistics(XCoordArray, min, max, mean, stdDev); XmeanArray[0] = mean; XstdDevArray[0] = stdDev; Array.getStatistics(YCoordArray, min, max, mean, stdDev); YmeanArray[0] = mean; YstdDevArray[0] = stdDev; run("Profile Plot Options...", "width=400 height=400 minimum="+toString(XmeanArray[0]-6*XstdDevArray[0])+" maximum="+toString(XmeanArray[0]+6*XstdDevArray[0])+" draw"); Plot.create("Stageposition"+toString(i), "X [um]", "Y [um]"); Plot.setLimits(XmeanArray[0]-6*XstdDevArray[0], XmeanArray[0]+6*XstdDevArray[0],YmeanArray[0]-6*XstdDevArray[0], YmeanArray[0]+6*XstdDevArray[0]); Plot.setLineWidth(8); Plot.setColor("red"); Plot.add("dots", XmeanArray, YmeanArray); Plot.setLineWidth(1); Plot.drawLine(XmeanArray[0]-XstdDevArray[0], YmeanArray[0]-YstdDevArray[0], XmeanArray[0]+XstdDevArray[0], YmeanArray[0]-YstdDevArray[0]); Plot.drawLine(XmeanArray[0]+XstdDevArray[0], YmeanArray[0]-YstdDevArray[0],XmeanArray[0]+XstdDevArray[0] , YmeanArray[0]+YstdDevArray[0]); Plot.drawLine(XmeanArray[0]+XstdDevArray[0], YmeanArray[0]+YstdDevArray[0],XmeanArray[0]-XstdDevArray[0] , YmeanArray[0]+YstdDevArray[0]); Plot.drawLine(XmeanArray[0]-XstdDevArray[0], YmeanArray[0]+YstdDevArray[0],XmeanArray[0]-XstdDevArray[0] , YmeanArray[0]-YstdDevArray[0]); Plot.setLineWidth(1); Plot.setColor("black"); Plot.add("crosses", XCoordArray, YCoordArray); Plot.setColor("black"); Text = toString("Position "+toString(i)); Plot.addText(Text, 0.01,0.07); Plot.show; selectWindow("Stageposition"+toString(i)); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText + "_Stageposition"+toString(i)+"_XYplot.tif"); if (UpdateWWWSite == true) saveAs("jpeg", WWWDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText + "_Stageposition"+toString(i)+"_XYplot.jpg"); run("Close"); // Generate intensity plots with different colours Array.getStatistics(IntensityArray, min, max, mean, std); if (i==1){ dvMin = mean-0.3*mean; dvMax = mean+0.3*mean; } if (ReadFormat == "dv") run("Profile Plot Options...", "width=600 height=255 minimum="+toString(dvMin)+" maximum="+toString(dvMax)+" fixed interpolate draw"); else run("Profile Plot Options...", "width=600 height=255 minimum=0 maximum=255 fixed interpolate draw"); Plot.create("Stageposition"+toString(i), "Time [min]", "Intensity"); if (ReadFormat == "dv") Plot.setLimits(0, TimePoints*StageTime/60, dvMin, dvMax); else Plot.setLimits(0, TimePoints*StageTime/60, 0, 255); Plot.setColor(TextColour[i]); Plot.setLineWidth(2); Plot.add("curve", TimeArray, IntensityArray); Text = toString("Position "+toString(i)); Plot.addText(Text, 0.01,0.07+i*0.05); Plot.show; selectWindow("Position"+toString(i)); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText + "_Stageposition"+toString(i)+".tif"); File.saveString(TempString, ReadDir+"\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText +"_Stageposition"+toString(i)+"_data.txt"); Array.getStatistics(XCoordArray, min, max, mean, stdDev); print("Bead position "+toString(i)+ ": Repeatability X mean [um ]", "\t", d2s(mean,3)); print("Bead position "+toString(i)+ ": Repeatability X StdDev [um ]", "\t", d2s(stdDev,3)); Array.getStatistics(YCoordArray, min, max, mean, stdDev); print("Bead position "+toString(i)+ ": Repeatability Y mean [um ]", "\t", d2s(mean,3)); print("Bead position "+toString(i)+ ": Repeatability Y StdDev [um ]", "\t", d2s(stdDev,3)); print("\n"); } // Merge plots and save result images as TIFF and JPEG files j=1; do { imageCalculator("AND", "Stageposition1","Stageposition"+toString(j)); j=j+1; } while (j<= StagePositions); selectWindow("Stageposition1"); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText +"_Bead_intensity_result.tif"); if (UpdateWWWSite == true){ saveAs("jpeg", WWWDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText + "_Bead_intensity_result.jpg"); WWWBeadRepeatString = ""; for (j=1; j<=StagePositions; j++){ WWWBeadRepeatString = WWWBeadRepeatString+" \n"; } if (StagePositions == 2) WWWBeadRepeatString = WWWBeadRepeatString+" \n"; WWWBeadRepeatString = WWWBeadRepeatString + " \n"; } while (nImages > 0) close(); stage_analysis = 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // End XY stage repeatability measurements ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Start XY stage accuracy measurements ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Test that stage images are present first // Checking in Leica SP5 LIF file format if (ReadFormat == "lif") { seriesFound = findSeries("stageacc1"); if ( seriesFound > -1) { Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblVoxelX 0",wtmp); StageVoxelXY = parseFloat(wtmp)*1000000; Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblZoom 0",wtmp); StageZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|dblPinholeAiry 0",wtmp); StagePinhole = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|nDelayTime_s 0",wtmp); StageTime = parseFloat(wtmp); Ext.getSeriesMetadataValue("HardwareSetting|ScannerSettingRecord|nDelayTime_ms 0",wtmp); if (wtmp > 0) StageTime = StageTime+parseFloat(wtmp)/1000; setBatchMode(true); StagePositionText = ""; XStagePosition = newArray(3); YStagePosition = newArray(3); s = 1; while (s <= 3) { // Open 'stage' image sequence, one window for each stage position, done individually as separate recordings seriesFound = findSeries("stageacc"+toString(s)); if (seriesFound > -1){ Ext.getSeriesMetadataValue("HardwareSetting|FilterSettingRecord|DMI6000 Stage Pos x 0",wtmp); if (wtmp == 0) Ext.getPlanePositionX(wtmp,1); XStagePosition[s-1] = parseFloat(wtmp)*1000000; StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": X [mm]\t"+ d2s(wtmp*1000,6) + "\n"; Ext.getSeriesMetadataValue("HardwareSetting|FilterSettingRecord|DMI6000 Stage Pos y 0",wtmp); if (wtmp == 0) Ext.getPlanePositionY(wtmp,1); YStagePosition[s-1] = parseFloat(wtmp)*1000000; StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": Y [mm]\t"+ d2s(wtmp*1000,6)+ "\n"; run("Bio-Formats Importer", "open=" + path +" view=[Standard ImageJ] stack_order=Default series_"+toString(seriesFound)); rename("Position"+toString(s)); } s = s + 1; } } } // Checking whether images in Deltavision DV file format present if (ReadFormat == "dv"){ if (File.exists(ReadDir + "\\"+"stageacc1_R3D.dv") == 1) { Ext.setId(ReadDir + "\\"+"stageacc1_R3D.dv"); Ext.setSeries(0); wtmp = 0; Ext.getMetadataValue("Image Properties Pixel Size",wtmp); StageVoxelXY = substring (wtmp,0,indexOf(wtmp," ")); StageZoom = "1.0"; StagePinhole = "10.0"; Ext.getPlaneTimingDeltaT(StageTime, 1); XStagePosition = newArray(3); YStagePosition = newArray(3); LogFile = File.openAsString(ReadDir + "\\"+"stageacc1_R3D.dv.log"); CheckForPointlist = substring(LogFile, indexOf(LogFile,"#KEY DO_POINT_VISITING")+23,indexOf(LogFile,"#KEY DO_POINT_VISITING")+24); if (CheckForPointlist == "F") DVStagePositions = 1; else if (CheckForPointlist == "T") DVStagePositions = parseInt (substring(LogFile, indexOf(LogFile,"#KEY POINT_VISIT_LIST 1-")+24,indexOf(LogFile,"#KEY POINT_VISIT_LIST 1-")+25)); setBatchMode(true); StagePositionText = ""; for (s=1; s<= DVStagePositions; s++) { Ext.setId(ReadDir+"\\"+"stageacc"+toString(s)+"_R3D.dv"); Ext.setSeries(0); Ext.getMetadataValue("Image 1. Stage coordinates",wtmp); xtmp = parseFloat(substring(wtmp,indexOf(wtmp,"(")+1,indexOf(wtmp,","))); ytmp = parseFloat(substring(wtmp,indexOf(wtmp,",")+1,lastIndexOf(wtmp,","))); StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": X [mm]\t"+ d2s(xtmp/1000,6) + "\n"; XStagePosition[s-1] = xtmp; StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": Y [mm]\t"+ d2s(ytmp/1000,6)+ "\n"; YStagePosition[s-1] = ytmp; run("Bio-Formats Importer", "open="+ReadDir+"\\"+"stageacc"+toString(s)+"_R3D.dv"+" view=[Standard ImageJ] stack_order=Default"); rename("Position"+toString(s)); resetMinAndMax(); run("Flip Vertically", "stack"); } } } // Checking in Zeiss 510 LSM file format else if (ReadFormat == "lsm") { if (File.exists(ReadDir + "\\"+"stageacc.lsm") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"stageacc.lsm"); Ext.getSeriesCount(StagePositions); StagePositionText = ""; XStagePosition = newArray(3); YStagePosition = newArray(3); wtmp = 0; s = 1; while (s <= StagePositions) { Ext.setSeries(s-1); Ext.getPlanePositionX(wtmp,1); if (wtmp == 0) Ext.getSeriesMetadataValue("stageacc #"+toString(s)+" Recording #1 Sample 0X",wtmp); XStagePosition[s-1] = parseFloat(wtmp)*1000000; StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": X [mm]\t"+ d2s(wtmp*1000,6) + "\n"; Ext.getPlanePositionY(wtmp,1); if (wtmp == 0) Ext.getSeriesMetadataValue("stageacc #"+toString(s)+" Recording #1 Sample 0Y",wtmp); YStagePosition[s-1] = parseFloat(wtmp)*1000000; StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": Y [mm]\t"+ d2s(wtmp*1000,6)+ "\n"; run("Bio-Formats Importer", "open="+ReadDir+"\\"+"stageacc.lsm"+" autoscale color_mode=Default view=Hyperstack stack_order=XYCZT series_"+toString(s)); rename("Position"+toString(s)); s=s+1; } getPixelSize(unit, StageVoxelXY, pixelHeight); Ext.getPlaneTimingDeltaT(deltaT, 1); StageTime = parseFloat(deltaT); Ext.getSeriesMetadataValue("Recording #1 Zoom X",wtmp); StageZoom = parseFloat(wtmp); Ext.getSeriesMetadataValue("DetectionChannel #1 Pinhole Diameter",wtmp); StagePinhole = parseFloat(wtmp); } } // Checking in Zeiss LSM780 file format else if (ReadFormat == "czi") { if (File.exists(ReadDir + "\\"+"stageacc.czi") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"stageacc.czi") Ext.getSeriesCount(StagePositions); StagePositionText = ""; XStagePosition = newArray(StagePositions); YStagePosition = newArray(StagePositions); wtmp = 0; s = 1; while (s <= StagePositions) { Ext.setSeries(s-1); Ext.getPlanePositionX(wtmp,1); if (wtmp == 0) Ext.getMetadataValue("Metadata Experiment ExperimentBlocks AcquisitionBlock AcquisitionModeSetup OffsetX 0",wtmp); XStagePosition[s-1] = parseFloat(wtmp)*1000; StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": X [mm]\t"+ d2s(wtmp*1000,6) + "\n"; Ext.getPlanePositionY(wtmp,1); if (wtmp == 0) Ext.getMetadataValue("Metadata Experiment ExperimentBlocks AcquisitionBlock AcquisitionModeSetup OffsetY0",wtmp); YStagePosition[s-1] = parseFloat(wtmp)*1000; StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": Y [mm]\t"+ d2s(wtmp*1000,6)+ "\n"; run("Bio-Formats Importer", "open="+ReadDir+"\\"+"stageacc.czi"+" autoscale color_mode=Default view=Hyperstack stack_order=XYCZT series_"+toString(s)); rename("Position"+toString(s)); s=s+1; } getPixelSize(unit, StageVoxelXY, pixelHeight); StageTime = getNumber("Stage performance: Enter time interval between images [s]", 20.0); Ext.getMetadataValue("Information|Image|Channel|PinholeSize|0",wtmp); StagePinhole = parseFloat(wtmp); Ext.getMetadataValue("Experiment|AcquisitionBlock|AcquisitionModeSetup|ZoomX|0",wtmp); StageZoom = parseFloat(wtmp); } } // Checking stage images in Nikon ND2 file format else if (ReadFormat == "nd2"){ if (File.exists(ReadDir + "\\"+"stageacc.nd2") == 1) { setBatchMode(true); Ext.setId(ReadDir + "\\"+"stageacc.nd2"); Ext.getSizeZ(StagePositions); XStagePosition = newArray(StagePositions); YStagePosition = newArray(StagePositions); StagePositionText = ""; wtmp = 0; s = 1; while (s <= StagePositions) { Ext.getPlanePositionX(wtmp,s); XStagePosition[s-1] = parseFloat(wtmp)*1000; StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": X [mm]\t"+ d2s(wtmp/1000,6) + "\n"; Ext.getPlanePositionY(wtmp,s); YStagePosition[s-1] = parseFloat(wtmp)*1000; StagePositionText = StagePositionText + "Stage position "+toString(s)+ ": Y [mm]\t"+ d2s(wtmp/1000,6)+ "\n"; s=s+1; } run("Bio-Formats Importer", "open="+ReadDir + "\\"+"stageacc.nd2"+" autoscale color_mode=Default split_focal view=[Standard ImageJ] stack_order=Default"); for (s=1; s<=nImages; s++) { selectWindow("stageacc.nd2 - Z="+toString(s-1)); rename("Position"+toString(s)); minTemp=100000; maxTemp=0; for (t=1;t<=nSlices; t++) { setSlice(t); getStatistics(area, mean, min, max); if (min < minTemp) minTemp = min; if (max > maxTemp) maxTemp = max; } setMinAndMax(minTemp, maxTemp); run("8-bit"); } getPixelSize(unit, StageVoxelXY, pixelHeight); Ext.getMetadataValue("dAvgPeriodDiff",wtmp); StageTime = parseFloat(wtmp)/1000; Ext.getMetadataValue("PinholeSize",wtmp); StagePinhole = parseFloat(wtmp); Ext.getMetadataValue("ImagingZoom",wtmp); StageZoom = parseFloat(wtmp); } } // Checking for stage images TIF files and manually enter the required parameters else if (ReadFormat == "tif"){ if (File.exists(ReadDir + "\\"+"stageacc1.tif") == 1) { StageVoxelXY = getNumber("XY stage accuracy: Enter XY pixelsize [um]", 0.1); StageZoom = getNumber("XY stage accuracy: Enter Zoom Factor", 16.0); StageTime = getNumber("XY stage accuracy: Enter time interval between images [s]", 20.0); StagePinhole = getNumber("XY stage accuracy: Enter pinhole diameter [airy units]", 1); QueryStagePositions = 1; for (st=2; st <= 3; st++){ if (File.exists(ReadDir + "\\"+"stageacc"+toString(st)+".tif") == 1) QueryStagePositions = QueryStagePositions + 1; } setBatchMode(true); XStagePosition = newArray(QueryStagePositions); YStagePosition = newArray(QueryStagePositions); StagePositionText = ""; for (st=1; st <= QueryStagePositions; st++){ open(ReadDir + "\\"+"stageacc"+toString(st)+".tif"); rename("Position"+toString(st)); StagePositionText = StagePositionText + "Stage position "+toString(st)+ ": X [mm]\t"+ "---\n"; StagePositionText = StagePositionText + "Stage position "+toString(st)+ ": Y [mm]\t"+ "---\n"; XStagePosition[st-1] = 0; YStagePosition[st-1] = 0; } } } // open stage images in any other file format supported by LOCI and manually enter the required parameters else { } // if stage images present continue with processing if (nImages > 0) { print("\nMeasurement XY stage accuracy"); print("------------------------------------------------------ \n"); print("XY dimension [um]:" ,"\t" ,d2s(StageVoxelXY,3)); print("Zoom Factor :" , "\t" , d2s(StageZoom,2)); if (ReadFormat == "czi" || ReadFormat == "lsm" || ReadFormat == "nd") print("Pinhole diameter [um]:", "\t", d2s(StagePinhole,3)); else print("Pinhole diameter [airy]:", "\t", d2s(StagePinhole,3)); print("Time interval [s]:","\t", toString(StageTime)); print("Number of repeats:","\t", nSlices); print("\n"); StagePositions = nImages; XYMaxDimension = getWidth()*StageVoxelXY; XCoordArray = newArray(nSlices); YCoordArray = newArray(nSlices); XCoordArrayAll = newArray(nSlices*StagePositions); YCoordArrayAll = newArray(nSlices*StagePositions); IntensityArrayAll = newArray(nSlices*StagePositions); DistanceArrayAll = newArray(nSlices*StagePositions); XmeanArray = newArray(1); YmeanArray = newArray(1); XstdDevArray = newArray(1); YstdDevArray = newArray(1); IntensityArray = newArray(nSlices); TimeArray = newArray(nSlices); LaserArray = newArray(nImages); TimePoints = nSlices; print(StagePositionText+"\n"); for (i=1; i<=StagePositions; i++) { selectWindow("Position"+toString(i)); for (t=1; t<= TimePoints; t++) { selectWindow("Position"+toString(i)); setSlice(t); getStatistics(area, mean, min, max, std, histogram); SliceThreshold = round(max/2); TrackedBeadStats(SliceThreshold); XCoordArray[t-1] = Centroid2D[0]*StageVoxelXY; XCoordArrayAll[(t-1)+(i-1)*nSlices] = Centroid2D[0]*StageVoxelXY; IntensityArray[t-1] = ImageStats[2]; IntensityArrayAll[(t-1)+(i-1)*nSlices] = ImageStats[2]; YCoordArray[t-1] = XYMaxDimension - Centroid2D[1]*StageVoxelXY; YCoordArrayAll[(t-1)+(i-1)*nSlices] = XYMaxDimension - Centroid2D[1]*StageVoxelXY; TimeArray[t-1] = (t-1)*StageTime/60; } // Generate plots of XY coordinates of bead at different timepoints; red dot marks mean XY coordinates; rectangle +/- StdDev for X and Y Array.getStatistics(XCoordArray, min, max, mean, stdDev); XmeanArray[0] = mean; XstdDevArray[0] = stdDev; print("Bead position "+toString(i)+ ": Repeatability X mean [um ]", "\t", d2s(mean,3)); print("Bead position "+toString(i)+ ": Repeatability X StdDev [um ]", "\t", d2s(stdDev,3)); Array.getStatistics(YCoordArray, min, max, mean, stdDev); YmeanArray[0] = mean; YstdDevArray[0] = stdDev; print("Bead position "+toString(i)+ ": Repeatability Y mean [um ]", "\t", d2s(mean,3)); print("Bead position "+toString(i)+ ": Repeatability Y StdDev [um ]", "\t", d2s(stdDev,3)); print("\n"); run("Profile Plot Options...", "width=400 height=400 minimum="+toString(XmeanArray[0]-6*XstdDevArray[0])+" maximum="+toString(XmeanArray[0]+6*XstdDevArray[0])+" draw"); Plot.create("Stageposition"+toString(i), "X [um]", "Y [um]"); Plot.setLimits(XmeanArray[0]-6*XstdDevArray[0], XmeanArray[0]+6*XstdDevArray[0],YmeanArray[0]-6*XstdDevArray[0], YmeanArray[0]+6*XstdDevArray[0]); Plot.setLineWidth(8); Plot.setColor("red"); Plot.add("dots", XmeanArray, YmeanArray); Plot.setLineWidth(1); Plot.drawLine(XmeanArray[0]-XstdDevArray[0], YmeanArray[0]-YstdDevArray[0], XmeanArray[0]+XstdDevArray[0], YmeanArray[0]-YstdDevArray[0]); Plot.drawLine(XmeanArray[0]+XstdDevArray[0], YmeanArray[0]-YstdDevArray[0],XmeanArray[0]+XstdDevArray[0] , YmeanArray[0]+YstdDevArray[0]); Plot.drawLine(XmeanArray[0]+XstdDevArray[0], YmeanArray[0]+YstdDevArray[0],XmeanArray[0]-XstdDevArray[0] , YmeanArray[0]+YstdDevArray[0]); Plot.drawLine(XmeanArray[0]-XstdDevArray[0], YmeanArray[0]+YstdDevArray[0],XmeanArray[0]-XstdDevArray[0] , YmeanArray[0]-YstdDevArray[0]); Plot.setLineWidth(1); Plot.setColor("black"); Plot.add("crosses", XCoordArray, YCoordArray); Plot.setColor("black"); Text = toString("Position "+toString(i)); Plot.addText(Text, 0.01,0.07); Plot.show; selectWindow("Stageposition"+toString(i)); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText + "_StageAccuracy_Position"+toString(i)+"_XYplot.tif"); if (UpdateWWWSite == true) saveAs("jpeg", WWWDir + "\\"+SystemName +"_" + MagText + "x_" + NAText + "_" + DateText + "_StageAccuracy_Position"+toString(i)+"_XYplot.jpg"); run("Close"); // Generate intensity plots with different colours for each position Array.getStatistics(IntensityArray, min, max, mean, std); if (i==1){ dvMin = mean-0.3*mean; dvMax = mean+0.3*mean; } if (ReadFormat == "dv") run("Profile Plot Options...", "width=600 height=255 minimum="+toString(dvMin)+" maximum="+toString(dvMax)+" fixed interpolate draw"); else run("Profile Plot Options...", "width=600 height=255 minimum=0 maximum=255 fixed interpolate draw"); Plot.create("Stageposition"+toString(i), "Time [min]", "Intensity"); if (ReadFormat == "dv") Plot.setLimits(0, TimePoints*StageTime/60, dvMin, dvMax); else Plot.setLimits(0, TimePoints*StageTime/60, 0, 255); Plot.setColor(TextColour[i]); Plot.setLineWidth(2); Plot.add("curve", TimeArray, IntensityArray); Text = toString("Position "+toString(i)); Plot.addText(Text, 0.01,0.07+i*0.05); Plot.show; } // Merge plots and images and save result images j=1; do { imageCalculator("AND", "Stageposition1","Stageposition"+toString(j)); j=j+1; } while (j<= StagePositions); j=1; do { j=j+1; imageCalculator("Max create stack", "Position1", "Position"+toString(j)); rename("Position1temp"); selectWindow("Position1"); close(); selectWindow("Position1temp"); rename("Position1"); } while (j< StagePositions); selectWindow("Stageposition1"); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText +"_StageAccuracy_Bead_intensity.tif"); selectWindow("Position1"); saveAs("Tiff", ReadDir + "\\"+SystemName + "_" + MagText + "x_" + NAText + "_" + DateText + "_StageAccuracy_Bead_images.tif"); while (nImages > 0) close(); // Calculate distances between bead centroids and save as text file for (i=0; i 0) close(); BeadMovement = 0; BeadError = 0; if (StagePositions == 2){ StageMovement = CalculateDistance(XStagePosition[0],YStagePosition[0], XStagePosition[1],YStagePosition[1]); print("Distance between stage positions [um]:\t", d2s(StageMovement,3)); for (i=0; i \n"; if (StagePositions == 2) WWWBeadAccString = WWWBeadAccString+" \n"; } stageacc_analysis = 1; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // End XY stage accuracy measurements ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Summary of checks performed and saving of measurement text (log) file /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // close unused windows list = getList("window.titles"); if (list.length > 0) { for (i=0; i\n"; if (axial_analysis == 1) WWWAmendString = WWWAmendString + WWWAxialString; else WWWAmendString = WWWAmendString + "\n\n"; if (bead_analysis == 1) WWWAmendString = WWWAmendString + WWWBeadString; else WWWAmendString = WWWAmendString + "\n\n\n"; if (field_analysis == 1) WWWAmendString = WWWAmendString + WWWFieldString; else WWWAmendString = WWWAmendString + "\n\n\n\n"; if (psf_analysis == 1) WWWAmendString = WWWAmendString + WWWPsfString; else WWWAmendString = WWWAmendString + "\n\n\n\n"; if (grid_analysis == 1) WWWAmendString = WWWAmendString + WWWGridString; else WWWAmendString = WWWAmendString + "\n"; if (zgalvo_analysis == 1) WWWAmendString = WWWAmendString + WWWZgalvoString; else WWWAmendString = WWWAmendString + "\n"; if (lambda_analysis == 1) WWWAmendString = WWWAmendString + WWWLambdaString; else WWWAmendString = WWWAmendString + "\n"; if (laser_analysis == 1) WWWAmendString = WWWAmendString + WWWLaserString; else WWWAmendString = WWWAmendString + "\n\n\n\n\n\n"; if (stage_analysis == 1) WWWAmendString = WWWAmendString + WWWBeadRepeatString; else WWWAmendString = WWWAmendString + "\n\n\n\n"; if (stageacc_analysis == 1) WWWAmendString = WWWAmendString + WWWBeadAccString; else WWWAmendString = WWWAmendString + "\n\n\n\n"; WWWAmendString = WWWAmendString + "\n\n\n"; NATextfile = replace(NAText, ".", "_"); WWWUpdatedString = File.openAsString(WWWDir+SystemName+"_"+MagText+"x"+NATextfile+"NA.html"); File.saveString(WWWUpdatedString, WWWDir+"\\"+SystemName+"_"+MagText+"x"+NATextfile+"NA_Backup"+DateText+".html"); WWWUpdatedString = substring(WWWUpdatedString, 0, lastIndexOf(WWWUpdatedString, "")); WWWUpdatedString = WWWUpdatedString + WWWAmendString; File.saveString(WWWUpdatedString, WWWDir+"\\"+SystemName+"_"+MagText+"x"+NATextfile+"NA.html"); showMessage("WWW summary file amended ! ","Updated File: "+SystemName+"_"+MagText+"x"+NATextfile+"NA.html"+"\nBackup file:"+SystemName+"_"+MagText+"x"+NATextfile+"NA_Backup"+DateText+".html"); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // END MAIN MACRO /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FUNCTIONS PERFORMANCE ANALYSIS /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function LambdaPeakFWHM(IntensityArray,LambdaArray,lambda,pmt) { // Find maximum intensity TempMax = 0; for (i=0; i TempMax){ TempMax = IntensityArray[i]; TempMaxPos = i; } } TempFWHM = round(TempMax/2); // Move left and right from intensity peak to find index of FWHM TempFWHMleftPosInt=newArray(1); TempFWHMleftPos=newArray(1); TempFWHMrightPosInt=newArray(1); TempFWHMrightPos=newArray(1); TempFWHMrightPos[0] = 0; for (i=TempMaxPos; i < lengthOf(IntensityArray); i++) { if(IntensityArray[i] <= TempFWHM){ TempFWHMrightPos[0] = i; TempFWHMrightPosInt[0] = IntensityArray[i]; i = lengthOf(IntensityArray); } } TempFWHMleftPos[0] = 0; for (i=TempMaxPos; i > 0; i--) { if(IntensityArray[i] <= TempFWHM){ TempFWHMleftPos[0] = i; TempFWHMleftPosInt[0] = IntensityArray[i]; i = 0; } } print("PMT" + toString(pmt) +":"); print(toString(lambda) +"nm line peak position [nm]:","\t", toString(LambdaArray[TempMaxPos])); print(toString(lambda) +"nm line peak intensity:","\t", d2s(IntensityArray[TempMaxPos],1)); print(toString(lambda) +"nm line FWHM [nm]:", LambdaArray[TempFWHMrightPos[0]]-LambdaArray[TempFWHMleftPos[0]]); } function GetPeakFWHM(IntensityArray) { // Find maximum intensity TempMax = 0; for (i=0; i TempMax){ TempMax = IntensityArray[i]; TempMaxPos = i; } } TempFWHM = round(TempMax/2); // Move left and right from intensity peak to find index of FWHM TempFWHMleftPosInt=newArray(1); TempFWHMleftPos=newArray(1); TempFWHMrightPosInt=newArray(1); TempFWHMrightPos=newArray(1); TempFWHMrightPos[0] = 0; for (i=TempMaxPos; i < lengthOf(IntensityArray); i++) { if(IntensityArray[i] <= TempFWHM){ TempFWHMrightPos[0] = i; TempFWHMrightPosInt[0] = IntensityArray[i]; i = lengthOf(IntensityArray); } } TempFWHMleftPos[0] = 0; for (i=TempMaxPos; i > 0; i--) { if(IntensityArray[i] <= TempFWHM){ TempFWHMleftPos[0] = i; TempFWHMleftPosInt[0] = IntensityArray[i]; i = 0; } } FWHM = TempFWHMrightPos[0]-TempFWHMleftPos[0]; Result = newArray(TempMaxPos,FWHM); return Result; } function GetLineStats(IntensityArray) { // Find maximum intensity TempMax = 0; TempMin = 100000; TempMean = 0; for (i=0; i TempMax) TempMax = IntensityArray[i]; if (IntensityArray[i] < TempMin) TempMin = IntensityArray[i]; TempMean = TempMean + IntensityArray[i]; } TempMean = TempMean/i; Result = newArray(TempMin,TempMax,TempMean); return Result; } function GetSelectedLaser(){ do { tickedBox = 0; Dialog.create("Laser"); for (i=0; i MaxIntensity) { MaxIntensity = max; BrightestSlice = i; } } setSlice(BrightestSlice); } function OpenSeries () { dir = ReadDir; list = getFileList(dir); stack = 0; for (i=0; i 0 ) { totalX = totalX+x; totalY = totalY+y; integrInt = integrInt + CurrentPosition; if (CurrentPosition < minInt) minInt = CurrentPosition; if (CurrentPosition > maxInt) maxInt = CurrentPosition; totalPos = totalPos + 1; } } } Centroid2D[0]= totalX/totalPos; Centroid2D[1] = totalY/totalPos; ImageStats[0]= minInt; ImageStats[1]= maxInt; ImageStats[2]= integrInt/totalPos; } function TrackedBeadStats(threshold){ totalX=0; totalY=0; totalPos=0; minInt=100000; maxInt=0; integrInt=0; for (y=0; y threshold ) { totalX = totalX+x; totalY = totalY+y; totalPos = totalPos + 1; integrInt = integrInt + CurrentPosition; if (CurrentPosition < minInt) minInt = CurrentPosition; if (CurrentPosition > maxInt) maxInt = CurrentPosition; } } } Centroid2D[0]= totalX/totalPos; Centroid2D[1] = totalY/totalPos; ImageStats[0]= minInt; ImageStats[1]= maxInt; ImageStats[2]= integrInt/totalPos; } function findSeries(searchSeries) { i = 0; Ext.getSeriesCount(seriesCount); do { Ext.setSeries(i); Ext.getSeriesName(seriesName); i=i+1; } while (searchSeries != seriesName && i j-1 && DataArray[i] <=j) BinnedData[j-1] = BinnedData[j-1] + 1; } } run("Profile Plot Options...", "width=200 height=100 minimum=0 maximum=1 fixed interpolate draw"); Plot.create(name, "Percent change","Frequency"); Array.getStatistics(BinnedData, min, max, mean, stdDev); if (NoChange > max) max = NoChange; Plot.setLimits(0, 20, 0, max/DataPoints); Plot.setLineWidth(2); Plot.setColor("orange"); Plot.drawLine(5, 0, 5, max/DataPoints); Plot.setColor("red"); Plot.drawLine(10, 0, 10, max/DataPoints); Plot.setColor("green"); Plot.drawLine(0.25, 0, 0.25, NoChange/DataPoints); Plot.setColor("black"); for (i=0; i\n"; menu_string = menu_string + "body {\n\tfont-family:verdana,arial,sans-serif;\n\tfont-size:10pt;"; menu_string = menu_string + "\n\tmargin:10px;\n\tbackground-color:#bbbbbb;\n\t}\n"; menu_string = menu_string + "\n\n

CONFOCAL PERFORMANCE TEST

"+name+"

\n"; frame_string = "\n\nConfocal Performance checks\n\n\n"; frame_string = frame_string + "\n"; frame_string = frame_string + "\n"; objective_string = "\n\nObjective - analysis table\n\n\n

CONFOCAL PERFORMANCE TEST - "+name+" - "+ WWWMagText + "x/"+WWWNAText+"NA

\n"; objective_string_temp = objective_string_temp + "\n\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n"; objective_string_temp = objective_string_temp + "\n
Date Axial resolution (axial405)Axial resolution (axial488)Colocalisation (1um beads)Colocalisation (1um beads)Colocalisation (centroid distances)Field illumination 405nmField illumination 488nmField illumination 543/561nmField illumination 633nmPSF PSF (pseudocolour)PSF (Resolution) PSF (Montage) XY galvo (grid) Z galvo (Z stability)Lambda Scan Laser power (rescaled) Laser stability 405nm Laser stability 488nm Laser stability 543/561nm Laser stability 594nm Laser stability 633nm XY stage repeatability position 1 XY stage repeatability position 2 XY stage repeatability position 3 XY stage Bead intensity XY stage accuracy position 1 XY stage accuracy position 2 XY stage accuracy position 3
\n\n"; File.saveString(objective_string_temp, WWWDir+"\\"+name+"_"+WWWMagText+"x"+NATextfile+"NA.html"); } menu_string = menu_string + "\n\n"; File.saveString(menu_string, WWWDir+"\\"+name+"_menu.html"); frame_string = frame_string + "\n<p>Use browser with frame support to display pages properly !</p>\n\n\n\n"; File.saveString(frame_string, WWWDir+"\\"+name+"_performance_checks.html"); } function SelectSystem(){ // the configuration file has to be saved in the ImageJ macros folder as ConfocalCheck_Configuration.txt FolderConfigFile = getDirectory("macros"); if (File.exists(FolderConfigFile + "\\ConfocalCheck_Configuration.txt")) ConfigString = File.openAsString(FolderConfigFile + "\\ConfocalCheck_Configuration.txt"); else exit("ERROR ! ConfocalCheck_Configuration.txt not found in macros folder !"); tempString = ConfigString; // Searching for all occurrences of systemname: in the config file to count the number of systems NumberOfConfigurations = 0; while (indexOf(tempString, "systemname:")>= 0) { index1 = indexOf(tempString, "systemname:"); if (tempString != -1) NumberOfConfigurations++ ; tempString = substring(tempString, index1+11); } // Array containing the system names SystemArray = newArray(NumberOfConfigurations); tempString = ConfigString; for (i=0; i 32) tempString = tempString + fromCharCode(ch); } laserlines = split(tempString, "\,"); } else laserlines = ""; // retrieve lasercolour index1 = indexOf(ConfigString,"lasercolour:"); if (index1 != -1) { index2 = indexOf(ConfigString, "\n", index1); lasercolourString = substring(ConfigString,index1+12,index2); // remove any space characters tempString = ""; for (i=0; i 32) tempString = tempString + fromCharCode(ch); } lasercolour = split(tempString, "\,"); } else lasercolour = ""; // retrieve lasers for colocalisation bead analysis index1 = indexOf(ConfigString,"colocalisation:"); if (index1 != -1) { index2 = indexOf(ConfigString, "\n", index1); lasercolourString = substring(ConfigString,index1+15,index2); // remove any space characters tempString = ""; for (i=0; i 32) tempString = tempString + fromCharCode(ch); } BeadLaser = split(tempString, "\,"); } else BeadLaser = ""; // retrieve lasers for axial405 axial resolution analysis index1 = indexOf(ConfigString,"axial405:"); if (index1 != -1) { index2 = indexOf(ConfigString, "\n", index1); axial405String = substring(ConfigString,index1+9,index2); // remove any space characters tempString = ""; for (i=0; i 32) tempString = tempString + fromCharCode(ch); } Axial405Laser = split(tempString, "\,"); } else Axial405Laser = ""; // retrieve lasers for axial488 axial resolution analysis index1 = indexOf(ConfigString,"axial488:"); if (index1 != -1) { index2 = indexOf(ConfigString, "\n", index1); axial488String = substring(ConfigString,index1+9,index2); // remove any space characters tempString = ""; for (i=0; i 32) tempString = tempString + fromCharCode(ch); } Axial488Laser = split(tempString, "\,"); } else Axial488Laser = ""; // retrieve laser for psf analysis index1 = indexOf(ConfigString,"psflaser:"); if (index1 != -1) { index2 = indexOf(ConfigString, "\n", index1); psflaserString = substring(ConfigString,index1+9,index2); // remove any space characters tempString = ""; for (i=0; i 32) tempString = tempString + fromCharCode(ch); } PsfLaser = tempString; } else PsfLaser = ""; // retrieve lasers for lambda scan index1 = indexOf(ConfigString,"lambdascan:"); if (index1 != -1) { index2 = indexOf(ConfigString, "\n", index1); lambdascanString = substring(ConfigString,index1+11,index2); // remove any space characters tempString = ""; for (i=0; i 32) tempString = tempString + fromCharCode(ch); } LambdaScanLaser = split(tempString, "\,"); } else LambdaScanLaser = ""; // retrieve list of objectives index1 = indexOf(ConfigString,"objectives:"); index2 = indexOf(ConfigString, "\n", index1); objectiveString = substring(ConfigString,index1+11,index2); // remove any space characters before the first characters tempString = ""; comma = 0; for (i=0; i 32 && i<=4) tempString = tempString + fromCharCode(ch); else if (i>4) tempString = tempString + fromCharCode(ch); } objectives = split(tempString, "\,"); }