diff --git a/BIOP_VSI_reader.ijm b/BIOP_VSI_reader.ijm index 6f8ac9b..49ccd52 100644 --- a/BIOP_VSI_reader.ijm +++ b/BIOP_VSI_reader.ijm @@ -1,1291 +1,1294 @@ // Action Bar description file : BIOP_VSI_reader // By Olivier Burri & Romain Guiet // EPFL BIOP 2014 /* * DESCRIPTION: Simple Action Bar to open and make sense of the Olympus OlyVIA Slide Scanner * The macro works as follows * Uses Jerome Mutterer's Action Bar Plugin as the interface. * Takes advantage of the print "Update" Function as of IJ 1.38m to keep data in memory. * Uses LOCI BioFormats to read and parse the data from the VSI reader * * MOTIVATION: Images produced by the OlyVIA Scanner are extremely large (>48'000px) * The inherent limitation of Java (or IJ) for images is about 48'000px * Because the .vsi files have preview thumbnails, we want to use those in order to * navigate the data and open only the part of the image we're interested in. * A Simple navigator is provided for convenience. * * DISCLAIMER: This is a work in progress and some bugs are bound to pop up, don't hesitate to contact us in case you have problems * at olivier.burri at epfl.ch * Bug 18.05.2012: Navigator: Not obvious when macro finished working. Find a way to stop the position update more easily. */ // Action Bar settings sep = File.separator; call("BIOP_LibInstaller.installLibrary", "plugins"+sep+"BIOP"+sep+"BiopLib.ijm"); // The line below is only for debugging and is not called from within the .jar file. //run("Action Bar","/plugins/ActionBar/BIOP_VSI_reader.ijm"); run("Action Bar", "jar:file:BIOP/BIOP_VSI_reader.jar!/BIOP_VSI_reader.ijm"); exit(); //Start of ActionBar function toolName() { return "VSI Reader"; } function isVSI(filename) { if(endsWith(filename, ".vsi")) { return true; } return false; } /* * openLociStack opens the stack at the given index. This index is the raw index of the image as interpreted by LOCI * It starts at 1 and should be used in conjuction with the "getSeriesIndex... series of functions to ensure it works properly * Based on an example by Wayne Rasband on the LOCI Website */ function openLociStack(name, index) { run("Bio-Formats Macro Extensions"); id = getID(); Ext.setId(id); // Place yourself at the desired series Index (starts at 0); Ext.setSeries(index); // Get ther dimensions Ext.getSizeC(sizeC); Ext.getSizeZ(sizeZ); Ext.getSizeT(sizeT); Ext.getImageCount(n); //Start opening the series setBatchMode(true); for (i=0; i1) { Stack.setDimensions(sizeC, sizeZ, sizeT); if (sizeC>1) { if (sizeC==3&&sizeC==nSlices) mode = "Composite"; else mode = "Color"; run("Make Composite", "display="+mode); } setOption("OpenAsHyperStack", true); } setBatchMode(false); run("Select None"); } /* * Same as above, but opens a sub-region of the image */ function openLociSubStack(name, index, posX, posY, w, h) { run("Bio-Formats Macro Extensions"); id = getID(); Ext.setId(id); Ext.setSeries(index); Ext.getSizeC(sizeC); Ext.getSizeZ(sizeZ); Ext.getSizeT(sizeT); Ext.getImageCount(n); setBatchMode(true); for (i=0; i1) { cMode = getData("Camera Mode"); Stack.setDimensions(sizeC, sizeZ, sizeT); if (sizeC>1) { if (sizeC==3&&sizeC==nSlices) mode = "Composite"; else mode = "Color"; run("Make Composite", "display="+mode); } setOption("OpenAsHyperStack", true); if (cMode == "Brightfield") { for (i=0; i=0; i--) { Ext.setSeries(i); Ext.getSizeX(sizeX); Ext.getSizeY(sizeY); if(sizeX < 100 && sizeY < 100) oldSeries++; } return oldSeries; } function getRawSeriesPos(series) { serN = parseInt(getData("totSeries")); nextSer = 0; nSer=1; //print("Searching for Series ", series); for (i=0; i optSize) { nX+=2; subX = oriW / nX; } while ( subY > optSize) { nY+=2; subY = oriH / nY; } FsubX = floor(subX*factor); FsubY = floor(subY*factor); setBatchMode(true); numSlices = nX*nY*nC; stack=0; sl=0; start = getTime(); for (j=0; j1) { Stack.setDimensions(nC, nX*nY, 1); setOption("OpenAsHyperStack", true); run("Make Composite", "display=Composite"); } run("Make Montage...", "columns="+nX+" rows="+nY+" scale=1"); rename("Series #"+serInd+" at ("+oriX+", "+oriY+") ScaleFactor "+factor); setBatchMode(false); end = getTime(); print("Time to resize [ms] = "+end-start); } else { showMessage("Please make a selection"); } } // Loads the current selection made on a thumbnail at 100% Size function loadCurrentSelection(rescaling) { step = 128; run("Bio-Formats Macro Extensions"); id = getID(); Ext.setId(id); name = getTitle(); serPos = parseInt(substring(name,0,indexOf(name, "-")-1)); serInd = parseInt(substring(name,indexOf(name,"#")+1,lengthOf(name))); //serPos=getSeriesPos(serInd); if(selectionType != -1) { //Get the coordinates of the box getSelectionBounds(x, y, width, height); //And the sizes of the image //Get the samplign factor from the pyramidal format mag = getResamplingRate(serInd); // print("Rescaling: ", rescaling); if ( (round(rescaling) - rescaling == 0 ) && rescaling%2 == 0) { mag = mag/(rescaling); serPos = serPos + round((log(rescaling)/log(2))); } // The the size of the resl series Ext.setSeries(serPos); Ext.getSizeX(sizeX); Ext.getSizeY(sizeY); oriX = round( (mag * (x)) * (1)); oriY = round( (mag * (y)) * (1)); oriW = ( floor(mag * (width) / step) ) * step; oriH = ( floor(mag * (height) / step) ) * step; if (oriX + oriW > sizeX) { neworiW = sizeX - oriX; print("Size of image exceeds image dimensions, cropping:"); print("Original Width: "+oriW+" , New Width: "+neworiW); oriW = neworiW; } if (oriY + oriH > sizeY) { neworiH = sizeY - oriY; print("Size of image exceeds image dimensions, cropping:"); print("Original Height: "+oriH+" , New Height: "+neworiH); oriH = neworiH; } // Make sure that the chosen size is not larger than what imageJ can handle if( oriW > 42000 || oriH > 42000) { showMessage("Your selection is too large ("+oriX+", "+oriY+")\n Please select a smaller area"); } else if(matches(name,".*Thumbnail.*")) { openLociSubStack("Series #"+serInd+" at ("+oriX+", "+oriY+")", (serPos), oriX, oriY, oriW , oriH); } else { showMessage("Please Select a Thumbnail Image!"); } } else { showMessage("Please make a selection"); } } function measureCurrentImageWithMacro(){ macroToMeasure = getData("Macro Image Processing and Measurement Path"); runMacro(macroToMeasure); } function createMaskFromROIs(measureStatus){ Stack.getDimensions(widthOri, heightOri, channelsOri, slicesOri, framesOri) n = roiManager("Count"); // get thu total number of ROI to process currentCat = "*none*"; // set current categorie name to 'none' // Here, the macro will create a new channel for each category // and will fill all ROI with a random grey value for (i=0; i