//N. Vischer //07.02.17 16:00 zoom-to-fit and black-border-bug fixed //11.10.16 16:09 wait for slow shutter //22.08.16 14:34 var // begin user-changeable values mVersion = "Version N.V. 07-Feb-2017", defaultField = 2048, //2048 or 1300f expArray = split("22 150 330 100 100 100 100 100 100 100"), gChnPattern = "bff", gFrames = 4, gChannelNames = "",//example: "phc gfp dapi" gName = "Untitled", // end user-changeable values demo = false, uvArr = newArray(10), expMsArray = newArray(10), currentStackID = 0, grabbedID = 0, counter = 0, busy = 0, exposure, ccdSize = 2048, fieldSizes = newArray("2048 * 2048", "1300 * 1300"), gFieldWidth, gFieldHeight, gNChannels, gSuffix = 1, step1needed = true, ; macro "Dialog [F5]"{ busy = 0; do{ if (step1needed){// --- Dialog step 1 --- if(counter > 0 && isOpen(currentStackID)){ selectImage(currentStackID); step1needed = false; showMessageWithCancel("Acquisition stack '" + getTitle + "' still pending\n Save and close it?"); saveCurrentStack(); //step1needed = true; exit; } Dialog.create("BX-Settings - step 1"); Dialog.addMessage(mVersion + "\n "); Dialog.addString("File base name", gName, 16); Dialog.setInsets(0, 0, 20); Dialog.addNumber("Suffix", gSuffix); Dialog.addString("Channel Pattern*:", gChnPattern); msg = "* For example, 'bff' would define \n 1 brightfield and 2 fluor. channels"; msg += "\n \n** Optional; for example 'phc gfp dapi'\n (will be stored as metadata)"; Dialog.addNumber("Frames per stack", gFrames); index = (defaultField != 2048); Dialog.addChoice("Field size:", fieldSizes, fieldSizes[index]); Dialog.addString("Channel names**:", gChannelNames, 16); Dialog.setInsets(50, 0, 0); Dialog.addMessage(msg); Dialog.show(); gName = Dialog.getString; gSuffix = Dialog.getNumber; gChnPattern = Dialog.getString; gChnPattern = toLowerCase(gChnPattern); gChnPattern = replace(gChnPattern, " ", ""); gNChannels = lengthOf(gChnPattern); gChannelNames = Dialog.getString; gFrames = Dialog.getNumber; acqRoi = split(Dialog.getChoice, "*"); gFieldWidth = parseInt(acqRoi[0]); gFieldHeight = parseInt(acqRoi[1]); print("\\Clear"); } // --- Dialog step 2 --- //gChannels = lengthOf(gChnPattern); settings = ""; sfx = parseInt(gSuffix); if (sfx < 10) sfx = "0" + sfx; settings += "\nName = " + gName + "_" + sfx; settings += "\nChannel Pattern = " + gChnPattern; settings += "\nFieldSize = " + gFieldWidth + " * " + gFieldHeight; settings += "\nChannels = " + lengthOf(gChnPattern); if (gChannelNames != "") settings += " (" + gChannelNames + ")"; settings += "\nFrames = " + gFrames; Dialog.create("BX-Exposures - step 2"); Dialog.setInsets(0, 0, 0); Dialog.addMessage(mVersion); Dialog.addMessage("Settings:"); Dialog.addMessage(settings); Dialog.addCheckbox("Change Settings Above", 0); Dialog.setInsets(50, 0, 0); exposures = split("2 3 5 7 10 22 33 47 68 100 150 220 330 470 680 1000 1500 2200 3300 4700"); Dialog.addMessage(" Exposures [ms]:"); for (chn = 1; chn <= gNChannels; chn++){ chr =substring(gChnPattern, chn-1, chn); lbl = " Channel-" + chn; if (chr == "f") lbl = "(f) " + lbl; Dialog.addChoice(lbl, exposures, expArray[chn-1]); } Dialog.setInsets(50, 0, 0); Dialog.addMessage("(f) = fluorescence with shutter"); Dialog.addMessage("Acquired: " + counter + " of " + gFrames *gNChannels); Dialog.show(); step1needed = Dialog.getCheckbox; for (chn = 0; chn 0){ beep; exit; } counter++; grabNextChannel(); } macro "Redo Channel [F2]"{ if(gFieldWidth == 0) exit("First issue 'Dialog [F5]'"); if(counter == 0) return; if(busy-- > 0){ beep; exit; } grabNextChannel(); } function grabNextChannel(){ busy = 2; channel = (counter + gNChannels- 1) % gNChannels + 1; grabChannel(channel); selectSnapWindow(); makeRectangle((ccdSize - gFieldWidth)/2, (ccdSize - gFieldHeight)/2, gFieldWidth, gFieldHeight); run("Copy"); if (!isOpen(currentStackID)){ //debug; busy = 0; //gChannels = lengthOf(gChnPattern); sfx = parseInt(gSuffix); if (sfx < 10) sfx = "0" + sfx; fullTitle = gName+"_" + sfx +".tif"; arg = " title=" +fullTitle; arg += " type=16-bit display=Grayscale"; arg += " width=" + gFieldWidth + " height=" + gFieldHeight; arg += " channels="+ gNChannels + " slices=1 frames=" + gFrames; run("New Hyperstack...", arg); currentStackID = getImageID; //if(!is("Caps Lock Set")) waitForUser("Click 'OK' to continue"); } selectImage(currentStackID); if (counter > nSlices || counter <= 0){ counter = 0; currentStackID = 0; gSuffix++; exit("Counter error, please save your stacks manually and continue"); } setSlice(counter); run("Select All");//07.02.17 15:15 run("Paste"); if(channel == 1)//07.02.17 15:15 zoomToFit(); chNames = split(gChannelNames); label = "" + exposure + "ms " ; if (chNames.length >= gNChannels) label = chNames[channel-1] + " " + label; setMetadata("Label", label); run("Enhance Contrast", "saturated=0"); run("Select None"); full = counter == nSlices; busy = 0; if (full){ counter = 0; saveCurrentStack(); } } function grabChannel(chn){ if(!isOpen("")){ busy = 0; if (counter > 0) counter--; exit("First click on 'Snap' to open the Snap window"); } exposure = expMsArray[chn - 1]; doRun("BX Control", "Exposure=" + exposure); doRun("BX Control", "autoshutter=0");//we do it manually if (uvArr[chn -1] == 1){ doRun("BX Control", "Shutter=1"); wait(120); } doRun("BX Control", "Grab=1"); grabbedID = getImageID; if (uvArr[chn -1] == 1) doRun("BX Control", "Shutter=0"); } function selectSnapWindow(){ if(isOpen(grabbedID)) selectImage(grabbedID); if(isOpen("")) selectImage(""); if(isOpen("Snap")) selectImage("Snap"); } macro "Open Shutter [F6]"{ doRun("BX Control", "Shutter=1"); } macro "Close Shutter [F7]"{ doRun("BX Control", "Shutter=0"); } macro "AutoRun" { demo = File.exists(getDirectory("macros") + "demo.txt"); if (demo){ waitForUser("You are in Demo mode, because file \n'demo.txt' \nis found in the 'macros' folder"); showStatus("demo mode"); wait(333); ccdSize = 512; fieldSizes = newArray("512 * 512", "222 * 188"); } run("Micro-Manager Studio"); selectWindow("ImageJ"); } macro "About BX_Control" { doRun("BX Control", "About"); } macro "AutoShutter on" { doRun("BX Control", "autoshutter=1"); doRun("BX Control", "updateGUI"); } macro "AutoShutter off" { doRun("BX Control", "autoshutter=0"); doRun("BX Control", "updateGUI"); } function doRun(aa, bb){ if(demo){ print(aa, bb); if(startsWith(bb, "Grab")) beep; } else run(aa, bb); } macro "Montage [F8]"{ //exit("not available yet"); //debug; close("MM-*"); Stack.getDimensions(x, y, channels, slices, frames); if(nSlices == 1) exit; run("Scale...", "x=0.25 y=0.25 z=1.0 create"); rename("MM--small"); srcID = getImageID; for(chn = 1; chn <= channels; chn++){ selectImage(srcID); Stack.setPosition(chn, 1, 1); run("Duplicate...", "duplicate channels=" + chn); rename("MM--Tmp"); run("Enhance Contrast", "saturated=0.35"); run("8-bit"); run("RGB Color"); run("Make Montage...", "columns=&frames rows=1 scale=1 border=6"); rename("MM--chn-" + chn); if(chn > 1){ run("Combine...", "stack1=MM--chn-1 stack2=MM--chn-" + chn + " combine"); rename("MM--chn-1"); } } rename("MM-montage"); close("MM--*"); run("Scale to Fit"); } function saveCurrentStack(){ if(isOpen(currentStackID)){ selectImage(currentStackID);//delete unused slices? if (counter > 0 && counter != nSlices){ showMessageWithCancel("Stack is not full, only store the valid part ?"); for (jj=nSlices; jj> counter && nSlices > gNChannels ; jj -= gNChannels ){ setSlice(nSlices); run("Delete Slice", "delete=frame"); } } if(isOpen(currentStackID)) selectImage(currentStackID); else return; currentStackID = 0; counter = 0; gSuffix++; run("Save"); title = getTitle; dashPos = lastIndexOf(title, "_"); if (dashPos > 1){ gName = substring(title, 0, dashPos); rest = substring(title, dashPos+1, lengthOf(title)); rest = replace(rest, ".tif", ""); indx = parseInt(rest); //auto-extract suffix if (indx >=0){ gSuffix = indx + 1; } } close; } } macro "Zoom to Fit [0]"{ zoomToFit(); } function zoomToFit(){ hh = screenHeight - 80; ww = hh/getHeight * getWidth; setLocation(10, 10, ww, hh); factor = hh/getHeight*95; run("Set... ", "zoom=&factor"); }