|
| 1 | +/* ---------------------------------------------------------------------------------------- |
| 2 | + |
| 3 | +How to use this macro? |
| 4 | + |
| 5 | +1. Open one of your images. |
| 6 | +2. Make sure that your ROIs Manager is filled |
| 7 | +3. Click the "Run" button |
| 8 | + |
| 9 | +Extracted metrics: |
| 10 | + |
| 11 | +- Name: Name of the ROI in the ROIs Manager |
| 12 | +- Total area: The area of each ROI is calculated. It is expressed in physical unit if the image is calibrated. |
| 13 | +- Global intensity: Integrated intensity over the whole ROI without restriction. |
| 14 | +- Ring intensity: Integrated intensity over the whole ROI after the image was multiplied with the ring mask. |
| 15 | + Since the integrated intensity is the sum of pixels values over the whole area, the presence |
| 16 | + of zeros (after the multiplication) doesn't affect the value. |
| 17 | + |
| 18 | +How is the ring mask calculated ? |
| 19 | + |
| 20 | +- The LoG filter is applied to the image, which produces a map of prominence, showing present structures. |
| 21 | + - A ring should be a donut-like structure |
| 22 | + - The absence of ring implies an absence of structure |
| 23 | + - An intermediate form should produce a fragmented mask over the nucleus. |
| 24 | +- This LoG result is thresholded and divided by 255 to have a mask where ring pixels are at 1, and BG is at 0. |
| 25 | +- We multiply the image with this mask, so the pixels of ring are left untouched while everything else is erased. |
| 26 | +- The integrated intensity over an area is constant whether this area contains 2 or 2000 zero-pixels. |
| 27 | + |
| 28 | +Settings: |
| 29 | +- TABLE_PREFIX: The name of the results table will the image's name prefixed with that. |
| 30 | +- THRESHOLDING: If "AUTO", the LoG will be thresholded with the THRESHOLD_MTD method. |
| 31 | + If "MANUAL", the LoG will be thresholded between -1E30 and THRESHOLD_VAL. |
| 32 | +- THRESHOLD_MTD: See description of 'THRESHOLDING' above. |
| 33 | +- THRESHOLD_VAL: See description of 'THRESHOLDING' above. |
| 34 | +- OUTPUT_FOLDER: Folder in which control images are exported. |
| 35 | + Make sure it ends with a separator ('/' on Mac&Linux, '\' on Windows) |
| 36 | + On Windows, make sure to double every '\'. No '\' should be alone, even the last one. |
| 37 | +- CHANNEL_INDEX: Rank of the channel in which intensity measurements have to be done. Starts at 1. |
| 38 | +- RADIUS: Approximate radius of a ring-like structure in physical unit (== thickness of the donut) |
| 39 | + |
| 40 | +-----------------------------------------------------------------------------------------*/ |
| 41 | + |
| 42 | +TABLE_PREFIX = "Ratios-"; |
| 43 | +THRESHOLDING = "AUTO" // "MANUAL" or "AUTO" |
| 44 | +THRESHOLD_MTD = "Triangle"; |
| 45 | +THRESHOLD_VAL = -80.12; |
| 46 | +OUTPUT_FOLDER = "/home/benedetti/Downloads/2025-04-30-mauboiron/transfer_9723622_files_252ef7e0/tests/"; |
| 47 | +CHANNEL_INDEX = 3; |
| 48 | +RADIUS = 0.2; |
| 49 | + |
| 50 | + |
| 51 | +function measure_global_intensities(image, table_name) { |
| 52 | + selectImage(image); |
| 53 | + run("Select None"); |
| 54 | + for (i = 0 ; i < roiManager("count") ; i++) { |
| 55 | + roiManager("select", i); |
| 56 | + name = RoiManager.getName(i); |
| 57 | + global_int = getValue("IntDen"); |
| 58 | + global_area = getValue("Area"); |
| 59 | + Table.set("Name", i, name, table_name); |
| 60 | + Table.set("Total area", i, global_area, table_name); |
| 61 | + Table.set("Global intensity", i, global_int, table_name); |
| 62 | + } |
| 63 | +} |
| 64 | + |
| 65 | +function measure_ring_intensities(image, table_name) { |
| 66 | + selectImage(image); |
| 67 | + t = getTitle(); |
| 68 | + run("Select None"); |
| 69 | + run("FeatureJ Laplacian", "compute smoothing="+RADIUS); |
| 70 | + saveAs("TIFF", OUTPUT_FOLDER+getTitle()); |
| 71 | + if (THRESHOLDING == "AUTO") { |
| 72 | + setAutoThreshold("Triangle no-reset"); |
| 73 | + } else { |
| 74 | + setThreshold(-1E30, THRESHOLD_VAL); |
| 75 | + } |
| 76 | + run("Convert to Mask"); |
| 77 | + run("Divide...", "value=255"); |
| 78 | + run("16-bit"); |
| 79 | + saveAs("TIFF", OUTPUT_FOLDER+getTitle()+"-mask.tif"); |
| 80 | + rename("target_mask"); |
| 81 | + target_mask = getImageID(); |
| 82 | + imageCalculator("Multiply create", t, "target_mask"); |
| 83 | + new_intensities = getImageID(); |
| 84 | + selectImage(target_mask); |
| 85 | + close(); |
| 86 | + |
| 87 | + selectImage(new_intensities); |
| 88 | + run("Select None"); |
| 89 | + for (i = 0 ; i < roiManager("count") ; i++) { |
| 90 | + roiManager("select", i); |
| 91 | + ring_int = getValue("IntDen"); |
| 92 | + Table.set("Ring intensity", i, ring_int, table_name); |
| 93 | + } |
| 94 | + close(); |
| 95 | +} |
| 96 | + |
| 97 | +function launch_measures() { |
| 98 | + image_name = getTitle(); |
| 99 | + table_name = TABLE_PREFIX + image_name; |
| 100 | + Table.create(table_name); |
| 101 | + run("Select None"); |
| 102 | + |
| 103 | + run("Duplicate...", "duplicate channels=" + CHANNEL_INDEX + "-" + CHANNEL_INDEX); |
| 104 | + original = getImageID(); |
| 105 | + |
| 106 | + measure_global_intensities(original, table_name); |
| 107 | + measure_ring_intensities(original, table_name); |
| 108 | + close(); |
| 109 | +} |
| 110 | + |
| 111 | +launch_measures(); |
0 commit comments