package edu.stanford.rsl.conrad.reconstruction.iterative; import ij.process.FloatProcessor; import ij.process.ImageProcessor; import java.text.NumberFormat; import java.util.Locale; import edu.stanford.rsl.conrad.data.numeric.Grid2D; import edu.stanford.rsl.conrad.data.numeric.Grid3D; import edu.stanford.rsl.conrad.filtering.ImageFilteringTool; import edu.stanford.rsl.conrad.geometry.trajectories.Trajectory; import edu.stanford.rsl.conrad.numerics.SimpleMatrix; import edu.stanford.rsl.conrad.numerics.SimpleVector; public abstract class ModelBasedIterativeReconstruction extends IterativeReconstruction{ private static final long serialVersionUID = 1L; protected boolean Debug = false; protected long time; protected Grid3D volumeImage = null; protected Grid3D projectionViews = null; protected double lineOffset; protected int maxK = 0; protected int maxI = 0; protected int maxJ = 0; protected int maxU = 0; protected int maxV = 0; protected double dx = 0.0; protected double dy = 0.0; protected double dz = 0.0; protected Trajectory dataTrajectory; @Override public void prepareForSerialization(){ super.prepareForSerialization(); init = false; } protected synchronized void initialize(ImageProcessor projection) throws Exception{ if (!init){ super.init(); // Precompute offsets lineOffset = 0; if (getGeometry().getDetectorWidth() != -1){ System.out.println("row size projection: " + projection.getWidth() + "\nrow size detector: " + getGeometry().getDetectorWidth()); lineOffset = (projection.getWidth() - getGeometry().getDetectorWidth()) / 2; } maxI = getGeometry().getReconDimensionX(); maxJ = getGeometry().getReconDimensionY(); maxK = getGeometry().getReconDimensionZ(); maxU = getGeometry().getDetectorWidth(); //or it should be projection.getWidth(); maxV = getGeometry().getDetectorHeight(); dx = getGeometry().getVoxelSpacingX(); dy = getGeometry().getVoxelSpacingY(); dz = getGeometry().getVoxelSpacingZ(); time = System.currentTimeMillis(); //projectionViews = InitializeProjectionViews(); //volumeImage = InitializeVolumeImage(); } } public Grid3D InitializeProjectionViews() throws Exception{ if (Debug) System.out.println("Created projection views"); if (nImages == 0 || maxU == 0 || maxV == 0 ){ System.out.println("Errpr: Wrong projection views size!"); } Grid3D views; views = new Grid3D(nImages,maxU,maxV); computeOffsets(); return views; } public Grid3D InitializeVolumeImage() throws Exception{ if (Debug) System.out.println("Created volume image"); if (maxI == 0 || maxJ == 0 || maxK == 0 ){ System.out.println("Errpr: Wrong volume image size!"); } Grid3D image; image = new Grid3D(maxI,maxJ,maxK); computeOffsets(); return image; } protected void copyProjectionViews()throws Exception{ FloatProcessor currentProjection; for ( int ip = 0; ip < nImages; ip++ ){ try { Grid2D projection = inputQueue.get(ip); currentProjection = new FloatProcessor(projection.getWidth(), projection.getHeight(), projection.getBuffer(), null); for (int iu = 0; iu <= maxU ; iu ++ ){ for (int iv = 0; iv <= maxV ; iv++){ // there may be a problem projectionViews.setAtIndex(ip, iu, iv, currentProjection.getf(iu, iv)); } } } catch (Exception e){ System.out.println("An error occured during copying projection views " + ip); } } } public Grid3D getProjectionViews(){ return projectionViews; } public Grid3D getvolumeImage(){ return volumeImage; } @Override public void configure() throws Exception{ boolean success = true; NumberFormat nf = NumberFormat.getInstance(Locale.US); nf.setMaximumFractionDigits(1); nf.setMinimumFractionDigits(1); nf.setMaximumIntegerDigits(1); nf.setMinimumIntegerDigits(1); initializeProjectionVolume(); configured = success; } /** * Back projects a single projection into the reconstruction space. * @param projection the projection to back project * @throws Exception may happen. */ protected abstract void backproject( Grid3D projImage, Grid3D volImage ) throws Exception; /** * Forward projects the object onto the projection image. * @param the object volume to back project * @throws Exception may happen. */ protected abstract void forwardproject( Grid3D projImage, Grid3D volImage ) throws Exception; @Override public String getName() { return "Model-based Iterative Reconstruction."; } @Override public String getToolName() { return "Model-based Iterative Reconstruction"; } @Override public synchronized void close() { super.close(); //if (true) throw new RuntimeException("Happended"); System.out.println("Closing iterative reconstruction"); //done = true; } @Override public ImageFilteringTool clone() { return this; } //----------------Methods for testing ----------------// public static void printSimpleMatrix( SimpleMatrix A ){ int n = A.getRows(); int m = A.getCols(); for (int i = 0; i < n ; i++ ){ for (int j = 0; j < m ; j++){ System.out.print( A.getElement(i, j) + "\t"); } System.out.print("\n"); } } public static void printSimpleVector( SimpleVector B ){ int n = B.getLen(); for (int i = 0; i < n ; i++ ){ System.out.print( B.getElement(i) + "\t"); } System.out.print("\n"); } //constructor overrides geometry for testing public ModelBasedIterativeReconstruction( Trajectory dataTraj ){ dataTrajectory = dataTraj; } //override for testing public Trajectory getGeometry() { return dataTrajectory; } public synchronized void initializeTest() throws Exception{ if (!init){ super.init(); nImages = getGeometry().getNumProjectionMatrices(); maxI = getGeometry().getReconDimensionX(); maxJ = getGeometry().getReconDimensionY(); maxK = getGeometry().getReconDimensionZ(); maxU = getGeometry().getDetectorWidth(); //or it should be projection.getWidth(); maxV = getGeometry().getDetectorHeight(); dx = getGeometry().getVoxelSpacingX(); dy = getGeometry().getVoxelSpacingY(); dz = getGeometry().getVoxelSpacingZ(); time = System.currentTimeMillis(); //projectionViews = InitializeProjectionViews(); //volumeImage = InitializeVolumeImage(); } } public void printOutGeometry(){ System.out.println("Detector Size: " + maxU + " X " + maxV ); System.out.println("Volume Size: " + maxI + " X " + maxJ + " X " + maxK ); System.out.println("Voxel Dimension: " + dx + " X " + dy + " X " + dz ); System.out.println( "Offsets: " + offsetX + ", " + offsetY + ", " + offsetZ) ; if (volumeImage != null && projectionViews != null ){ System.out.println( "volumeImage and projectionViews created successfully!"); } } } /* * Copyright (C) 2010-2014 Meng Wu * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */