This shows you the differences between two versions of the page.
— |
macro:platemontage [2019/04/12 13:13] (current) |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== PlateMontage ====== | ||
+ | ** Creates a labeled plate montage image from BD Pathway 855 / AttoVision 1.6 data sets ** | ||
+ | |||
+ | <code java> | ||
+ | /* PlateMontage macro */ var version = '1.4a, 2009-10-13'; | ||
+ | // | ||
+ | // Creates a labeled plate montage image from BD Pathway 855 / AttoVision 1.6 data sets | ||
+ | // | ||
+ | // Features: | ||
+ | // Borders do not hide part of the images as in AttoVision | ||
+ | // Simultaneous processing of up to three channels | ||
+ | // Automatically saves the montage | ||
+ | // Style is customizable | ||
+ | // Well images can be inverted | ||
+ | // Missing images are not a problem | ||
+ | // All settings are remembered | ||
+ | // | ||
+ | // Shortcuts: | ||
+ | // Shift-P: Run this macro | ||
+ | // Shift-C: Close all windows | ||
+ | // Shift-M: Reload this macro | ||
+ | // | ||
+ | // System requirements: | ||
+ | // The screen height must be at least 1024 pixels | ||
+ | // | ||
+ | // BD Pathway 855 / AttoVision data set directory structure: | ||
+ | // + 2009-09-20 exp 328 | ||
+ | // + 2009-09-21_000 | ||
+ | // + Well A001 | ||
+ | // Alexa 488 - n000000.tif | ||
+ | // Alexa 594 - n000000.tif | ||
+ | // Hoechst - n000000.tif | ||
+ | // | ||
+ | // Contact: njensen@mail.unc.edu | ||
+ | // This code has been released into the Public Domain (PD) | ||
+ | |||
+ | |||
+ | // global constants | ||
+ | var settingsFile = 'PlateMontageSettings.txt'; | ||
+ | var borderWidth = 3; | ||
+ | var labelHeight = 80; | ||
+ | var labelWidth = 60; | ||
+ | var labelFont = 'SansSerif'; | ||
+ | var labelSize = 60; | ||
+ | var labelStyle = 'antialiased'; | ||
+ | var labelColor = 0; | ||
+ | var scaledWidth = 200; | ||
+ | var montageColor = 255; | ||
+ | var beepDone = true; | ||
+ | var tab = '\t'; | ||
+ | var macroDir = getDirectory('macros'); | ||
+ | var settingsFileFull = macroDir + settingsFile; | ||
+ | |||
+ | // global variables | ||
+ | var inputPath; | ||
+ | var outputPath; | ||
+ | var folderFormat; | ||
+ | var imageUse1; | ||
+ | var image1; | ||
+ | var imageUse2; | ||
+ | var image2; | ||
+ | var imageUse3; | ||
+ | var image3; | ||
+ | var rowFromChar; | ||
+ | var colFrom; | ||
+ | var rowToChar; | ||
+ | var colTo; | ||
+ | var outputPath; | ||
+ | var invertImages; | ||
+ | var invertMontage; | ||
+ | var invertBorders; | ||
+ | var popupDone; | ||
+ | var i; | ||
+ | var j; | ||
+ | var parentDir; | ||
+ | var parentParentDir; | ||
+ | var rowFrom; | ||
+ | var rowTo; | ||
+ | var reportMontage; | ||
+ | |||
+ | |||
+ | // | ||
+ | // PlateMontage: main program, gets and saves parameters | ||
+ | // | ||
+ | |||
+ | function PlateMontage() { | ||
+ | |||
+ | // default settings | ||
+ | inputPath = 'C:\\AttoVision\\Data\\'; | ||
+ | outputPath = '..\\..\\'; | ||
+ | folderFormat = '384'; | ||
+ | imageUse1 = true; | ||
+ | image1 = 'Alexa 594 - n000000.tif'; | ||
+ | imageUse2 = true; | ||
+ | image2 = 'Hoechst - n000000.tif'; | ||
+ | imageUse3 = false; | ||
+ | image3 = ''; | ||
+ | rowFromChar = 'A'; | ||
+ | colFrom = 1; | ||
+ | rowToChar = 'P'; | ||
+ | colTo = 24; | ||
+ | invertImages = false; | ||
+ | invertMontage = false; | ||
+ | invertBorders = false; | ||
+ | popupDone = true; | ||
+ | |||
+ | rowFrom = charCodeAt(toUpperCase(rowFromChar), 0) - 64; | ||
+ | rowTo = charCodeAt(toUpperCase(rowToChar), 0) - 64; | ||
+ | |||
+ | // read settings | ||
+ | if (File.exists(settingsFileFull) == 1) { | ||
+ | var settings = File.openAsString(settingsFileFull); | ||
+ | var settingLines = split(settings, '\r\n'); | ||
+ | for (i = 0; i < lengthOf(settingLines); i ++) { | ||
+ | setting = split(settingLines[i], tab); | ||
+ | if (lengthOf(setting) == 1) { | ||
+ | var name = setting[0]; | ||
+ | setting = newArray(2); | ||
+ | setting[0] = name; | ||
+ | setting[1] = ''; | ||
+ | } | ||
+ | if (setting[0] == 'inputPath') { | ||
+ | inputPath = setting[1]; | ||
+ | } | ||
+ | else if (setting[0] == 'outputPath') { | ||
+ | outputPath = setting[1]; | ||
+ | } | ||
+ | else if (setting[0] == 'folderFormat') { | ||
+ | folderFormat = setting[1]; | ||
+ | } | ||
+ | else if (setting[0] == 'imageUse1') { | ||
+ | imageUse1 = parseInt(setting[1]); | ||
+ | } | ||
+ | else if (setting[0] == 'image1') { | ||
+ | image1 = setting[1]; | ||
+ | } | ||
+ | else if (setting[0] == 'imageUse2') { | ||
+ | imageUse2 = parseInt(setting[1]); | ||
+ | } | ||
+ | else if (setting[0] == 'image2') { | ||
+ | image2 = setting[1]; | ||
+ | } | ||
+ | else if (setting[0] == 'imageUse3') { | ||
+ | imageUse3 = parseInt(setting[1]); | ||
+ | } | ||
+ | else if (setting[0] == 'image3') { | ||
+ | image3 = setting[1]; | ||
+ | } | ||
+ | else if (setting[0] == 'rowFromChar') { | ||
+ | rowFromChar = setting[1]; | ||
+ | } | ||
+ | else if (setting[0] == 'colFrom') { | ||
+ | colFrom = parseInt(setting[1]); | ||
+ | } | ||
+ | else if (setting[0] == 'rowToChar') { | ||
+ | rowToChar = setting[1]; | ||
+ | } | ||
+ | else if (setting[0] == 'colTo') { | ||
+ | colTo = parseInt(setting[1]); | ||
+ | } | ||
+ | else if (setting[0] == 'scaledWidth') { | ||
+ | scaledWidth = parseInt(setting[1]); | ||
+ | } | ||
+ | else if (setting[0] == 'invertImages') { | ||
+ | invertImages = parseInt(setting[1]); | ||
+ | } | ||
+ | else if (setting[0] == 'invertMontage') { | ||
+ | invertMontage = parseInt(setting[1]); | ||
+ | } | ||
+ | else if (setting[0] == 'invertBorders') { | ||
+ | invertBorders = parseInt(setting[1]); | ||
+ | } | ||
+ | else if (setting[0] == 'popupDone') { | ||
+ | popupDone = parseInt(setting[1]); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | rowFromChar = toUpperCase(rowFromChar); | ||
+ | rowToChar = toUpperCase(rowToChar); | ||
+ | rowFrom = charCodeAt(rowFromChar, 0) - 64; | ||
+ | rowTo = charCodeAt(rowToChar, 0) - 64; | ||
+ | |||
+ | // display dialog | ||
+ | requires('1.41j'); | ||
+ | Dialog.create('Plate Montage Settings'); | ||
+ | Dialog.addMessage('== PlateMontage Macro (Version ' + version + ') ==\n \nCreates a labeled plate montage from BD Pathway plate images\n \nShift-P: Run this macro\nShift-C: Close all windows\nShift-M: Reload this macro'); | ||
+ | Dialog.addMessage('Parent directory of images (DATE-NUMBER; leave empty for popup):'); | ||
+ | Dialog.addString('', inputPath, 90); | ||
+ | Dialog.addMessage('Output directory (relative paths: ".\\" (same directory), "..\\" (one up); leave empty for popup):'); | ||
+ | Dialog.addString('', outputPath, 90); | ||
+ | Dialog.addMessage('Image folder format (24: "A1"; 96: "A01", 384: "A001"):'); | ||
+ | Dialog.addChoice('', newArray('24', '96', '384'), folderFormat) | ||
+ | Dialog.addCheckbox('Process filename 1 (leave empty for popup):', imageUse1); | ||
+ | Dialog.addString('', image1, 30); | ||
+ | Dialog.addCheckbox('Process filename 2 (leave empty for popup):', imageUse2); | ||
+ | Dialog.addString('', image2, 30); | ||
+ | Dialog.addCheckbox('Process filename 3 (leave empty for popup):', imageUse3); | ||
+ | Dialog.addString('', image3, 30); | ||
+ | Dialog.addMessage('Coordinates of block of wells (non-existing wells will be left empty):'); | ||
+ | Dialog.addString('From row:', rowFromChar, 1); | ||
+ | Dialog.addNumber('From column:', colFrom); | ||
+ | Dialog.addString('To row:', rowToChar, 1); | ||
+ | Dialog.addNumber('To column:', colTo); | ||
+ | Dialog.addMessage('Scaled image width in pixels:'); | ||
+ | Dialog.addNumber('', scaledWidth); | ||
+ | Dialog.addCheckbox('Invert images', invertImages); | ||
+ | Dialog.addCheckbox('Black canvas with white label text', invertMontage); | ||
+ | Dialog.addCheckbox('Black borders and plate background', invertBorders); | ||
+ | Dialog.addMessage(''); | ||
+ | Dialog.addCheckbox('Display message when done', popupDone); | ||
+ | Dialog.addMessage(''); | ||
+ | Dialog.show(); | ||
+ | |||
+ | // get settings from dialog | ||
+ | inputPath = Dialog.getString(); | ||
+ | outputPath = Dialog.getString(); | ||
+ | folderFormat = Dialog.getChoice(); | ||
+ | imageUse1 = Dialog.getCheckbox(); | ||
+ | image1 = Dialog.getString(); | ||
+ | imageUse2 = Dialog.getCheckbox(); | ||
+ | image2 = Dialog.getString(); | ||
+ | imageUse3 = Dialog.getCheckbox(); | ||
+ | image3 = Dialog.getString(); | ||
+ | rowFromChar = Dialog.getString(); | ||
+ | colFrom = Dialog.getNumber(); | ||
+ | rowToChar = Dialog.getString(); | ||
+ | colTo = Dialog.getNumber(); | ||
+ | scaledWidth = Dialog.getNumber(); | ||
+ | invertImages = Dialog.getCheckbox(); | ||
+ | invertMontage = Dialog.getCheckbox(); | ||
+ | invertBorders = Dialog.getCheckbox(); | ||
+ | popupDone = Dialog.getCheckbox(); | ||
+ | |||
+ | rowFromChar = toUpperCase(rowFromChar); | ||
+ | rowToChar = toUpperCase(rowToChar); | ||
+ | rowFrom = charCodeAt(rowFromChar, 0) - 64; | ||
+ | rowTo = charCodeAt(rowToChar, 0) - 64; | ||
+ | |||
+ | var processingImages = ''; | ||
+ | |||
+ | // ask for image 1 | ||
+ | if (imageUse2 == true) { | ||
+ | if (image2 == '') { | ||
+ | Popup('Please select an image 1', 'Image 1'); | ||
+ | open(); | ||
+ | image1 = File.getName(File.name); | ||
+ | |||
+ | // get input path from image path | ||
+ | if (inputPath == '') { | ||
+ | inputPath = replace(File.directory, '\\.*?\\.*?$', '\\'); | ||
+ | } | ||
+ | close(); | ||
+ | } | ||
+ | processingImages = processingImages + image1 + '\n'; | ||
+ | } | ||
+ | |||
+ | // ask for image 2 | ||
+ | if (imageUse2 == true) { | ||
+ | if (image2 == '') { | ||
+ | Popup('Please select an image 2', 'Image 2'); | ||
+ | open(); | ||
+ | image2 = File.getName(File.name); | ||
+ | |||
+ | // get input path from image path | ||
+ | if (inputPath == '') { | ||
+ | inputPath = replace(File.directory, '\\.*?\\.*?$', '\\'); | ||
+ | } | ||
+ | close(); | ||
+ | } | ||
+ | processingImages = processingImages + image2 + '\n'; | ||
+ | } | ||
+ | |||
+ | // ask for image 3 | ||
+ | if (imageUse3 == true) { | ||
+ | if (image3 == '') { | ||
+ | Popup('Please select an image 3', 'Image 3'); | ||
+ | open(); | ||
+ | image3 = File.getName(File.name); | ||
+ | |||
+ | // get input path from image path | ||
+ | if (inputPath == '') { | ||
+ | inputPath = replace(File.directory, '\\.*?\\.*?$', '\\'); | ||
+ | } | ||
+ | close(); | ||
+ | } | ||
+ | processingImages = processingImages + image3 + '\n'; | ||
+ | } | ||
+ | |||
+ | // select input path | ||
+ | if (inputPath == '') { | ||
+ | inputPath = getDirectory('Parent directory (DATE-NUMBER)'); | ||
+ | } | ||
+ | |||
+ | // add trailing \ | ||
+ | inputPath = replace(inputPath, '([^\\\\])$', '$1\\\\'); | ||
+ | |||
+ | // select output path | ||
+ | if (outputPath == '') { | ||
+ | outputPath = getDirectory('Output directory'); | ||
+ | } | ||
+ | |||
+ | // add trailing \ | ||
+ | outputPath = replace(outputPath, '([^\\\\])$', '$1\\\\'); | ||
+ | |||
+ | // save settings to file | ||
+ | var file = File.open(settingsFileFull) ; | ||
+ | print(file, 'inputPath' + tab + inputPath); | ||
+ | print(file, 'outputPath' + tab + outputPath); | ||
+ | print(file, 'folderFormat' + tab + folderFormat); | ||
+ | print(file, 'imageUse1' + tab + imageUse1); | ||
+ | print(file, 'image1' + tab + image1); | ||
+ | print(file, 'imageUse2' + tab + imageUse2); | ||
+ | print(file, 'image2' + tab + image2); | ||
+ | print(file, 'imageUse3' + tab + imageUse3); | ||
+ | print(file, 'image3' + tab + image3); | ||
+ | print(file, 'rowFromChar' + tab + rowFromChar); | ||
+ | print(file, 'colFrom' + tab + colFrom); | ||
+ | print(file, 'rowToChar' + tab + rowToChar); | ||
+ | print(file, 'colTo' + tab + colTo); | ||
+ | print(file, 'scaledWidth' + tab + scaledWidth); | ||
+ | print(file, 'invertImages' + tab + invertImages); | ||
+ | print(file, 'invertMontage' + tab + invertMontage); | ||
+ | print(file, 'invertBorders' + tab + invertBorders); | ||
+ | print(file, 'popupDone' + tab + popupDone); | ||
+ | File.close(file); | ||
+ | |||
+ | // convert relative o absolute output path | ||
+ | if (matches(outputPath, '^(\\.|\\.\\.)\\\\.*?$') == true) { | ||
+ | outputPath = inputPath + outputPath; | ||
+ | var outputPathOld; | ||
+ | do { | ||
+ | outputPathOld = outputPath; | ||
+ | outputPath = replace(outputPath, '\\\\\\.\\\\', '\\\\'); | ||
+ | outputPath = replace(outputPath, '\\\\[^\\\\]+\\\\\\.\\.\\\\', '\\\\'); | ||
+ | } while (outputPath != outputPathOld); | ||
+ | } | ||
+ | |||
+ | // check values | ||
+ | if (rowFrom < 1) { | ||
+ | exit('Start row ' + rowFromChar + ' is not between A and P'); | ||
+ | } | ||
+ | if (rowTo > 16) { | ||
+ | exit('End row ' + rowToChar + ' is not between A and P'); | ||
+ | } | ||
+ | if (rowFrom > rowTo) { | ||
+ | exit('End row ' + rowToChar + ' is smaller than start row ' + rowFromChar); | ||
+ | } | ||
+ | |||
+ | if (colFrom < 1) { | ||
+ | exit('Start column ' + colFrom + ' is not between 1 and 24'); | ||
+ | } | ||
+ | if (colTo > 24) { | ||
+ | exit('End col ' + colTo + ' is not between 1 and 24'); | ||
+ | } | ||
+ | if (colFrom > colTo) { | ||
+ | exit('End column ' + colTo + ' is smaller than start column ' + colFrom); | ||
+ | } | ||
+ | |||
+ | // check paths | ||
+ | if (File.isDirectory(inputPath) == false) { | ||
+ | exit('Parent directory "' + inputPath + '" does not exist'); | ||
+ | } | ||
+ | if (File.isDirectory(outputPath) == false) { | ||
+ | exit('Output directory "' + outputPath + '" does not exist'); | ||
+ | } | ||
+ | |||
+ | // process images | ||
+ | CloseImages(); | ||
+ | |||
+ | // get name of parent directories | ||
+ | parentDir = replace(inputPath, '^.*?\\\\([^\\\\]*?)\\\\$', '$1'); | ||
+ | parentParentDir = replace(inputPath, '^.*?\\\\([^\\\\]*?)\\\\[^\\\\]*?\\\\$', '$1'); | ||
+ | reportMontage = ''; | ||
+ | |||
+ | // print to log | ||
+ | print('Processing...\nDirectory: ' + parentParentDir + '\\' + parentDir + '\nPath: ' + inputPath + '\nImages:\n' + processingImages); | ||
+ | ProcessMontage(image1, imageUse1); | ||
+ | ProcessMontage(image2, imageUse2); | ||
+ | ProcessMontage(image3, imageUse3); | ||
+ | |||
+ | // print to log | ||
+ | print('Output path: ' + outputPath + '\nMontage files: ' + reportMontage + '\nDone!\n--------\n'); | ||
+ | |||
+ | // beep | ||
+ | if (beepDone == true) { | ||
+ | beep(); | ||
+ | } | ||
+ | |||
+ | // popup | ||
+ | if (popupDone == true) { | ||
+ | Popup('Done!\n \nSaved to: \n' + outputPath + '\n \nMontage files:' + reportMontage, 'Done'); | ||
+ | } | ||
+ | |||
+ | return; | ||
+ | } | ||
+ | |||
+ | |||
+ | // | ||
+ | // ProcessMontage: create and save a montage | ||
+ | // | ||
+ | |||
+ | function ProcessMontage(image, imageUse) { | ||
+ | |||
+ | if (imageUse == true) { | ||
+ | |||
+ | // create montage file name | ||
+ | var montageImage = parentParentDir + ', ' + parentDir + ', ' + replace(image, '\\.\\w+$', '') + '.png'; | ||
+ | CreateMontage(image, montageImage); | ||
+ | if (isOpen(montageImage)) { | ||
+ | reportMontage = reportMontage + '\n' + montageImage; | ||
+ | selectWindow(montageImage); | ||
+ | saveAs('PNG', outputPath + montageImage); | ||
+ | } | ||
+ | if (isOpen('Log')) { | ||
+ | selectWindow('Log'); | ||
+ | } | ||
+ | } | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | |||
+ | // | ||
+ | // CreateMontage: create a montage | ||
+ | // | ||
+ | |||
+ | function CreateMontage(image, montageImage) { | ||
+ | |||
+ | if (isOpen('Log')) { | ||
+ | selectWindow('Log'); | ||
+ | } | ||
+ | setBatchMode(true); | ||
+ | |||
+ | // image folder name format | ||
+ | var folderDigits = '000'; | ||
+ | if (folderFormat == '24') { | ||
+ | folderDigits = '0'; | ||
+ | } | ||
+ | if (folderFormat == '96') { | ||
+ | folderDigits = '00'; | ||
+ | } | ||
+ | else if (folderFormat == '384') { | ||
+ | folderDigits = '000'; | ||
+ | } | ||
+ | |||
+ | var scalingFactor; | ||
+ | var dimensionsCreated = false; | ||
+ | var montageCreated = false; | ||
+ | |||
+ | var numRows = rowTo - rowFrom + 1; | ||
+ | var numCols = colTo - colFrom + 1; | ||
+ | |||
+ | // cycle through images | ||
+ | for (row = 0; row < numRows; row ++) { | ||
+ | var rowNumber = row + rowFrom; | ||
+ | var rowChar = fromCharCode(rowNumber + 64); | ||
+ | |||
+ | for (col = 0; col < numCols; col ++) { | ||
+ | var colNumber = col + colFrom; | ||
+ | var colStr = substring(folderDigits, lengthOf(toString(colNumber))) + colNumber; | ||
+ | |||
+ | // open image | ||
+ | var imageFileFull = inputPath + 'Well ' + rowChar + colStr + '\\' + image; | ||
+ | if (File.exists(imageFileFull) == true) { | ||
+ | open(imageFileFull); | ||
+ | rename('Image'); | ||
+ | |||
+ | // get dimensions from first image | ||
+ | if (dimensionsCreated == false) { | ||
+ | dimensionsCreated = true; | ||
+ | var width = getWidth(); | ||
+ | var height = getHeight(); | ||
+ | scalingFactor = scaledWidth / width; | ||
+ | scaledHeight = floor(height * scalingFactor); | ||
+ | } | ||
+ | |||
+ | // create montage with dimensions | ||
+ | if (montageCreated == false) { | ||
+ | montageCreated = true; | ||
+ | montageWidth = labelWidth * 2 + scaledWidth * numCols + borderWidth * (numCols + 1); | ||
+ | montageHeight = labelHeight + scaledHeight * numRows + borderWidth * (numRows + 1); | ||
+ | newImage(montageImage, '16-bit Black' + montageColor, montageWidth, montageHeight, 1); | ||
+ | setForegroundColor(255, 255, 255); | ||
+ | run('Select All'); | ||
+ | run('Fill'); | ||
+ | |||
+ | // label montage | ||
+ | setFont(labelFont, labelSize, labelStyle); | ||
+ | setColor(labelColor); | ||
+ | setJustification('center'); | ||
+ | |||
+ | // label columns | ||
+ | var x = scaledWidth / 2 + labelWidth * 2 + borderWidth; | ||
+ | var y = labelHeight - 10; | ||
+ | for (colNumberLabel = colFrom; colNumberLabel <= colTo; colNumberLabel ++) { | ||
+ | drawString(colNumberLabel, x, y); | ||
+ | x += scaledWidth + borderWidth; | ||
+ | } | ||
+ | |||
+ | // label rows | ||
+ | var x1 = labelWidth / 2; | ||
+ | var x2 = labelWidth / 2 + labelWidth; | ||
+ | var y = labelHeight + borderWidth + scaledHeight / 2 + 30; | ||
+ | for (rowNumberLabel = rowFrom; rowNumberLabel <= rowTo; rowNumberLabel ++) { | ||
+ | var rowCharLabel = fromCharCode(rowNumberLabel + 64); | ||
+ | drawString(rowNumberLabel, x1, y); | ||
+ | drawString(rowCharLabel, x2, y); | ||
+ | y += scaledHeight + borderWidth; | ||
+ | } | ||
+ | |||
+ | //invert | ||
+ | if ( (invertMontage == true) || (invertBorders == true) ) { | ||
+ | makeRectangle(labelWidth * 2, labelHeight, montageWidth - labelWidth * 2, montageHeight - labelHeight); | ||
+ | |||
+ | // invert border and image background | ||
+ | if (invertBorders == true) { | ||
+ | run('Invert'); | ||
+ | } | ||
+ | |||
+ | // invert montage background and labels | ||
+ | if (invertMontage == true) { | ||
+ | run('Make Inverse'); | ||
+ | run('Invert'); | ||
+ | } | ||
+ | |||
+ | run('Select None'); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // scale image | ||
+ | selectWindow('Image'); | ||
+ | run('Scale...', 'x=- y=- width=' + scaledWidth + ' height=' + scaledHeight + ' interpolate title=[Image]'); | ||
+ | run('Canvas Size...', 'width=' + scaledWidth + ' height=' + scaledHeight + ' position=Center'); | ||
+ | run('Multiply...', 'value=16'); | ||
+ | |||
+ | // invert | ||
+ | if (invertImages == true) { | ||
+ | run('XOR...', 'value=1111111111111111'); | ||
+ | } | ||
+ | |||
+ | // copy scaled image into montage | ||
+ | selectWindow('Image'); | ||
+ | run('Select All'); | ||
+ | run('Copy'); | ||
+ | selectWindow(montageImage); | ||
+ | makeRectangle(labelWidth * 2 + scaledWidth * col + borderWidth * (col + 1), labelHeight + scaledHeight * row + borderWidth * (row + 1), scaledWidth, scaledHeight); | ||
+ | run('Paste'); | ||
+ | run('Select None'); | ||
+ | selectWindow('Image'); | ||
+ | close(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | selectWindow(montageImage); | ||
+ | setBatchMode(false); | ||
+ | |||
+ | return; | ||
+ | } | ||
+ | |||
+ | |||
+ | // | ||
+ | // Popup: popup a message | ||
+ | // | ||
+ | |||
+ | function Popup(text, title) { | ||
+ | text = '' + text; | ||
+ | title = '' + title; | ||
+ | Dialog.create(title); | ||
+ | Dialog.addMessage(text) | ||
+ | Dialog.show(); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | |||
+ | // | ||
+ | // CloseAllImages | ||
+ | // | ||
+ | |||
+ | function CloseImages() { | ||
+ | |||
+ | for (i = nImages(); i > 0; i -- ) { | ||
+ | selectImage(i); | ||
+ | close(); | ||
+ | } | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | |||
+ | // | ||
+ | // CloseAllImages | ||
+ | // | ||
+ | |||
+ | function CloseAllImages() { | ||
+ | |||
+ | CloseImages(); | ||
+ | |||
+ | // close message window | ||
+ | if (isOpen('Log')) { | ||
+ | selectWindow('Log'); | ||
+ | run('Close'); | ||
+ | } | ||
+ | |||
+ | return; | ||
+ | } | ||
+ | |||
+ | |||
+ | // install macro: plate montage | ||
+ | macro 'Plate Montage [P]' { | ||
+ | PlateMontage(); | ||
+ | } | ||
+ | |||
+ | // install macro: reload the macro | ||
+ | macro 'Reload Plate Montage macro [M]' { | ||
+ | run('Install...', 'install=[C:\\Program Files\\ImageJ\\macros\\PlateMontage.ijm]'); | ||
+ | } | ||
+ | |||
+ | // install macro: close all images | ||
+ | macro 'Close all images [C]' { | ||
+ | CloseAllImages(); | ||
+ | } | ||
+ | </code> |