/* Originally just lexible unweighted blur v210504 1st version with Dialog Peter J. Lee NHMFL FSU v210723 This version expanded to include CLAHE v211025 Updated functions v211104: Updated stripKnownExtensionFromString function 211112 + 220616 + 230505 + v230607: Again, v230615 updated addImageToStack v230803: Replaced getDir for 1.54g10. */ macro "Create Process Series_Stack_ASC" { macroL = "Create_Process_Series_Stack_ASC_v230803_RGBOnly.ijm"; requires("1.53g"); /* Uses expandable arrays */ call("java.lang.System.gc"); saveSettings; getDimensions(imageW, imageH, imageChannels, imageSlices, imageFrames); maxDim = maxOf(imageW, imageH); if (imageChannels>1 || imageSlices>1 || imageFrames>1) exit("Sorry, currently only one original layer supported"); /* Check to see if there is a rectangular location already set for the summary */ if (selectionType()==0) { getSelectionBounds(selPosStartX, selPosStartY, originalSelEWidth, originalSelEHeight); selectionExists = true; } else selectionExists = false; run("Select None"); /* for now this is not used but makes sure we are working on the full area */ imageID = getImageID(); /* get id of image and title */ iDir = getDirectory("image"); oTitle = getInfo("image.title"); oTitleNE = File.getNameWithoutExtension(oTitle); oTitle = stripKnownExtensionFromString(getTitle()); getPixelSize(unit, pixelWidth, pixelHeight); /* perhaps expand to actual unit values later */ processes = newArray("Mean","Median","Min","Max","Gaussian Blur","CLAHE"); setBatchMode(true); /* Toggle batch mode off */ radiusUnit = "pixel"; /* for later expansion to unit versions */ sigmaStart = 0; /* adjust as necessary */ sigmaInc = 1; sigmaN = 50; if (selectionExists){ snapShotX = selPosStartX; snapShotY = selPosStartY; snapShotWidth = originalSelEWidth; snapShotHeight = originalSelEHeight; snapShotProfX = selPosStartX; snapShotProfY = selPosStartY + originalSelEHeight/2; snapShotProfWidth = originalSelEWidth; snapShotProfWidth = minOf(snapShotWidth,imageW); snapShotProfHeight = 1; // snapShotProfHeight = minOf(snapShotProfHeight,1); } else{ /* assume entire image */ snapShotX = 0; snapShotY = 0; snapShotWidth = imageW; snapShotHeight = imageH; snapShotProfX = 0; snapShotProfY = 0 + imageH/2; snapShotProfWidth = imageW; snapShotProfHeight = 1; // snapShotProfHeight = minOf(snapShotProfHeight,1); } Dialog.create("Processing options"); Dialog.addMessage("Macro: " + macroL); Dialog.addMessage("Image: " + oTitle); Dialog.addMessage("Pixel size: " + pixelWidth + " " + unit); Dialog.addRadioButtonGroup("Process: ",processes,6,1,"Mean"); Dialog.addCheckbox("Create table of profile values for location below?",false); Dialog.addNumber("Process radius \(CLAHE blocksize\) start: ",sigmaStart,0,5,"pixels"); Dialog.addNumber("Process radius\\size increment: ",sigmaInc,0,5,"pixels"); Dialog.addNumber("Process radius\\size increments: ",sigmaN,0,5,"pixels"); Dialog.addNumber("Process radius\\size increments power: ",1,0,5,"leave as 1 for no exponent"); Dialog.addNumber("CLAHE histogram, zero = Auto",0,0,5,"Auto from square of blocksize 64-256 limits"); Dialog.addNumber("CLAHE gradient limit \(max = 7 \)",7,0,5,"Must be >1"); Dialog.addRadioButtonGroup("CLAHE accurate or fast?",newArray("accurate","fast"),1,2,"accurate"); Dialog.addNumber("Post-process gamma \(1 means none, 0 means Auto\)",1,2,4,"maximum value = 5"); Dialog.addNumber("StartX: ",snapShotX,0,5,"pixels"); Dialog.addNumber("StartY: ",snapShotY,0,5,"pixels"); Dialog.addNumber("Width: ",snapShotWidth,0,5,"pixels"); Dialog.addNumber("Height: ",snapShotHeight,0,5,"pixels"); Dialog.addNumber("Profile start x: ",snapShotProfX,0,5,"pixels"); Dialog.addNumber("Profile start y: ",snapShotProfY,0,5,"pixels"); Dialog.addNumber("Profile width: ",snapShotProfWidth,0,5,"pixels"); Dialog.addNumber("Profile height: ",snapShotProfHeight,0,5,"pixels"); Dialog.show; process = Dialog.getRadioButton(); iProfile = Dialog.getCheckbox(); sigmaStart = Dialog.getNumber; sigmaInc = Dialog.getNumber; sigmaN = Dialog.getNumber; sigmaP = Dialog.getNumber; cHist = Dialog.getNumber; cGrad = Dialog.getNumber; cAcc = Dialog.getRadioButton; pGam = minOf(5,Dialog.getNumber()); snapShotX = Dialog.getNumber; snapShotY = Dialog.getNumber; snapShotWidth = Dialog.getNumber; snapShotHeight = Dialog.getNumber; snapShotProfX = Dialog.getNumber; snapShotProfY = Dialog.getNumber; snapShotProfWidth = Dialog.getNumber; snapShotProfHeight = Dialog.getNumber; titleStack = oTitle + "_" + sigmaN + "x" + process + "_Stack"; run("Select None"); if (selectionExists) makeRectangle(snapShotX, snapShotY, snapShotWidth, snapShotHeight); run("Duplicate...", "title="+titleStack); getPixelSize(unit,pixelWidth,pixelHeight); distanceTitle = "distance \("+unit+"\)"; if (iProfile){ Table.create(oTitle + "_" + process + ":_" + sigmaN + "_" + radiusUnit + "_Results"); for (i=0; imaxDim) i = sigmaN; } if (iProfile) { /* Save as spreadsheet compatible text file */ pPath = iDir+oTitleNE+"_"+sigma+"-"+sigmaInc*sigmaN+"_sigma_profile.csv"; Table.save(pPath); makeRectangle(snapShotProfX, snapShotProfY, snapShotProfWidth, snapShotProfHeight); } iPath = iDir+oTitleNE+"_"+sigma+"-"+sigmaInc*sigmaN+"_sigma_profile.tif"; selectWindow(titleStack); run("Select None"); saveAs("tiff", iPath); setBatchMode(false); } /* ( 8(|) ( 8(|) ASC Functions @@@@@:-) @@@@@:-) */ function addImageToStack(stackName,baseImage) { /* v230614: Added "Select None" */ run("Copy"); selectWindow(stackName); run("Add Slice"); run("Paste"); run("Select None"); selectWindow(baseImage); } function closeImageByTitle(windowTitle) { /* Cannot be used with tables */ /* v181002 reselects original image at end if open v200925 uses "while" instead of if so it can also remove duplicates */ oIID = getImageID(); while (isOpen(windowTitle)) { selectWindow(windowTitle); close(); } if (isOpen(oIID)) selectImage(oIID); } function gammaTweakF() { /* v211216 first version based on formula */ getRawStatistics(pixels, meanI, minI, maxI); originalBitDepth = bitDepth; if (originalBitDepth==16) fMaxI = pow(2,16); else if (originalBitDepth==32) fMaxI = maxI; else fMaxI = 255; print(pixels, meanI, minI, maxI,fMaxI); gParameters = "value=" + log(0.5)/log(meanI/fMaxI); print (gParameters); if (nSlices>1) gParameters += " slice"; run("Gamma...", gParameters); } function stripKnownExtensionFromString(string) { /* Note: Do not use on path as it may change the directory names v210924: Tries to make sure string stays as string. v211014: Adds some additional cleanup. v211025: fixes multiple 'known's issue. v211101: Added ".Ext_" removal. v211104: Restricts cleanup to end of string to reduce risk of corrupting path. v211112: Tries to fix trapped extension before channel listing. Adds xlsx extension. v220615: Tries to fix the fix for the trapped extensions ... v230504: Protects directory path if included in string. Only removes doubled spaces and lines. v230505: Unwanted dupes replaced by unusefulCombos. v230607: Quick fix for infinite loop on one of while statements. v230614: Added AVI. v230905: Better fix for infinite loop. v230914: Added BMP and "_transp" and rearranged */ fS = File.separator; string = "" + string; protectedPathEnd = lastIndexOf(string,fS)+1; if (protectedPathEnd>0){ protectedPath = substring(string,0,protectedPathEnd); string = substring(string,protectedPathEnd); } unusefulCombos = newArray("-", "_"," "); for (i=0; i=0) string = replace(string,combo,unusefulCombos[i]); } } if (lastIndexOf(string, ".")>0 || lastIndexOf(string, "_lzw")>0) { knownExts = newArray(".avi", ".csv", ".bmp", ".dsx", ".gif", ".jpg", ".jpeg", ".jp2", ".png", ".tif", ".txt", ".xlsx"); knownExts = Array.concat(knownExts,knownExts,"_transp","_lzw"); kEL = knownExts.length; for (i=0; i0){ preChan = substring(string,0,iChanLabels); postChan = substring(string,iChanLabels); while (indexOf(preChan,knownExts[i])>0){ preChan = replace(preChan,knownExts[i],""); string = preChan + postChan; } } } while (endsWith(string,knownExts[i])) string = "" + substring(string, 0, lastIndexOf(string, knownExts[i])); } } unwantedSuffixes = newArray(" ", "_","-"); for (i=0; i0){ if(!endsWith(protectedPath,fS)) protectedPath += fS; string = protectedPath + string; } return string; }