Commit 54e9d9d4 authored by Aliaksandr Halavatyi's avatar Aliaksandr Halavatyi
Browse files

fiji-plugin-morphometry for calculating embryo center and rotation in HZ focus job

parent 940cd517
......@@ -17,7 +17,16 @@ Multichamber wide slide with fixed fly embryos stained with 3 dyes:
# Log/updates
2018-01-05 Tim and Alex
## 2019-03
Version of high-zoom focus job based on `fiji-plugin morphometry` from C. Tischer. It allows split to touching embryos and correctly calculate embryo center in XYZ anfd rotation angle.
## ....
## 2018-01-05 Tim and Alex
- Configuring acquisition jobs manually.
- Trying feedback experiments with manual selection procedures
- X-Y coordinates are flipping, microscope additionally scans from right to left
\ No newline at end of file
......@@ -94,7 +94,7 @@
<dependency>
<groupId>de.embl.cba</groupId>
<artifactId>fiji-plugin-morphometry</artifactId>
<version>0.4.03</version>
<version>0.4.04</version>
</dependency>
</dependencies>
......
package feedback.fly.embryo.jobdistributors;
import ij.gui.GenericDialog;
import ij.gui.WaitForUserDialog;
import ij.plugin.PlugIn;
import automic.online.jobdistributors.JobDistributor_Abstract;
import automic.online.jobs.common.Job_AutofocusInitOffset;
import automic.parameters.ParameterCollection;
import automic.parameters.gui.ParameterGuiManager;
import automic.table.TableModel;
import automic.table.TableProcessor;
import feedback.fly.embryo.jobs.Job_FocusEmbryoAutoDatasetSplit;
import feedback.fly.embryo.jobs.Job_RecordFinishDataset;
import feedback.fly.embryo.jobs.Job_SelectMultipleEmbryosManual3D;
public class JobDistributor_ManualSelection3DMultiple_AFocus_Rotation_Split extends JobDistributor_Abstract implements PlugIn {
@Override
protected void fillJobList(){
Job_AutofocusInitOffset job1=new Job_AutofocusInitOffset();
ParameterCollection job1Parameters=job1.createJobParameters();
job1Parameters.setUndefinedValuesFromDefaults();
ParameterGuiManager pgManager1=new ParameterGuiManager(job1Parameters);
try{
pgManager1.refineParametersViaDialog("Coverslip focusing");
}catch(Exception _ex){
new WaitForUserDialog("error in parameter values");
}
job1.parseInputParameterValues(pgManager1.getParameterCollection());
super.addImageJob(job1, "DE_1_", "AFocus", true);
Job_SelectMultipleEmbryosManual3D job2=new Job_SelectMultipleEmbryosManual3D();
ParameterCollection job2Parameters=job2.createJobParameters();
job2Parameters.setUndefinedValuesFromDefaults();
ParameterGuiManager pgManager2=new ParameterGuiManager(job2Parameters);
try{
pgManager2.refineParametersViaDialog("Parameters for manual embryo selection");
}catch(Exception _ex){
new WaitForUserDialog("error in parameter values");
}
job2.parseInputParameterValues(pgManager2.getParameterCollection());
super.addImageJob(job2, "DE_2_", "LZ.Image", true);
Job_FocusEmbryoAutoDatasetSplit job3=new Job_FocusEmbryoAutoDatasetSplit();
ParameterCollection job3Parameters=job3.createJobParameters();
job3Parameters.setUndefinedValuesFromDefaults();
ParameterGuiManager pgManager3=new ParameterGuiManager(job3Parameters);
try{
pgManager3.refineParametersViaDialog("Parameters for embryo focusing");
}catch(Exception _ex){
new WaitForUserDialog("error in parameter values");
}
job3.parseInputParameterValues(pgManager3.getParameterCollection());
super.addImageJob(job3, "TR1_1_", "Focus.Image", true);
super.addImageJob(Job_RecordFinishDataset.class, "TR2_1_", "Result.Image", true);
}
@Override
protected TableModel constructTabModel(String _rpth){
TableModel outTbl=new TableModel(_rpth);
outTbl.addColumn("Date.Time");
outTbl.addFileColumns("AFocus", "IMG");
outTbl.addFileColumns("LZ.Image", "IMG");
outTbl.addFileColumns("Focus.Image", "IMG");
outTbl.addFileColumns("Result.Image", "IMG");
outTbl.addValueColumn("Zoom.X", "NUM");
outTbl.addValueColumn("Zoom.Y", "NUM");
outTbl.addValueColumn("Correction.X", "NUM");
outTbl.addValueColumn("Correction.Y", "NUM");
outTbl.addValueColumn("Focus.Z", "NUM");
outTbl.addValueColumn("Rotation", "NUM");
outTbl.addValueColumn("Success", "BOOL");
outTbl.addRow(new Object[outTbl.getColumnCount()]);
return outTbl;
}
@Override
protected TableProcessor configureTableProcessor(TableModel _tModel)throws Exception{
TableProcessor tProcessor=new TableProcessor(_tModel);
tProcessor.addFileColumns("Selected.Embryo.LZ", "ROI");
return tProcessor;
}
@Override
protected void putProtocolPreferencesToDialog(GenericDialog _dialog){}
@Override
protected void getProtocolPreferencesFromDialog(GenericDialog _dialog){}
@Override
protected boolean showDialogInDebugRun(){
return false;
}
@Override
protected void setDebugConfiguration(){
final String searchPath="C:/tempDat/AutoMic_test";
this.setGeneralOptions(searchPath, true, false);
this.fileExtension="lsm";
}
}
package feedback.fly.embryo.jobs;
import java.awt.Color;
import java.io.File;
import java.util.concurrent.TimeUnit;
import automic.online.microscope.ZeissKeys;
import automic.online.jobs.Job_Default;
import automic.parameters.ParameterCollection;
import automic.parameters.ParameterType;
import automic.table.TableModel;
import de.embl.cba.morphometry.ImageIO;
import de.embl.cba.morphometry.Utils;
import de.embl.cba.morphometry.drosophila.registration.DrosophilaRegistrationSettings;
import de.embl.cba.morphometry.drosophila.registration.DrosophilaSingleChannelRegistration;
import ij.IJ;
import net.imagej.ImageJ;
import ij.ImagePlus;
import ij.gui.Arrow;
import ij.gui.Overlay;
import ij.gui.PointRoi;
import ij.gui.Roi;
import loci.plugins.BF;
import loci.plugins.in.ImporterOptions;
import net.imagej.ops.OpService;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
public class Job_FocusEmbryoAutoDatasetSplit extends Job_Default{
public static final String KEY_FOCUS_CHANNEL_INDEX="Focus channel index";
public static final String KEY_WAIT_IMAGE_OPENING="Wait for image opening (milliseconds)";
public static final String KEY_FOCUS_OFFSET="Focus offset";
private OpService opService=null;
private ImagePlus img=null;
private Double selectedXPosition;
private Double selectedYPosition;
private Double selectedZPosition;
private Double rotation;
private Double halfLength;
private int targetChannel=1;
private int imageOpeningTimeDelay=3000;
private int focusOffset=0;
@Override
public void initialise(String _fTag,String _colNm, boolean _visOnline){
super.initialise(_fTag, _colNm, _visOnline);
opService=new ImageJ().op();
}
@Override
protected void cleanIterOutput(){
img=null;
selectedXPosition=null;
selectedYPosition=null;
selectedYPosition=null;
rotation=null;
halfLength=null;
}
@Override
protected void preProcessOnline()throws Exception{
int zoomCounter=(int)this.getSharedValue("Zoom Counter");
int tableRowCounter=(int)this.getSharedValue("Table Row Counter");
zoomCounter++;
tableRowCounter++;
String Exper_nm=(String)getSharedValue("Experiment Name");// newImgFile.getName();
String rootPath=currentTable.getRootPath();
File experimentTableFile=new File(rootPath,"summary_"+Exper_nm+".txt");
TableModel experimentTable=new TableModel(experimentTableFile);
while(experimentTable.getBooleanValue(tableRowCounter, "Success")==false) {
tableRowCounter++;
}
experimentTable.setFileAbsolutePath(newImgFile, tableRowCounter, imgColumnNm, "IMG");
experimentTable.writeNewFile("summary_"+Exper_nm+".txt", true);
TimeUnit.MILLISECONDS.sleep(imageOpeningTimeDelay);
img=openSelectedSlices(newImgFile);
this.setSharedValue("Zoom Counter", zoomCounter);
this.setSharedValue("Table Row Counter", tableRowCounter);
}
@Override
protected void preProcessOffline()throws Exception{
//img=ImageOpenerWithBioformats.openImage(currentTable.getFile(curDInd, imgColumnNm, "IMG"));
img=openSelectedSlices(currentTable.getFile(curDInd, imgColumnNm, "IMG"));
}
private ImagePlus openSelectedSlices(File _imageFile)throws Exception{
ImporterOptions options = new ImporterOptions();
options.setAutoscale(true);
options.setId(_imageFile.getAbsolutePath());
options.setCBegin(0, targetChannel-1);
options.setCEnd(0, targetChannel-1);
return BF.openImagePlus(options)[0];
}
@Override
protected boolean runProcessing()throws Exception{
this.showDebug(img, "Original Image", false);
//new WaitForUserDialog ("Select Shift Point").show();
this.showDebug(img, "Original Image", false);
//////code from Tischi
getEllipsoidParameters(img);
////
halfLength=img.getWidth()/3.0;
if(rotation>90)
rotation=rotation-180;
return true;
}
private < T extends RealType< T > & NativeType< T > >
void getEllipsoidParameters(ImagePlus _image)throws Exception {
final DrosophilaRegistrationSettings settings =
new DrosophilaRegistrationSettings();
settings.onlyComputeEllipsoidParameters = true;
double w=img.getCalibration().pixelWidth/settings.registrationResolution;
double h=img.getCalibration().pixelHeight/settings.registrationResolution;
double d=img.getCalibration().pixelDepth/settings.registrationResolution;
RandomAccessibleInterval< T > images =
ImageIO.getChannelImages( _image );
RandomAccessibleInterval< T > image =
ImageIO.getChannelImage( images, 0 );
final DrosophilaSingleChannelRegistration registration = new DrosophilaSingleChannelRegistration( settings, opService );
final double[] calibration = Utils.getCalibration( _image );
registration.run( image, calibration );
final double[] centre = registration.getElliposidCentreInInputImagePixelUnits();
final double[] angles = registration.getElliposidEulerAnglesInDegrees();
selectedXPosition = centre[0];
selectedYPosition = centre[1];
selectedZPosition = centre[2];
rotation=-angles[0];
}
@Override
protected Overlay createOverlay(){
Overlay o=new Overlay();
Roi pointRoi=new PointRoi(selectedXPosition, selectedYPosition);
pointRoi.setPosition((int)(selectedZPosition+1));
o.add(pointRoi);
Double angleRadians=rotation/180*Math.PI;
Roi lineRoi=new Arrow(selectedXPosition, selectedYPosition, selectedXPosition+halfLength*Math.cos(angleRadians), selectedYPosition-halfLength*Math.sin(angleRadians));
lineRoi.setStrokeColor(Color.PINK);
lineRoi.setStrokeWidth(1);
o.add(lineRoi);
return o;
}
@Override
public void visualise(int _xvis, int _yvis){
this.visualiseImg(img, getOverlay(), _xvis, _yvis);
if (selectedZPosition!=null)
img.setPosition((int)(selectedZPosition+1));
}
@Override
public void postProcessSuccess()throws Exception{
ZeissKeys.submitCommandsToMicroscope("trigger2", ""+selectedXPosition,""+selectedYPosition,""+selectedZPosition,""+rotation,"","","","","");
int tableRowCounter=(int)this.getSharedValue("Table Row Counter");
String Exper_nm=(String)getSharedValue("Experiment Name");// newImgFile.getName();
File experimentTableFile=new File(currentTable.getRootPath(),"summary_"+Exper_nm+".txt");
TableModel experimentTable=new TableModel(experimentTableFile);
experimentTable.setNumericValue(selectedXPosition, tableRowCounter, "Correction.X");
experimentTable.setNumericValue(selectedYPosition, tableRowCounter, "Correction.Y");
experimentTable.setNumericValue(selectedZPosition, tableRowCounter, "Focus.Z");
experimentTable.setNumericValue(rotation, tableRowCounter, "Rotation");
experimentTable.writeNewFile("summary_"+Exper_nm+".txt", true);
saveRoisForImage(newImgFile,getOverlay().toArray());
}
@Override
public void postProcessFail()throws Exception{
ZeissKeys.submitCommandsToMicroscope("nothing",null,null,null,null,null,null,null,null, "Suitable object is not found");
int tableRowCounter=(int)this.getSharedValue("Table Row Counter");
String Exper_nm=(String)getSharedValue("Experiment Name");// newImgFile.getName();
File experimentTableFile=new File(currentTable.getRootPath(),"summary_"+Exper_nm+".txt");
TableModel experimentTable=new TableModel(experimentTableFile);
experimentTable.setBooleanValue(false, tableRowCounter, "Success");
experimentTable.writeNewFile("summary_"+Exper_nm+".txt", true);
}
protected void postProcessOffline(){
try {
this.showDebug(img, "Image with overlay", true,getOverlay());
}catch (Exception ex){
IJ.error("Error during offline visualisation");
}
}
@Override
public ParameterCollection createJobParameters(){
ParameterCollection jobCollection=new ParameterCollection();
jobCollection.addParameter(KEY_FOCUS_CHANNEL_INDEX, null, targetChannel, ParameterType.INT_PARAMETER);
jobCollection.addParameter(KEY_WAIT_IMAGE_OPENING, null, imageOpeningTimeDelay,ParameterType.INT_PARAMETER);
jobCollection.addParameter(KEY_FOCUS_OFFSET, null, focusOffset, ParameterType.INT_PARAMETER);
return jobCollection;
}
@Override
public void parseInputParameterValues(ParameterCollection _jobParameterCollection){
this.targetChannel= (Integer)_jobParameterCollection.getParameterValue(KEY_FOCUS_CHANNEL_INDEX);
this.imageOpeningTimeDelay= (Integer)_jobParameterCollection.getParameterValue(KEY_WAIT_IMAGE_OPENING);
this.focusOffset= (Integer)_jobParameterCollection.getParameterValue(KEY_FOCUS_OFFSET);
}
/**
* offline debugging
* @param args unsused
*/
public static void main(String[] args)throws Exception{
// start ImageJ
new ImageJ().ui().showUI();
String tblPth="C:\\tempDat\\Crocker-lab\\Test_protocol_update_20181109";
String tblFnm="summary_test8_m.txt";
Job_FocusEmbryoAutoDatasetSplit testJob=new Job_FocusEmbryoAutoDatasetSplit();
testJob.initialise(null, "Focus.Image", false);
testJob.testJobMicTable(3, tblPth, tblFnm);
}
}
......@@ -11,5 +11,6 @@ Plugins>Auto Mic Tools>Fly Embryo Screen, "Automated selection of multiple embry
Plugins>Auto Mic Tools>Fly Embryo Screen, "Automated selection of multiple embryos with reflection autofocus", feedback.fly.embryo.jobdistributors.JobDistributor_AutoSelectionMultiple_AFocus
Plugins>Auto Mic Tools>Fly Embryo Screen, "Automated selection of multiple embryos with reflection autofocus and embryo rotation", feedback.fly.embryo.jobdistributors.JobDistributor_AutoSelectionMultiple_AFocus_Rotation
Plugins>Auto Mic Tools>Fly Embryo Screen, "Manual selection of multiple embryos with reflection autofocus and embryo rotation", feedback.fly.embryo.jobdistributors.JobDistributor_ManualSelection3DMultiple_AFocus_Rotation
Plugins>Auto Mic Tools>Fly Embryo Screen, "Manual selection of multiple embryos with reflection autofocus, embryo rotation and split", feedback.fly.embryo.jobdistributors.JobDistributor_ManualSelection3DMultiple_AFocus_Rotation_Split
Plugins>Auto Mic Tools>Fly Embryo Screen,"-"
Plugins>Auto Mic Tools>Fly Embryo Screen, "Test segmentation parameters", feedback.fly.embryo.jobtests.Embryo_Selection_Tester
......@@ -25,7 +25,7 @@ public class FindEmbryoOrientationTischi {
public static < T extends RealType< T > & NativeType< T > >
void main(String[] args) throws Exception{
final ImageJ ij = new ImageJ();
//ij.ui().showUI();
ij.ui().showUI();
final OpService opService = ij.op();
......@@ -33,7 +33,8 @@ public class FindEmbryoOrientationTischi {
System.out.println(new File(inputPath).exists());
final ImagePlus imagePlus = BF.openImagePlus(inputPath)[0];
imagePlus.show();
final DrosophilaRegistrationSettings settings =
new DrosophilaRegistrationSettings();
settings.onlyComputeEllipsoidParameters = true;
......@@ -49,11 +50,17 @@ public class FindEmbryoOrientationTischi {
final double[] calibration = Utils.getCalibration( imagePlus );
registration.run( image, calibration );
final double[] centre = registration.getElliposidCentreInInputImagePixelUnits();
final double[] angles = registration.getElliposidEulerAnglesInDegrees();
final EllipsoidMLJ ellipsoidParameters = registration.getEllipsoidParameters();
System.out.println(String.format("X:%f; Y: %f; z: %f", centre[0], centre[1], centre[2]));
System.out.println(String.format("A1:%f; A2: %f; A3: %f", angles[0], angles[1], angles[2]));
//final EllipsoidMLJ ellipsoidParameters = registration.getEllipsoidParameters();
Logger.log( ellipsoidParameters.toString() );
//Logger.log( ellipsoidParameters.toString() );
final AffineTransform3D alignmentTransform =EllipsoidsMLJ.createAlignmentTransform( ellipsoidParameters );
//final AffineTransform3D alignmentTransform =EllipsoidsMLJ.createAlignmentTransform( ellipsoidParameters );
}
}
package jobdistributors.run.debug;
import feedback.fly.embryo.jobdistributors.JobDistributor_ManualSelection3DMultiple_AFocus_Rotation;
import feedback.fly.embryo.jobdistributors.JobDistributor_ManualSelection3DMultiple_AFocus_Rotation_Split;
import ij.IJ;
import ij.ImageJ;
import net.imagej.ImageJ;
public class RunManualDistributorRotation {
public class RunManualDistributorRotationSplit {
public static void main(String[] args) {
Class<?> clazz = JobDistributor_ManualSelection3DMultiple_AFocus_Rotation.class;
Class<?> clazz = JobDistributor_ManualSelection3DMultiple_AFocus_Rotation_Split.class;
// start ImageJ
new ImageJ();
ImageJ ij2=new ImageJ();
ij2.ui().showUI();
IJ.runPlugIn(clazz.getName(),"Debug run");
//IJ.runPlugIn(clazz.getName(),"");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment