11 Commits

Author SHA1 Message Date
ec1259303b OptScan: Change a comment. 2019-10-14 10:47:09 +02:00
a929a097ab Removed to avoid conflicts with Chris. 2019-10-14 10:46:47 +02:00
9e99b1136f OptScan: fixed prints and comments to be more clear. 2019-10-14 08:17:15 +02:00
8108ff2187 OptScan: Removed Constant Grid option (was not working yet), since the point of optimised scan is then lost. Some comments have been fixed. 2019-10-14 07:58:30 +02:00
a4083a8cf4 OptScan: fixed missing semicolon. 2019-10-14 07:49:04 +02:00
0a88bba53a OptScan: plugin can read and write hidden parameters file in home folder. 2019-10-14 07:45:11 +02:00
96ea80aefc Added TODO comment about reading settings file 2019-10-10 18:26:48 +02:00
22860e351d MultiScale: changed creation date 2019-10-10 15:46:52 +02:00
f519685d39 OptScan: Changed header 2019-10-10 15:44:41 +02:00
b8d26956d9 Merge branch 'MS-read-parameters-file'
* MS-read-parameters-file:
  Implemented "if" to check if settings file exists and put corresponding default values. At end of plugin, the settings file is (re)written with the new parameters.
  Removed temporary file for tests
  Changed if for test
  Added if
  Added hidden file for testing
  Removed stitchedScan line, since this is deprecated.
2019-10-10 15:27:58 +02:00
cd9fd03d32 Added last modification line. 2019-10-10 11:20:37 +02:00
3 changed files with 91 additions and 177 deletions

View File

@@ -4,7 +4,7 @@
///////// MULTISCALE TOMOGRAPHY PLUGIN /////////
///////// /////////
///////// Created by Hector Dejea, hector.dejea@psi.ch /////////
///////// October, 2019 /////////
///////// May, 2017 /////////
///////// /////////
///////// Reference paper: /////////
///////// Dejea, H. et al. Scientific Reports 9, 6996 (2019) /////////
@@ -28,7 +28,9 @@ The ROI size of the HighRes scan is shown according to the user-
supplied parameters of LowRes and HighRes scans. The user can move
the ROI interactively to the desired position, and the movements in
um are given as the result. Start and end position values for stitched
scans are also available. */
scans are also available.
Last modified: 10/10/2019*/
//Check if there is a file containing the multiscale settings
settings_path = getDirectory("home") + "/.multiscale_settings.txt";

View File

@@ -1,30 +1,67 @@
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
///////// /////////
///////// OPTIMISED SCAN PLUGIN /////////
///////// /////////
///////// Created by Hector Dejea, hector.dejea@psi.ch /////////
///////// February, 2018 /////////
///////// /////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/* Optimised Scan
Opt_Scan.ijm is an ImageJ plugin to find the optimal scanning grid for irregular objects. Binary and
non binary images are accepted. The option to have a constant grid on the whole object or
independent grids for each of the different Y layers is given. The plugin generates a .txt file that
can be used as input for the beamline macro.
Opt_Scan.ijm is an ImageJ plugin to find the optimal scanning grid for
irregular objects. Binary and non binary images are accepted. The option
to have a constant grid on the whole object or independent grids for
each of the different Y layers is given. The plugin generates a .txt file
that can be used as input for the beamline macro.
*Created by hector.dejea@psi.ch in February 2018* */
Last modified: 14/10/2019 */
//Set default values
LowResimagePixelSize = 6.5;
ZZcenterLowRes = 0;
XXcenterLowRes = 0;
YposLowRes = 0;
LowResFOVY = 590;
cameraFOVX = 2560;
cameraFOVY = 2160;
HighResimagePixelSize = 0.65;
CameraMoveX = 0;
CameraMoveY = 0;
//Check if there is a file containing the OptScan settings
settings_path = getDirectory("home") + "/.optscan_settings.txt";
overlapXZ = cameraFOVX*0.3;
overlapY = 50;
if (File.exists(settings_path)){
//Set default parameters specified in the file
parameters_file = File.openAsString(settings_path);
lines=split(parameters_file,"\n");
LowResimagePixelSize = lines[3];
ZZcenterLowRes = lines[5];
XXcenterLowRes = lines[7];
YposLowRes = lines[9];
LowResFOVY = lines[11];
cameraFOVX = lines[13];
cameraFOVY = lines[15];
HighResimagePixelSize = lines[17];
CameraMoveX = lines[19];
CameraMoveY = lines[21];
overlapXZ = lines[23];
overlapY = lines[25];
} else {
//Otherwise set these default values
LowResimagePixelSize = 6.5;
ZZcenterLowRes = 0;
XXcenterLowRes = 0;
YposLowRes = 0;
LowResFOVY = 590;
cameraFOVX = 2560;
cameraFOVY = 2160;
HighResimagePixelSize = 0.65;
CameraMoveX = 0;
CameraMoveY = 0;
overlapXZ = cameraFOVX*0.3;
overlapY = 50;
}
repeatFlag = 1;
while (repeatFlag == 1){
print("Welcome to the Scan Optimisation plugin!");
print("Welcome to the Scan Optimisation plugin!\n");
//Ask the user for LowRes and HighRes acquisition parameters
Dialog.create("Magnification and Camera Settings");
@@ -41,12 +78,10 @@ while (repeatFlag == 1){
Dialog.addNumber("Overlap in X and Z (pixels):", overlapXZ);
Dialog.addNumber("Overlap in Y (pixels):", overlapY);
Dialog.addChoice("Projection Method:", newArray("MaxIP" ,"MinIP"), "MaxIP");
Dialog.addChoice("Grid Mode:", newArray("Constant !!NOT READY!!" ,"Independent"), "Independent");
Dialog.show();
LowResimagePixelSize = Dialog.getNumber();
//angleLowRes = Dialog.getChoice();
XXcenterLowRes = Dialog.getNumber();
ZZcenterLowRes = Dialog.getNumber();
YposLowRes = Dialog.getNumber();
@@ -59,7 +94,6 @@ while (repeatFlag == 1){
overlapXZ = Dialog.getNumber();
overlapY = Dialog.getNumber();
projMethod = Dialog.getChoice();
gridMode = Dialog.getChoice();
// Real magnification
real_magnification = LowResimagePixelSize/HighResimagePixelSize;
@@ -74,13 +108,13 @@ while (repeatFlag == 1){
//Compute number of acquisition layers in Y and layer size
blockSizeY = cameraFOVY-overlapY;
print("Complete block Size in Y is " + (cameraFOVY/real_magnification) + " pixels");
print("Volume Size in Y is " + (cameraFOVY/real_magnification) + " pixels");
print("Block Size in Y is " + (blockSizeY/real_magnification) + " pixels");
nLayersY = computeNumberBlocks("Y",blockSizeY,cameraFOVY,StartSlice,EndSlice,real_magnification);
//Compute blocksize XZ
blockSizeXZ = cameraFOVX-overlapXZ;
print("Complete block Size in XZ is " + (cameraFOVX/real_magnification) + " pixels");
print("Volume Size in XZ is " + (cameraFOVX/real_magnification) + " pixels");
print("Block Size in XZ is " + (blockSizeXZ/real_magnification) + " pixels");
//Check if image is binary
@@ -127,20 +161,10 @@ while (repeatFlag == 1){
yEndVals[i] = y + height -1;
}
//GENERATE Y CONSTANT GRID
if (gridMode == "Constant") {
centresXXZZY = generateYConstantGrid(blockSizeXZ,blockSizeY,cameraFOVX,cameraFOVY,nLayersY,xVals,
yVals,xEndVals,yEndVals,real_magnification,XXcenterLowRes,ZZcenterLowRes,LowResimagePixelSize,
HighResimagePixelSize,LowResFOVY,CameraMoveX,CameraMoveY,imagewidth,imageheight,StartSlice);
}
//GENERATE Y INDEPENDENT GRID
if (gridMode == "Independent") {
centresXXZZY = generateYIndependentGrid(blockSizeXZ,blockSizeY,cameraFOVX,cameraFOVY,nLayersY,xVals,
yVals,xEndVals,yEndVals,real_magnification,XXcenterLowRes,ZZcenterLowRes,LowResimagePixelSize,
HighResimagePixelSize,LowResFOVY,CameraMoveX,CameraMoveY,imagewidth,imageheight,StartSlice);
}
//GENERATE GRID
centresXXZZY = generateYIndependentGrid(blockSizeXZ,blockSizeY,cameraFOVX,cameraFOVY,nLayersY,xVals,
yVals,xEndVals,yEndVals,real_magnification,XXcenterLowRes,ZZcenterLowRes,LowResimagePixelSize,
HighResimagePixelSize,LowResFOVY,CameraMoveX,CameraMoveY,imagewidth,imageheight,StartSlice);
//COMPLETE FOR BINARY IMAGES -> ELIMINATE EMPTY VOLUMES
@@ -176,19 +200,11 @@ while (repeatFlag == 1){
yEndVals[i] = y + height -1;
}
//GENERATE CONSTANT GRID
if (gridMode == "Constant") {
centresXXZZY = generateYConstantGrid(blockSizeXZ,blockSizeY,cameraFOVX,cameraFOVY,nLayersY,xVals,
yVals,xEndVals,yEndVals,real_magnification,XXcenterLowRes,ZZcenterLowRes,LowResimagePixelSize,
HighResimagePixelSize,LowResFOVY,CameraMoveX,CameraMoveY,imagewidth,imageheight,StartSlice);
}
//GENERATE GRID
centresXXZZY = generateYIndependentGrid(blockSizeXZ,blockSizeY,cameraFOVX,cameraFOVY,nLayersY,xVals,
yVals,xEndVals,yEndVals,real_magnification,XXcenterLowRes,ZZcenterLowRes,LowResimagePixelSize,
HighResimagePixelSize,LowResFOVY,CameraMoveX,CameraMoveY,imagewidth,imageheight,StartSlice);
//GENERATE INDEPENDENT GRID
if (gridMode == "Independent") {
centresXXZZY = generateYIndependentGrid(blockSizeXZ,blockSizeY,cameraFOVX,cameraFOVY,nLayersY,xVals,
yVals,xEndVals,yEndVals,real_magnification,XXcenterLowRes,ZZcenterLowRes,LowResimagePixelSize,
HighResimagePixelSize,LowResFOVY,CameraMoveX,CameraMoveY,imagewidth,imageheight,StartSlice);
}
}
//Print .txt file with the generated coordinates
@@ -200,8 +216,26 @@ while (repeatFlag == 1){
if (repeatFlag) {
closeGeneratedImgs();
}
//Save txt file with the parameters used, so that they are default for next use.
settings_file = File.open(settings_path);
settings_array = "File containing the last settings used in Opt_Scan.ijm\n" +
"\nLowResimagePixelSize\n" + LowResimagePixelSize +
"\nZZcenterLowRes\n" + ZZcenterLowRes +
"\nXXcenterLowRes\n" + XXcenterLowRes +
"\nYposLowRes\n" + YposLowRes +
"\nLowResFOVY\n" + LowResFOVY +
"\ncameraFOVX\n" + cameraFOVX +
"\ncameraFOVY\n" + cameraFOVY +
"\nHighResimagePixelSize\n" + HighResimagePixelSize +
"\nCameraMoveX\n" + CameraMoveX +
"\nCameraMoveY\n" + CameraMoveY +
"\noverlapXZ\n" + overlapXZ +
"\noverlapY\n" + overlapY;
print(settings_file, settings_array);
File.close(settings_file);
}
} //END
@@ -332,8 +366,10 @@ while (repeatFlag == 1){
totalBlocksLayer = 0;
totalBlocks = 0;
for (i = 0; i < nLayersY; i++ ) {
print("\nY layer" + (i+1) + ":");
numBlocksXX[i] = computeNumberBlocks("XX",blockSizeXZ,cameraFOVX,yVals[i],yEndVals[i],real_magnification);
numBlocksZZ[i] = computeNumberBlocks("ZZ",blockSizeXZ,cameraFOVX,xVals[i],xEndVals[i],real_magnification);
//Total number of XX and ZZ blocks
totalBlocksLayer = numBlocksXX[i]*numBlocksZZ[i];
totalBlocks = totalBlocks + totalBlocksLayer;
@@ -346,111 +382,6 @@ while (repeatFlag == 1){
return centresXXZZY;
}
////////////////////////////////////////
function generateYConstantGrid(blockSizeXZ,blockSizeY,cameraFOVX,cameraFOVY,nLayersY,xVals,yVals,xEndVals,
yEndVals,real_magnification,XXcenterLowRes,ZZcenterLowRes,LowResimagePixelSize,HighResimagePixelSize,
LowResFOVY,CameraMoveX,CameraMoveY,imagewidth,imageheight,StartSlice) {
//Function that generates a constant grid for all Y layers.
Array.getStatistics(xVals, minx);
Array.getStatistics(yVals, miny);
Array.getStatistics(xEndVals, minw, maxw);
Array.getStatistics(yEndVals, minh, maxh);
//Compute number of blocks for most extense rectangle
numBlocksXXmax = computeNumberBlocks("XX",blockSizeXZ,cameraFOVX,miny,maxh,real_magnification);
numBlocksZZmax = computeNumberBlocks("ZZ",blockSizeXZ,cameraFOVX,minx,maxw,real_magnification);
//Generate the FIXED GRID (in Low Resolution pixels)
gridXX = newArray(numBlocksXXmax+1);
gridZZ = newArray(numBlocksZZmax+1);
gridXXcentres = newArray(numBlocksXXmax);
gridZZcentres = newArray(numBlocksZZmax);
gridXX[0] = miny;
gridZZ[0] = minx;
//First block is complete, so the center is computed without overlap taken into account
gridXXcentres[0] = gridXX[0] + cameraFOVX/2/real_magnification;
//Compute XX center and XX position for each volume of the grid
for (i=1; i < numBlocksXXmax; i++) {
gridXXcentres[i] = gridXXcentres[i-1] + blockSizeXZ/real_magnification;
gridXX[i] = gridXX[i-1] + blockSizeXZ/real_magnification;
}
//First block is complete, so the center is computed without overlap taken into account
gridZZcentres[0] = gridZZ[0] + cameraFOVX/2/real_magnification;
//Compute ZZ center and ZZ grid position for each volume of the grid
for (i=1; i < numBlocksZZmax; i++) {
gridZZcentres[i] = gridZZcentres[i-1] + blockSizeXZ/real_magnification;
gridZZ[i] = gridZZ[i-1] + blockSizeXZ/real_magnification;
}
//Modify rectangle coordinates to fit the generated grid
//Central position of the corresponding FOV is given (in pixels)
posInZZ = newArray(nLayersY);
posFinZZ = newArray(nLayersY);
posInXX = newArray(nLayersY);
posFinXX = newArray(nLayersY);
for (i = 0; i < nLayersY; i++) {
for (j = 1; j < numBlocksZZmax+1; j++) {
if (xVals[i] < gridZZ[j]){
posInZZ[i] = gridZZcentres[j-1];
break;
}
}
for (k = j; k < numBlocksZZmax+1; k++) {
if (xEndVals[i] < gridZZ[k]){
posFinZZ[i] = gridZZcentres[k-1];
break;
}
}
for (jj = 1; jj < numBlocksXXmax+1; jj++) {
if (yVals[i] < gridXX[jj]){
posInXX[i] = gridXXcentres[jj-1];
break;
}
}
for (kk = jj; kk < numBlocksXXmax+1; kk++) {
if (yEndVals[i] < gridXX[kk]){
posFinXX[i] = gridXXcentres[kk-1];
break;
}
}
}
//Compute Y positions in stage coords
centresYreal = computeYCoords(nLayersY,YposLowRes,LowResFOVY,StartSlice,LowResimagePixelSize,CameraMoveY,
cameraFOVY,HighResimagePixelSize,blockSizeY);
//Compute number of blocks per layer and total number
numBlocksXX = newArray(nLayersY);
numBlocksZZ = newArray(nLayersY);
totalBlocksLayer = 0;
totalBlocks = 0;
for (i = 0; i < nLayersY; i++ ) {
numBlocksXX[i] = computeNumberBlocks("XX",blockSizeXZ,cameraFOVX,posInXX[i],posFinXX[i],real_magnification);
numBlocksZZ[i] = computeNumberBlocks("ZZ",blockSizeXZ,cameraFOVX,posInZZ[i],posFinZZ[i],real_magnification);
//Total number of XX and ZZ blocks
totalBlocksLayer = numBlocksXX[i]*numBlocksZZ[i];
totalBlocks = totalBlocks + totalBlocksLayer;
}
//Grid in stage coords giving (XX,ZZ,Y) for each volume, from top to bottom, left to right and up to down.
centresXXZZY = lowResPx2StageCoords(numBlocksXX,numBlocksZZ,totalBlocks,nLayersY,posInXX,posInZZ,
cameraFOVX,real_magnification,imagewidth,imageheight,XXcenterLowRes,ZZcenterLowRes,LowResimagePixelSize,
HighResimagePixelSize,CameraMoveX,blockSizeXZ,centresYreal);
return centresXXZZY;
}
////////////////////////////////////////
function writeCoordsFile(centresXXZZY) {

View File

@@ -1,19 +0,0 @@
from ij import IJ
from ij.gui import Overlay, Line
imp = IJ.getImage()
cx = int(imp.width/2.0)
cy = int(imp.height/2.0)
print cx, cy
overlay = Overlay()
line_v = Line(cx,0,cx,imp.height)
line_v.setStrokeWidth(1)
overlay.add(line_v)
line_h = Line(0,cy,imp.width,cy)
line_h.setStrokeWidth(1)
overlay.add(line_h)
imp.setOverlay(overlay)
imp.show()